source: trunk/zoo-project/zoo-kernel/ulinet.c @ 955

Last change on this file since 955 was 955, checked in by djay, 5 years ago

Fix issue when RELY_ON_DB is on and data is published. Ensure to use WPS 3 only when required. Set wmfs_link, wfs_link or wcs_link only when found in the metadata.

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc
File size: 22.5 KB
Line 
1/*
2 *  ulinet.c
3 *
4 * Author : Gérald FENOY
5 *
6 * Copyright (c) 2008-2019 GeoLabs SARL
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this software and associated documentation files (the "Software"), to deal
10 * in the Software without restriction, including without limitation the rights
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 * copies of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 * THE SOFTWARE.
25 *
26 */
27
28#define _ULINET
29#define MAX_WAIT_MSECS 180*1000 /* Wait max. 180 seconds */
30#include "ulinet.h"
31#include "server_internal.h"
32#include <assert.h>
33#include <ctype.h>
34#include "fcgi_stdio.h"
35
36/**
37 * Write the downloaded content to a _HINTERNET structure
38 *
39 * @param buffer the buffer to read
40 * @param size size of each member
41 * @param nmemb number of element to read
42 * @param data the _HINTERNET structure to write in
43 * @return the size red, -1 if buffer is NULL
44 */
45size_t write_data_into(void *buffer, size_t size, size_t nmemb, void *data){
46  size_t realsize = size * nmemb;
47  _HINTERNET *psInternet;
48  if(buffer==NULL){
49    buffer=NULL;
50    return -1;
51  }
52  psInternet=(_HINTERNET *)data;
53  if(psInternet->pabyData){
54    psInternet->pabyData=(unsigned char*)realloc(psInternet->pabyData,psInternet->nDataLen+realsize+1);
55    psInternet->nDataAlloc+=psInternet->nDataLen+realsize+1;
56  }
57  else{
58    psInternet->pabyData=(unsigned char*)malloc(psInternet->nDataLen+realsize+1);
59    psInternet->nDataAlloc=realsize+1;
60  }
61
62  if (psInternet->pabyData) {
63    memcpy( psInternet->pabyData + psInternet->nDataLen, buffer, realsize);
64    psInternet->nDataLen += realsize;
65    psInternet->pabyData[psInternet->nDataLen] = 0;
66  }
67
68  buffer=NULL;
69  return realsize;
70}
71
72/**
73 * Write the downloaded content in the file pouted by the _HINTERNET structure
74 *
75 * @param buffer the buffer to read
76 * @param size size of each member
77 * @param nmemb number of element to read
78 * @param data the _HINTERNET structure to write in
79 * @return the size red, -1 if buffer is NULL
80 */
81size_t write_data_into_file(void *buffer, size_t size, size_t nmemb, void *data) 
82{ 
83   size_t realsize = size * nmemb;
84   size_t writen=0;
85   _HINTERNET *psInternet;
86   if(buffer==NULL){
87     buffer=NULL;
88     return -1;
89   }
90   psInternet=(_HINTERNET *)data;
91   writen+=fwrite(buffer, size, nmemb, psInternet->file);
92   fflush(psInternet->file);
93   psInternet->nDataLen += realsize;
94
95   buffer=NULL;
96   return realsize;
97}
98
99
100/**
101 * In case of presence of "Set-Cookie" in the headers red, store the cookie
102 * identifier in cookie
103 *
104 * @param buffer the buffer to read
105 * @param size size of each member
106 * @param nmemb number of element to read
107 * @param data the _HINTERNET structure to write in
108 * @return the size red, -1 if buffer is NULL
109 * @see cookie
110 */
111size_t header_write_data(void *buffer, size_t size, size_t nmemb, void *data){
112  if(strncmp("Set-Cookie: ",(char*)buffer,12)==0){
113    int i;
114    char* tmp;
115    for(i=0;i<12;i++)
116#ifndef WIN32
117      buffer++;
118#else
119        ;
120#endif
121    tmp=strtok((char*) buffer,";"); // knut: added cast to char*
122    int cnt=0;
123    _HINTERNET *psInternet=(_HINTERNET *)data;
124    if(tmp!=NULL && psInternet!=NULL){
125      psInternet->cookie=(char*)malloc(sizeof(char)*(strlen(tmp)+1));
126      sprintf(psInternet->cookie,"%s",tmp);
127    }
128  }
129  return size * nmemb;//write_data_into(buffer,size,nmemb,data,HEADER);
130};
131
132/**
133 * Define the proxy to use for a CURL handler
134 *
135 * @param handle the CURL handler
136 * @param host the proxy host (including http://)
137 * @param port the proxy port
138 */
139void setProxy(CURL* handle,char* host,long port){
140  char* proxyDef=(char*)malloc((strlen(host)+10+2)*sizeof(char));
141  sprintf(proxyDef,"%s:%ld",host,port);
142  curl_easy_setopt(handle,CURLOPT_PROXY,proxyDef);
143  free(proxyDef);
144}
145
146/**
147 * MACOSX
148 */
149#if defined(macintosh) || (defined(__MACH__) && defined(__APPLE__))
150
151
152char* CFStringToCString(CFStringRef dest,char *buffer){
153  CFStringEncoding encoding = kCFStringEncodingUTF8;
154  Boolean bool2 = CFStringGetCString(dest,buffer,1024,encoding);
155  if(bool2){
156    printf("Loaded into local_buffer");
157    return buffer;
158  }
159  return NULL;
160}
161
162OSStatus setProxiesForProtcol(CURL* handle,const char *proto){
163  OSStatus              err;
164  CFDictionaryRef proxyDict;
165  CFArrayRef            proxies;
166 
167  CFStringRef key_enabled = NULL;
168  CFStringRef key_host = NULL;
169  CFStringRef key_port = NULL;
170 
171  bool proxy_enabled;
172  char *proxy_host;
173  long proxy_port;
174 
175  proxyDict = NULL;
176  proxies = NULL;
177
178  err = noErr;
179  proxyDict = SCDynamicStoreCopyProxies(NULL);
180
181  if(strncmp(proto,"http",4)==0){
182      key_enabled=kSCPropNetProxiesHTTPEnable;
183      key_host=kSCPropNetProxiesHTTPProxy;
184      key_port=kSCPropNetProxiesHTTPPort;
185  }
186  else
187    if(strncmp(proto,"https",5)==0){
188      key_enabled=kSCPropNetProxiesHTTPSEnable;
189      key_host=kSCPropNetProxiesHTTPSProxy;
190      key_port=kSCPropNetProxiesHTTPSPort;
191    }
192
193  CFNumberGetValue(CFDictionaryGetValue(proxyDict,key_enabled),kCFNumberIntType,&proxy_enabled);
194  if(proxy_enabled){
195    CFNumberGetValue(CFDictionaryGetValue(proxyDict,key_port),CFNumberGetType(CFDictionaryGetValue(proxyDict,key_port)),&proxy_port);
196    char buffer[1024];
197    CFStringToCString(CFDictionaryGetValue(proxyDict,key_host),buffer);
198    proxy_host=buffer;
199
200#ifdef MSG_LAF_VERBOSE
201    printf("\n**[PROXY SETTINGS DETECTION %s (%d) %s:%li (%s)]**\n",proto,proxy_enabled,(char*)proxy_host,proxy_port,buffer);
202#endif
203
204    if (proxyDict == NULL) {
205      err = coreFoundationUnknownErr;
206    }
207
208    setProxy(handle,proxy_host,proxy_port);
209  }
210  return err;
211}
212#else
213/**
214 * Should autodetect the proxy configuration (do nothing on linux)
215 *
216 * @param handle a CURL handle
217 * @param proto the protocol requiring the use of a proxy
218 */
219int setProxiesForProtcol(CURL* handle,const char *proto){
220#ifdef MSG_LAF_VERBOSE
221  fprintf( stderr, "setProxiesForProtocol (do nothing) ...\n" );
222#endif
223  return 0;
224}
225#endif
226
227/**
228 * Create a HINTERNET
229 *
230 * @param lpszAgent the HTPP User-Agent to use to send requests
231 * @param  dwAccessType type of access required
232 * @param  lpszProxyName the name of the proxy server(s) to use
233 * @param  lpszProxyBypass ip address or host names which should not be routed
234 *  through the proxy
235 * @param  dwFlags Options (INTERNET_FLAG_ASYNC,INTERNET_FLAG_FROM_CACHE,INTERNET_FLAG_OFFLINE)
236 * @return the created HINTERNET
237 */
238HINTERNET InternetOpen(char* lpszAgent,int dwAccessType,char* lpszProxyName,char* lpszProxyBypass,int dwFlags){
239  HINTERNET ret;
240  ret.handle=curl_multi_init();
241  ret.agent=zStrdup(lpszAgent);
242  ret.nb=0;
243  ret.waitingRequests[ret.nb] = NULL;
244  ret.ihandle[ret.nb].header=NULL;
245  ret.ihandle[ret.nb].handle=NULL;
246  ret.ihandle[ret.nb].hasCacheFile=0;
247  ret.ihandle[ret.nb].nDataAlloc = 0;
248  ret.ihandle[ret.nb].url = NULL;
249  ret.ihandle[ret.nb].mimeType = NULL;
250  ret.ihandle[ret.nb].cookie = NULL;
251  ret.ihandle[ret.nb].nDataLen = 0;
252  ret.ihandle[ret.nb].nDataAlloc = 0;
253  ret.ihandle[ret.nb].pabyData = NULL;
254  ret.ihandle[ret.nb].post = NULL;
255  return ret;
256}
257
258/**
259 * Verify if the URL should use a shared cache or not.
260 *
261 * In case the security section contains a key named "shared", then if the
262 * domain listed in the shared key are contained in the url given as parameter
263 * then it return "SHARED" in other cases, it returns "OTHER".
264 *
265 * @param conf the main configuration file maps
266 * @param url the URL to evaluate
267 * @return a string "SHARED" in case the host is in a domain listed in the
268 * shared key, "OTHER" in other cases.
269 */
270char* getProvenance(maps* conf,const char* url){
271  int i=0;
272  map* sharedCache=getMapFromMaps(conf,"security","shared");
273  char *res="OTHER";
274  char *paths[2]={
275    "mapserverAddress",
276    "tmpUrl"
277  };
278  if(sharedCache!=NULL){
279    char *hosts=sharedCache->value;
280    char *curs=strtok(hosts,",");
281    while(curs!=NULL){
282      if(strstr(url,curs)==NULL){
283        return "SHARED";
284      }
285      curs=strtok(NULL,",");
286    }
287  }
288  for(i=0;i<2;i++){
289    sharedCache=getMapFromMaps(conf,"main",paths[i]);
290    if(sharedCache!=NULL){
291      if(strstr(url,sharedCache->value)!=NULL){
292        return "LOCAL";
293      }
294    }
295  }
296  return res;
297}
298
299/**
300 * Add missing headers to an existing _HINTERNET
301 *
302 *
303 * @param handle the _HINTERNET pointer
304 * @param key the header parameter name
305 * @param value the header parameter value
306 * @return 0 if the operation succeeded, -1 in other case.
307 */
308int AddMissingHeaderEntry(_HINTERNET* handle,const char* key,const char* value){
309  size_t length=strlen(key)+strlen(value)+3;
310  char *entry=(char*)malloc((length)*sizeof(char));
311  if(entry==NULL)
312    return -1;
313  snprintf (entry, length, "%s: %s", key, value);
314  handle->header = curl_slist_append (handle->header, entry);
315  free(entry);
316  return 0;
317}
318
319/**
320 * Verify if a host is protected (appear in [security] > hosts)
321 *
322 * @param protectedHosts string containing all the protected hosts (coma separated)
323 * @param url string used to extract the host from
324 * @return 1 if the host is listed as protected, 0 in other case
325 */
326int isProtectedHost(const char* protectedHosts, const char* url) {
327        char *token, *saveptr;
328        int cnt;
329
330        // knut: make a copy of url since strtok family modifies first argument and cannot be used on constant strings 
331        char* urlcpy = (char*)malloc(sizeof(char)*(strlen(url) + 1));
332        urlcpy = strncpy(urlcpy, url, strlen(url) + 1); // since count > strlen(url), a null character is properly appended
333
334        //token = strtok_r (url, "//", &saveptr);
335        token = strtok_r(urlcpy, "//", &saveptr);   // knut
336        cnt = 0;
337        while (token != NULL && cnt <= 1) {
338                fprintf(stderr, "%s %d %s \n", __FILE__, __LINE__, token);
339                if (cnt == 1)
340                        fprintf(stderr, "%s %d %s \n", __FILE__, __LINE__, strstr(protectedHosts, token));
341                fflush(stderr);
342                if (cnt == 1 && strstr(protectedHosts, token) != NULL) {
343                        fprintf(stderr, "%s %d %s \n", __FILE__, __LINE__, strstr(protectedHosts, token));
344                        free(urlcpy);
345                        return 1;
346                }
347                token = strtok_r(NULL, "/", &saveptr);
348                cnt += 1;
349        }
350        free(urlcpy);
351        return 0;
352}
353
354/**
355 * Add headers defined in [security] > attributes to an existing HINTERNET
356 * @see isProtectedHost, AddMissingHeaderEntry
357 *
358 * @param handle the _HINTERNET pointer
359 * @param conf the header parameter name
360 * @param value the header parameter value
361 * @return 0 if the operation succeeded, -1 in other case.
362 */
363void AddHeaderEntries(HINTERNET* handle,maps* conf){
364  map* passThrough=getMapFromMaps(conf,"security","attributes");
365  map* targetHosts=getMapFromMaps(conf,"security","hosts");
366  char* passedHeader[10];
367  int cnt=0;
368  if(passThrough!=NULL && targetHosts!=NULL){
369    char *tmp=zStrdup(passThrough->value);
370    int i;
371    for(i=0;i<handle->nb;i++){
372      if(strstr(targetHosts->value,"*")!=NULL || isProtectedHost(targetHosts->value,handle->ihandle[i].url)==1){
373        char *token, *saveptr;
374        token = strtok_r (tmp, ",", &saveptr);
375        while (token != NULL){
376          size_t length=strlen(token)+6;
377          char* tmp1=(char*)malloc(length*sizeof(char));
378          map* tmpMap;
379          snprintf(tmp1,6,"HTTP_");
380          int j;
381          for(j=0;token[j]!='\0';j++){
382            if(token[j]!='-')
383              tmp1[5+j]=toupper(token[j]);
384            else
385              tmp1[5+j]='_';
386            tmp1[5+j+1]='\0';
387          }
388          tmpMap = getMapFromMaps(conf,"renv",tmp1);
389          if(tmpMap!=NULL){
390            AddMissingHeaderEntry(&handle->ihandle[i],token,tmpMap->value);
391          }
392          if(handle->ihandle[i].header!=NULL)
393            curl_easy_setopt(handle->ihandle[i].handle,CURLOPT_HTTPHEADER,handle->ihandle[i].header);
394          free(tmp1);
395          cnt+=1;
396          token = strtok_r (NULL, ",", &saveptr);
397        }
398      }
399    }
400    free(tmp);
401  }
402}
403
404/**
405 * Close a HINTERNET connection and free allocated resources
406 *
407 * @param handle0 the HINTERNET connection to close
408 */
409void InternetCloseHandle(HINTERNET* handle0){
410  int i=0;
411  if(handle0!=NULL){
412    for(i=0;i<handle0->nb;i++){
413      _HINTERNET handle=handle0->ihandle[i];
414      if(handle.hasCacheFile>0){
415        fclose(handle.file);
416        zUnlink(handle.filename);
417        free(handle.filename);
418      }
419      else{
420        handle.pabyData = NULL;
421        handle.nDataAlloc = handle.nDataLen = 0;
422      }
423      if(handle.header!=NULL){
424        curl_slist_free_all(handle.header);
425        handle.header=NULL;
426      }
427      if(handle.post!=NULL){
428        free(handle.post);
429        handle.post=NULL;
430      }
431      if(handle.url!=NULL){
432        free(handle.url);
433        handle.url=NULL;
434      }
435      if(handle.mimeType!=NULL){
436        free(handle.mimeType);
437        handle.mimeType=NULL;
438      }
439      if(handle.cookie!=NULL){
440        free(handle.cookie);
441        handle.cookie=NULL;
442      }
443      if(handle0->waitingRequests[i]!=NULL){
444        free(handle0->waitingRequests[i]);
445        handle0->waitingRequests[i]=NULL;
446      }
447    }
448    if(handle0->handle)
449      curl_multi_cleanup(handle0->handle);
450    if(handle0->agent!=NULL){
451      free(handle0->agent);
452      handle0->agent=NULL;
453    }
454  }
455}
456
457/**
458 * Create a new element in the download queue
459 *
460 * @param hInternet the HINTERNET connection to add the download link
461 * @param lpszUrl the url to download
462 * @param lpszHeaders the additional headers to be sent to the HTTP server
463 * @param dwHeadersLength the size of the additional headers
464 * @param dwFlags desired download mode (INTERNET_FLAG_NO_CACHE_WRITE for not using cache file)
465 * @param dwContext not used
466 * @param conf the main configuration file maps pointer
467 * @return the updated HINTERNET
468 */
469HINTERNET InternetOpenUrl(HINTERNET* hInternet,LPCTSTR lpszUrl,LPCTSTR lpszHeaders,size_t dwHeadersLength,size_t dwFlags,size_t dwContext,const maps* conf){
470
471  char filename[255];
472  int ldwFlags=INTERNET_FLAG_NEED_FILE;
473  struct MemoryStruct header;
474  map* memUse=getMapFromMaps((maps*) conf,"main","memory"); // knut: addad cast to maps*
475
476  hInternet->ihandle[hInternet->nb].handle=curl_easy_init( );
477  hInternet->ihandle[hInternet->nb].hasCacheFile=0;
478  hInternet->ihandle[hInternet->nb].nDataAlloc = 0;
479  hInternet->ihandle[hInternet->nb].url = NULL;
480  hInternet->ihandle[hInternet->nb].mimeType = NULL;
481  hInternet->ihandle[hInternet->nb].cookie = NULL;
482  hInternet->ihandle[hInternet->nb].nDataLen = 0;
483  hInternet->ihandle[hInternet->nb].id = hInternet->nb;
484  hInternet->ihandle[hInternet->nb].nDataAlloc = 0;
485  hInternet->ihandle[hInternet->nb].code = -1;
486  hInternet->ihandle[hInternet->nb].pabyData = NULL;
487  hInternet->ihandle[hInternet->nb].post = NULL;
488
489  map* caBundle=getMapFromMaps((maps*) conf,"curl","cainfo");
490  if(caBundle!=NULL)
491    curl_easy_setopt(hInternet->ihandle[hInternet->nb].handle,CURLOPT_CAINFO,caBundle->value);
492  curl_easy_setopt(hInternet->ihandle[hInternet->nb].handle, CURLOPT_COOKIEFILE, "ALL");
493#ifndef TIGER
494  curl_easy_setopt(hInternet->ihandle[hInternet->nb].handle, CURLOPT_COOKIELIST, "ALL");
495#endif
496  curl_easy_setopt(hInternet->ihandle[hInternet->nb].handle, CURLOPT_USERAGENT, hInternet->agent);
497 
498  curl_easy_setopt(hInternet->ihandle[hInternet->nb].handle,CURLOPT_FOLLOWLOCATION,1);
499  curl_easy_setopt(hInternet->ihandle[hInternet->nb].handle,CURLOPT_MAXREDIRS,3);
500 
501  header.memory=NULL;
502  header.size = 0;
503
504  curl_easy_setopt(hInternet->ihandle[hInternet->nb].handle, CURLOPT_HEADERFUNCTION, header_write_data);
505  curl_easy_setopt(hInternet->ihandle[hInternet->nb].handle, CURLOPT_WRITEHEADER, (void *)&header);
506
507#ifdef MSG_LAF_VERBOSE
508  curl_easy_setopt(hInternet->ihandle[hInternet->nb].handle, CURLOPT_VERBOSE, 1);
509#endif
510
511  if(memUse!=NULL && strcasecmp(memUse->value,"load")==0)
512    ldwFlags=INTERNET_FLAG_NO_CACHE_WRITE;
513 
514  switch(ldwFlags)
515    {
516    case INTERNET_FLAG_NO_CACHE_WRITE:
517      curl_easy_setopt(hInternet->ihandle[hInternet->nb].handle, CURLOPT_WRITEFUNCTION, write_data_into);
518      curl_easy_setopt(hInternet->ihandle[hInternet->nb].handle, CURLOPT_WRITEDATA, (void*)&hInternet->ihandle[hInternet->nb]);
519      hInternet->ihandle[hInternet->nb].hasCacheFile=-1;
520      break;
521    default:
522      memset(filename,0,255);
523      char* tmpUuid=get_uuid();
524      map* tmpPath=NULL;
525      if(conf!=NULL){
526        tmpPath=getMapFromMaps((maps*) conf,"main","tmpPath"); // knut added cast to maps*
527      }
528      if(tmpPath==NULL)
529        sprintf(filename,"/tmp/ZOO_Cache%s", tmpUuid);
530      else
531        sprintf(filename,"%s/ZOO_Cache%s", tmpPath->value,tmpUuid);
532      free(tmpUuid);
533      hInternet->ihandle[hInternet->nb].filename=zStrdup(filename);
534      hInternet->ihandle[hInternet->nb].file=fopen(hInternet->ihandle[hInternet->nb].filename,"w+");
535      hInternet->ihandle[hInternet->nb].hasCacheFile=1;
536      curl_easy_setopt(hInternet->ihandle[hInternet->nb].handle, CURLOPT_WRITEFUNCTION, write_data_into_file);
537      curl_easy_setopt(hInternet->ihandle[hInternet->nb].handle, CURLOPT_WRITEDATA, (void*)&hInternet->ihandle[hInternet->nb]);
538      break;
539    }
540#ifdef ULINET_DEBUG
541  fprintf(stderr,"URL (%s)\nBODY (%s)\n",lpszUrl,lpszHeaders);
542#endif
543  if(lpszHeaders!=NULL && strlen(lpszHeaders)>0){
544#ifdef MSG_LAF_VERBOSE
545    fprintf(stderr,"FROM ULINET !!");
546    fprintf(stderr,"HEADER : [%s] %d\n",lpszHeaders,dwHeadersLength);
547#endif
548    curl_easy_setopt(hInternet->ihandle[hInternet->nb].handle,CURLOPT_POST,1);
549#ifdef ULINET_DEBUG
550    fprintf(stderr,"** (%s) %d **\n",lpszHeaders,dwHeadersLength);
551    curl_easy_setopt(hInternet->ihandle[hInternet->nb].handle,CURLOPT_VERBOSE,1);
552#endif
553    hInternet->ihandle[hInternet->nb].post=zStrdup(lpszHeaders);
554    curl_easy_setopt(hInternet->ihandle[hInternet->nb].handle,CURLOPT_POSTFIELDS,hInternet->ihandle[hInternet->nb].post);
555    curl_easy_setopt(hInternet->ihandle[hInternet->nb].handle,CURLOPT_POSTFIELDSIZE,(long)dwHeadersLength);
556  }
557  if(hInternet->ihandle[hInternet->nb].header!=NULL)
558    curl_easy_setopt(hInternet->ihandle[hInternet->nb].handle,CURLOPT_HTTPHEADER,hInternet->ihandle[hInternet->nb].header);
559
560  curl_easy_setopt(hInternet->ihandle[hInternet->nb].handle,CURLOPT_URL,lpszUrl);
561  hInternet->ihandle[hInternet->nb].url = zStrdup(lpszUrl);
562
563  curl_multi_add_handle(hInternet->handle,hInternet->ihandle[hInternet->nb].handle);
564 
565  hInternet->ihandle[hInternet->nb].header=NULL;
566  ++hInternet->nb;
567  hInternet->ihandle[hInternet->nb].header=NULL;
568
569#ifdef ULINET_DEBUG
570  fprintf(stderr,"DEBUG MIMETYPE: %s\n",hInternet.mimeType);
571  fflush(stderr);
572#endif
573  return *hInternet;
574};
575
576/**
577 * Download all opened urls in the queue
578 *
579 * @param hInternet the HINTERNET structure containing the queue
580 * @return 0
581 */
582int processDownloads(HINTERNET* hInternet){
583  int still_running=0,numfds;
584  int msgs_left=0;
585  int i=0;
586  do{
587    CURLMcode mc;
588    mc = curl_multi_perform(hInternet->handle, &still_running);
589    if(mc==CURLM_OK){
590#if LIBCURL_VERSION_MINOR >= 28
591      mc = curl_multi_wait(hInternet->handle, NULL, 0, 1000, &numfds);
592#else
593      struct timeval timeout;
594      fd_set fdread;
595      fd_set fdwrite;
596      fd_set fdexcep;
597      int maxfd = -1;
598
599      long curl_timeo = -1;
600
601      FD_ZERO(&fdread);
602      FD_ZERO(&fdwrite);
603      FD_ZERO(&fdexcep);
604
605      /* set a suitable timeout to play around with */
606      timeout.tv_sec = 1;
607      timeout.tv_usec = 0;
608
609      curl_multi_timeout(hInternet->handle, &curl_timeo);
610      if(curl_timeo >= 0) {
611        timeout.tv_sec = curl_timeo / 1000;
612        if(timeout.tv_sec > 1)
613          timeout.tv_sec = 1;
614        else
615          timeout.tv_usec = (curl_timeo % 1000) * 1000;
616      }
617
618      /* get file descriptors from the transfers */
619      mc = curl_multi_fdset(hInternet->handle, &fdread, &fdwrite, &fdexcep, &maxfd);
620#endif
621    }
622    if(mc != CURLM_OK) {
623      fprintf(stderr, "curl_multi failed, code %d.n", mc);
624      break;
625    }
626  }while(still_running); 
627  for(i=0;i<hInternet->nb;i++){
628    char *tmp;
629    curl_easy_getinfo(hInternet->ihandle[i].handle,CURLINFO_CONTENT_TYPE,&tmp);
630    if(tmp!=NULL)
631      hInternet->ihandle[i].mimeType=zStrdup(tmp);
632    curl_easy_getinfo(hInternet->ihandle[i].handle,CURLINFO_RESPONSE_CODE,&(hInternet->ihandle[i].code));
633    curl_multi_remove_handle(hInternet->handle, hInternet->ihandle[i].handle);
634    curl_easy_cleanup(hInternet->ihandle[i].handle);
635  }
636  return 0;
637}
638
639/**
640 * Initialize the cookie for a specific index (hInternet.nb)
641 *
642 * @param hInternet the HINTERNET structure to know the cookie index to reset
643 * @return 1
644 * @see HINTERNET
645 */
646int freeCookieList(HINTERNET hInternet){
647  hInternet.ihandle[hInternet.nb].cookie=zStrdup("");
648#ifndef TIGER
649  curl_easy_setopt(hInternet.ihandle[hInternet.nb].handle, CURLOPT_COOKIELIST, "ALL");
650#endif
651  return 1;
652}
653
654/**
655 * Copy a downloaded content
656 *
657 * @param hInternet the _HINTERNET structure
658 * @param lpBuffer the memory space to copy the downloaded content
659 * @param dwNumberOfBytesToRead the size of lpBuffer
660 * @param lpdwNumberOfBytesRead number of bytes red
661 * @return 1 on success, 0 if failure
662 */
663int InternetReadFile(_HINTERNET hInternet,LPVOID lpBuffer,int dwNumberOfBytesToRead, size_t *lpdwNumberOfBytesRead){
664  size_t dwDataSize;
665
666  if(hInternet.hasCacheFile>0){
667    fseek (hInternet.file , 0 , SEEK_END);
668    dwDataSize=ftell(hInternet.file); //taille du ficher
669    //dwDataSize=hInternet.nDataLen;
670    //rewind (hInternet.file);
671    fseek(hInternet.file, 0, SEEK_SET);
672  }
673  else{
674    memset(lpBuffer,0,hInternet.nDataLen+1);
675    memcpy(lpBuffer, hInternet.pabyData, hInternet.nDataLen );
676    dwDataSize=hInternet.nDataLen;
677    free( hInternet.pabyData );
678    hInternet.pabyData=NULL;
679  }
680
681  if( dwNumberOfBytesToRead /* buffer size */ < dwDataSize ){
682    return 0;
683  }
684
685#ifdef MSG_LAF_VERBOSE
686  fprintf(stderr,"\nfile size : %dko\n",dwDataSize/1024);
687#endif
688
689  if(hInternet.hasCacheFile>0){
690    size_t freadRes = fread(lpBuffer,dwDataSize+1,1,hInternet.file); 
691    *lpdwNumberOfBytesRead = hInternet.nDataLen;
692  }
693  else{
694    *lpdwNumberOfBytesRead = hInternet.nDataLen;
695    free( hInternet.pabyData );
696    hInternet.pabyData = NULL;
697    hInternet.nDataAlloc = hInternet.nDataLen = 0;
698  }
699
700  if( *lpdwNumberOfBytesRead < dwDataSize )
701      return 0;
702  else
703      return 1; // TRUE
704}
705
706
707/**
708 * Use basic authentication for accessing a resource
709 *
710 * @param hInternet the _HINTERNET structure
711 * @param login the login to use to authenticate
712 * @param passwd the password to use to authenticate
713 */
714int setBasicAuth(HINTERNET hInternet,char* login,char* passwd){
715  char *tmp;
716  tmp=(char*)malloc((strlen(login)+strlen(passwd)+2)*sizeof(char));
717  sprintf(tmp,"%s:%s",login,passwd);
718  if(curl_easy_setopt(hInternet.ihandle[hInternet.nb].handle,CURLOPT_USERPWD,tmp)==CURLE_OUT_OF_MEMORY){
719    free(tmp);
720    return -1;
721  }
722  curl_easy_setopt(hInternet.ihandle[hInternet.nb].handle, CURLOPT_HTTPAUTH,CURLAUTH_ANY);
723  free(tmp);
724  return 0;
725}
Note: See TracBrowser for help on using the repository browser.

Search

ZOO Sponsors

http://www.zoo-project.org/trac/chrome/site/img/geolabs-logo.pnghttp://www.zoo-project.org/trac/chrome/site/img/neogeo-logo.png http://www.zoo-project.org/trac/chrome/site/img/apptech-logo.png http://www.zoo-project.org/trac/chrome/site/img/3liz-logo.png http://www.zoo-project.org/trac/chrome/site/img/gateway-logo.png

Become a sponsor !

Knowledge partners

http://www.zoo-project.org/trac/chrome/site/img/ocu-logo.png http://www.zoo-project.org/trac/chrome/site/img/gucas-logo.png http://www.zoo-project.org/trac/chrome/site/img/polimi-logo.png http://www.zoo-project.org/trac/chrome/site/img/fem-logo.png http://www.zoo-project.org/trac/chrome/site/img/supsi-logo.png http://www.zoo-project.org/trac/chrome/site/img/cumtb-logo.png

Become a knowledge partner

Related links

http://zoo-project.org/img/ogclogo.png http://zoo-project.org/img/osgeologo.png