source: branches/prototype-v0/zoo-project/zoo-kernel/ulinet.c @ 896

Last change on this file since 896 was 896, checked in by knut, 5 years ago

Added some recent changes from trunk (r889), including some new utility functions and exception handling and new (conditional) definition of type bool. Added some new logic concerning Python and Mono environment and search paths. Fixed problem with Mono updateStatus function. Changed response_print.h to #include locale.h unconditionally and xlocale.h conditionally; xlocale.h is non-standard and can probably be dropped.

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