source: trunk/zoo-project/zoo-kernel/caching.c @ 963

Last change on this file since 963 was 961, checked in by djay, 4 years ago

Make sure not to try accessing mimetype and provenance in case a local file is used. Fix issue with addMapsToMaps. Produce value string only when memory=load for Python support. Make gdal/profile service usable in case memory=protect.

  • Property svn:keywords set to Id
File size: 23.6 KB
Line 
1/*
2 * Author : Gérald Fenoy
3 *
4 *  Copyright 2008-2015 GeoLabs SARL. All rights reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
24
25#include <openssl/md5.h>
26#include <openssl/evp.h>
27#include "service.h"
28#include "service_internal.h"
29#include "response_print.h"
30#include "caching.h"
31#ifdef MS_FORCE_LOCAL_FILE_USE
32#include "ogr_api.h"
33#include "mapserver.h"
34#endif
35/**
36 * Compute md5
37 *
38 * @param url the char*
39 * @return a char* representing the md5 of the url
40 * @warning make sure to free resources returned by this function
41 */
42char* getMd5(char* url){
43  EVP_MD_CTX *md5ctx=EVP_MD_CTX_create();
44  char* fresult=(char*)malloc((EVP_MAX_MD_SIZE+1)*sizeof(char));
45  unsigned char result[EVP_MAX_MD_SIZE];
46  unsigned int len;
47  EVP_DigestInit(md5ctx, EVP_md5());
48  EVP_DigestUpdate(md5ctx, url, strlen(url));
49  EVP_DigestFinal_ex(md5ctx,result,&len);
50  EVP_MD_CTX_destroy(md5ctx);
51  int i;
52  for(i = 0; i < len; i++){
53    if(i>0){
54      char *tmp=zStrdup(fresult);
55      sprintf(fresult,"%s%02x", tmp,result[i]);
56      free(tmp);
57    }
58    else
59      sprintf(fresult,"%02x",result[i]);
60  }
61  return fresult;
62}
63
64/**
65 * Compute md5 of a file
66 *
67 * @param file the char*
68 * @return a char* representing the md5 of the url
69 * @warning make sure to free resources returned by this function
70 */
71char* getMd5f(char* file){
72  EVP_MD_CTX *md5ctx=EVP_MD_CTX_create();
73  char* fresult=(char*)malloc((EVP_MAX_MD_SIZE+1)*sizeof(char));
74  unsigned char result[EVP_MAX_MD_SIZE];
75  unsigned int len;
76  int bytes;
77  int dlen=65536;
78  unsigned char data[65537];
79  FILE *inFile = fopen (file, "rb");
80  EVP_DigestInit(md5ctx, EVP_md5());
81  while ((bytes = fread (data, sizeof(unsigned char), dlen, inFile)) != 0)
82    EVP_DigestUpdate(md5ctx, data, bytes);
83  EVP_DigestFinal_ex(md5ctx,result,&len);
84  EVP_MD_CTX_destroy(md5ctx);
85  int i;
86  for(i = 0; i < len; i++){
87    if(i>0){
88      char *tmp=zStrdup(fresult);
89      sprintf(fresult,"%s%02x", tmp,result[i]);
90      free(tmp);
91    }
92    else
93      sprintf(fresult,"%02x",result[i]);
94  }
95  fclose (inFile);
96  return fresult;
97}
98
99
100
101/**
102 * Create a URL by appending every request header listed in the security
103 * section.This imply that the URL will contain any authentication
104 * informations that should be fowarded to the server from which de input
105 * was download.
106 * @param conf the main configuration maps
107 * @param request the URL to transform.
108 * @return a char* that contain the original URL plus potential header (only for
109 * hosts that are not shared).
110 * @warning Be sure to free the memory returned by this function.
111 */
112char* getFilenameForRequest(maps* conf, const char* request){
113  map* passThrough=getMapFromMaps(conf,"security","attributes");
114  map* targetHosts=getMapFromMaps(conf,"security","hosts");
115  char* passedHeader[10];
116  int cnt=0;
117  char *res=zStrdup(request);
118  char *toAppend=NULL;
119  if(passThrough!=NULL && targetHosts!=NULL){
120    char *tmp=zStrdup(passThrough->value);
121    char *token, *saveptr;
122    token = strtok_r (tmp, ",", &saveptr);
123    int i;
124    if((strstr(targetHosts->value,"*")!=NULL || isProtectedHost(targetHosts->value,request)==1) && strncasecmp(getProvenance(conf,request),"SHARED",6)!=0){
125      while (token != NULL){
126        int length=strlen(token)+6;
127        char* tmp1=(char*)malloc(length*sizeof(char));
128        map* tmpMap;
129        snprintf(tmp1,6,"HTTP_");
130        int j;
131        for(j=0;token[j]!='\0';j++){
132          if(token[j]!='-')
133            tmp1[5+j]=toupper(token[j]);
134          else
135            tmp1[5+j]='_';
136          tmp1[5+j+1]='\0';
137        }
138        tmpMap = getMapFromMaps(conf,"renv",tmp1);
139        if(tmpMap!=NULL){
140          if(toAppend==NULL){
141            toAppend=(char*)malloc((strlen(tmpMap->value)+1)*sizeof(char));
142            sprintf(toAppend,"%s",tmpMap->value);
143          }else{
144            char *tmp3=zStrdup(toAppend);
145            toAppend=(char*)realloc(toAppend,(strlen(tmpMap->value)+strlen(tmp3)+2)*sizeof(char));
146            sprintf(toAppend,"%s,%s",tmp3,tmpMap->value);
147            free(tmp3);
148          }
149        }
150        free(tmp1);
151        cnt+=1;
152        token = strtok_r (NULL, ",", &saveptr);
153      }
154    }
155    free(tmp);
156  }
157  if(toAppend!=NULL){
158    char *tmp3=zStrdup(res);
159    res=(char*)realloc(res,(strlen(tmp3)+strlen(toAppend)+1)*sizeof(char));
160    sprintf(res,"%s%s",tmp3,toAppend);
161    free(tmp3);
162    free(toAppend);
163  }
164  return res;
165}
166
167/**
168 * Store MD5 of the content of a file
169 * @file char* the full path of the file
170 */
171int storeMd5(char* file){
172  char* storage=zStrdup(file);
173  char* md5fstr=getMd5f(file);
174  storage[strlen(storage)-2]='m';
175  storage[strlen(storage)-1]='d';
176  FILE* fo=fopen(storage,"w+");
177  if(fo==NULL)
178    return 1;
179  fwrite(md5fstr,sizeof(char),strlen(md5fstr),fo);
180  free(md5fstr);
181  free(storage);
182  fclose(fo);
183  return 0;
184}
185
186/**
187 * Cache a file for a given request.
188 * For each cached file, the are two files stored, a .zca and a .zcm containing
189 * the downloaded content and the mimeType respectively.
190 *
191 * @param conf the maps containing the settings of the main.cfg file
192 * @param request the url used too fetch the content
193 * @param content the downloaded content
194 * @param mimeType the content mimeType
195 * @param length the content size
196 * @param filepath a buffer for storing the path of the cached file; may be NULL
197 * @param max_path the size of the allocated filepath buffer 
198 */
199void cacheFile(maps* conf,char* request,char* mimeType,int length,char* filename){
200  map* tmp=getMapFromMaps(conf,"main","cacheDir");
201  char contentr[4096];
202  int cred=0;
203  if(tmp!=NULL){
204    char* myRequest=getFilenameForRequest(conf,request);
205    char* md5str=getMd5(myRequest);
206    free(myRequest);
207    char* fname=(char*)malloc(sizeof(char)*(strlen(tmp->value)+strlen(md5str)+6));
208    // Store md5
209    char* md5fstr=getMd5f(filename);
210    sprintf(fname,"%s/%s.zmd",tmp->value,md5str);
211    FILE* fo=fopen(fname,"w+");
212#ifdef DEBUG
213    fprintf(stderr,"filename: %s\n",filename);
214    fprintf(stderr,"MD5: %s\n",md5fstr);
215#endif
216    fwrite(md5fstr,sizeof(char),strlen(md5fstr),fo);
217    free(md5fstr);
218    fclose(fo);
219   
220    sprintf(fname,"%s/%s.zca",tmp->value,md5str);
221    zooLock* lck=lockFile(conf,fname,'w');
222    if(lck!=NULL){
223#ifdef DEBUG
224      fprintf(stderr,"Cache list : %s\n",fname);
225      fflush(stderr);
226#endif
227      FILE* fi=fopen(filename,"rb");
228      sprintf(fname,"%s/%s.zca",tmp->value,md5str);
229      fo=fopen(fname,"w+");
230      if(fo==NULL){
231#ifdef DEBUG
232        fprintf (stderr, "Failed to open %s for writing: %s\n",fname, strerror(errno));
233#endif
234        unlockFile(conf,lck);
235        return;
236      }
237      if(fi==NULL){
238#ifdef DEBUG
239        fprintf (stderr, "Failed to open %s for reading: %s\n",filename, strerror(errno));
240#endif
241        unlockFile(conf,lck);
242        return;
243      }
244      memset(contentr,0,4096);
245      while((cred=fread(contentr,sizeof(char),4096,fi))>0){
246        fwrite(contentr,sizeof(char),cred,fo);
247        fflush(fo);
248        memset(contentr,0,4096);
249      }
250      unlockFile(conf,lck);
251      fclose(fo);
252      fclose(fi);
253
254      // Store mimeType
255      sprintf(fname,"%s/%s.zcm",tmp->value,md5str);
256      fo=fopen(fname,"w+");
257#ifdef DEBUG
258      fprintf(stderr,"MIMETYPE: %s\n",mimeType);
259#endif
260      fwrite(mimeType,sizeof(char),strlen(mimeType),fo);
261      fclose(fo);
262
263      // Store provenance
264      sprintf(fname,"%s/%s.zcp",tmp->value,md5str);
265      fo=fopen(fname,"w+");
266      char* origin=getProvenance(conf,request);
267#ifdef DEBUG
268      fprintf(stderr,"ORIGIN: %s\n",mimeType);
269#endif
270      fwrite(origin,sizeof(char),strlen(origin),fo);
271      fclose(fo);
272
273      free(md5str);
274
275    }
276    free(fname);
277  }
278}
279
280/**
281 * Cache a file for a given request.
282 * For each cached file, the are two files stored, a .zca and a .zcm containing
283 * the downloaded content and the mimeType respectively.
284 *
285 * @param conf the maps containing the settings of the main.cfg file
286 * @param request the url used too fetch the content
287 * @param content the downloaded content
288 * @param mimeType the content mimeType
289 * @param length the content size
290 * @param filepath a buffer for storing the path of the cached file; may be NULL
291 * @param max_path the size of the allocated filepath buffer 
292 */
293void addToCache(maps* conf,char* request,char* content,char* mimeType,int length, 
294                char* filepath, size_t max_path){
295  map* tmp=getMapFromMaps(conf,"main","cacheDir");
296  if(tmp!=NULL){
297    char* myRequest=getFilenameForRequest(conf,request);
298    char* md5str=getMd5(myRequest);
299    free(myRequest);
300    char* fname=(char*)malloc(sizeof(char)*(strlen(tmp->value)+strlen(md5str)+6));
301    sprintf(fname,"%s/%s.zca",tmp->value,md5str);
302    zooLock* lck=lockFile(conf,fname,'w');
303    if(lck!=NULL){
304#ifdef DEBUG
305      fprintf(stderr,"Cache list : %s\n",fname);
306      fflush(stderr);
307#endif
308      FILE* fo=fopen(fname,"w+");
309      if(fo==NULL){
310#ifdef DEBUG
311        fprintf (stderr, "Failed to open %s for writing: %s\n",fname, strerror(errno));
312#endif
313        filepath = NULL;
314        unlockFile(conf,lck);
315        return;
316      }
317      fwrite(content,sizeof(char),length,fo);
318      unlockFile(conf,lck);
319      fclose(fo);
320       
321      if (filepath != NULL) {
322        strncpy(filepath, fname, max_path);
323      }
324
325      sprintf(fname,"%s/%s.zcm",tmp->value,md5str);
326      fo=fopen(fname,"w+");
327#ifdef DEBUG
328      fprintf(stderr,"MIMETYPE: %s\n",mimeType);
329#endif
330      fwrite(mimeType,sizeof(char),strlen(mimeType),fo);
331      fclose(fo);
332
333      sprintf(fname,"%s/%s.zcp",tmp->value,md5str);
334      fo=fopen(fname,"w+");
335      char* origin=getProvenance(conf,request);
336#ifdef DEBUG
337      fprintf(stderr,"ORIGIN: %s\n",mimeType);
338#endif
339      fwrite(origin,sizeof(char),strlen(origin),fo);
340      fclose(fo);
341
342      free(md5str);
343      free(fname);
344    }
345  }
346  else {
347    filepath = NULL;
348  }       
349}
350
351/**
352 * Verify if a url is available in the cache
353 *
354 * @param conf the maps containing the settings of the main.cfg file
355 * @param request the url
356 * @return the full name of the cached file if any, NULL in other case
357 * @warning make sure to free resources returned by this function (if not NULL)
358 */
359char* isInCache(maps* conf,char* request){
360  map* tmpUrl=getMapFromMaps(conf,"main","tmpUrl");
361  map* tmpM=getMapFromMaps(conf,"main","cacheDir");
362  if(tmpM==NULL)
363    tmpM=getMapFromMaps(conf,"main","tmpPath");
364  if(strstr(request,tmpUrl->value)!=NULL){
365    map* tmpPath=getMapFromMaps(conf,"main","tmpPath");
366    char* tmpStr=strstr(request,tmpUrl->value);
367    char* tmpStr1=zStrdup(tmpStr+strlen(tmpUrl->value));
368    char* res=(char*) malloc((strlen(tmpPath->value)+strlen(tmpStr1)+2)*sizeof(char));
369    sprintf(res,"%s/%s",tmpPath->value,tmpStr1);
370    free(tmpStr1);
371    return res;
372  }
373#ifdef MS_FORCE_LOCAL_FILE_USE
374  map* msUrl=getMapFromMaps(conf,"main","mapserverAddress");
375  if(msUrl!=NULL && strstr(request,msUrl->value)!=NULL){
376    char *tmpStr=strstr(request,"?");
377    char *cursor=zStrdup(tmpStr+1);
378    char *token, *saveptr;
379    token = strtok_r (cursor, "&", &saveptr);
380    while(token!=NULL){
381      char *token1, *saveptr1;
382      token1 = strtok_r (token, "=", &saveptr1);
383      char *name=NULL;
384      while(token1!=NULL){
385        if(name==NULL)
386          name=zStrdup(token1);
387        else
388          if(strcasecmp(name,"map")==0){
389            mapObj *myMap=msLoadMap(token1,NULL);
390            char * res=zStrdup(myMap->layers[0]->data);
391            free(name);
392            free(cursor);
393            msFreeMap(myMap);
394            return res;
395          }
396        token1 = strtok_r (NULL, "=", &saveptr1);
397      }
398      token = strtok_r (NULL, "&", &saveptr);
399    }
400    free(cursor);
401  }
402#endif 
403  if(strncasecmp(request,"file://",7)==0){
404    char* tmpStr=zStrdup(request+7);
405    setMapInMaps(conf,"lenv",tmpStr,"local");
406    return tmpStr;
407  }
408  else{
409    char* myRequest=getFilenameForRequest(conf,request);
410    char* md5str=getMd5(myRequest);
411    free(myRequest);
412#ifdef DEBUG
413    fprintf(stderr,"MD5STR : (%s)\n\n",md5str);
414#endif
415    char* fname=(char*)malloc(sizeof(char)*(strlen(tmpM->value)+strlen(md5str)+6));
416    sprintf(fname,"%s/%s.zca",tmpM->value,md5str);
417    zStatStruct f_status;
418    int s=zStat(fname, &f_status);
419    if(s==0 && f_status.st_size>0){
420      free(md5str);
421      return fname;
422    }
423    free(md5str);
424    free(fname);
425  }
426  return NULL;
427}
428
429/**
430 * Read the downloaded file for a specific input
431 *
432 * @param m the maps containing the settings of the main.cfg file
433 * @param in the input
434 * @param index the input index
435 * @param hInternet the internet connection
436 * @param error the error map pointer
437 * @return 0 in case of success, -1 in case of failure
438 */
439int readCurrentInput(maps** m,maps** in,int* index,HINTERNET* hInternet,map** error){
440 
441  int shouldClean=-1;
442  map* tmp1;
443  char sindex[5];
444  maps* content=*in;
445  map* length=getMap(content->content,"length");
446  map* memUse=getMapFromMaps(*m,"main","memory");
447  if(length==NULL){
448    length=createMap("length","1");
449    shouldClean=1;
450  }
451  for(int i=0;i<atoi(length->value);i++){
452    char* fcontent;
453    char *mimeType=NULL;
454    int fsize=0;
455    char oriname[12];
456    char cname[15];
457    char vname[11];
458    char vname1[11];
459    char sname[9];
460    char mname[15];
461    char icname[14];
462    char xname[16];
463    char bname[8];
464    char hname[11];
465    char oname[12];
466    char ufile[12];   
467    if(*index>0)
468      sprintf(vname1,"value_%d",*index);
469    else
470      sprintf(vname1,"value");
471   
472    if(i>0){
473      sprintf(cname,"cache_file_%d",i);
474      tmp1=getMap(content->content,cname);
475      sprintf(oriname,"origin_%d",i);
476      sprintf(vname,"value_%d",i);
477      sprintf(sname,"size_%d",i);
478      sprintf(mname,"mimeType_%d",i);
479      sprintf(icname,"isCached_%d",i);
480      sprintf(xname,"Reference_%d",i);
481      sprintf(bname,"body_%d",i);
482      sprintf(hname,"headers_%d",i);
483      sprintf(oname,"Order_%d",i);
484      sprintf(ufile,"use_file_%d",i);
485    }else{
486      sprintf(cname,"cache_file");
487      sprintf(oriname,"origin");
488      sprintf(vname,"value");
489      sprintf(sname,"size");
490      sprintf(mname,"mimeType");
491      sprintf(icname,"isCached");
492      sprintf(xname,"Reference");
493      sprintf(bname,"body");
494      sprintf(hname,"headers");
495      sprintf(oname,"Order");
496      sprintf(ufile,"use_file");
497    }
498   
499    map* tmap=getMap(content->content,oname);
500    sprintf(sindex,"%d",*index+1);
501    if((tmp1=getMap(content->content,xname))!=NULL && tmap!=NULL && strcasecmp(tmap->value,sindex)==0){
502
503      if(getMap(content->content,icname)==NULL) {
504        if(memUse==NULL || strcasecmp(memUse->value,"load")==0){
505          fcontent=(char*)malloc((hInternet->ihandle[*index].nDataLen+1)*sizeof(char));
506          if(fcontent == NULL){
507            errorException(*m, _("Unable to allocate memory"), "InternalError",NULL);
508            return -1;
509          }
510          size_t dwRead;
511          InternetReadFile(hInternet->ihandle[*index], 
512                           (LPVOID)fcontent, 
513                           hInternet->ihandle[*index].nDataLen, 
514                           &dwRead);
515          fcontent[hInternet->ihandle[*index].nDataLen]=0;
516        }
517        fsize=hInternet->ihandle[*index].nDataLen;
518        if(hInternet->ihandle[*index].mimeType==NULL)
519          mimeType=zStrdup("none");
520        else
521          mimeType=zStrdup(hInternet->ihandle[*index].mimeType);             
522       
523        map* tmpMap=getMapOrFill(&(*in)->content,vname,"");
524        if(memUse==NULL || strcasecmp(memUse->value,"load")==0){
525          free(tmpMap->value);
526          tmpMap->value=(char*)malloc((fsize+1)*sizeof(char));
527          if(tmpMap->value==NULL){
528            return errorException(*m, _("Unable to allocate memory"), "InternalError",NULL);
529          }
530          memcpy(tmpMap->value,fcontent,(fsize+1)*sizeof(char));
531        }else
532          addToMap((*in)->content,ufile,"true");
533        if(hInternet->ihandle[*index].code!=200){
534          const char *error_rep_str=_("Unable to download the file for the input <%s>, response code was : %d.");
535          char *error_msg=(char*)malloc((strlen(error_rep_str)+strlen(content->name)+4)*sizeof(char));
536          sprintf(error_msg,error_rep_str,content->name,hInternet->ihandle[*index].code);
537          if(*error==NULL){
538            *error=createMap("text",error_msg);
539            addToMap(*error,"locator",content->name);
540            addToMap(*error,"code","InvalidParameterValue");
541          }else{
542            int nb=1;
543            map* tmpMap=getMap(*error,"length");
544            if(tmpMap!=NULL)
545              nb=atoi(tmpMap->value);
546            setMapArray(*error,"text",nb,error_msg);
547            setMapArray(*error,"locator",nb,content->name);
548            setMapArray(*error,"code",nb,"InvalidParameterValue");
549          }
550          return -1;
551        }
552       
553        char ltmp1[256];
554        sprintf(ltmp1,"%d",fsize);
555        map* tmp=getMapFromMaps(*m,"main","cacheDir");
556        char *request=NULL;
557        if(tmp!=NULL){
558          map* tmp2;
559          char* md5str=NULL;
560          if((tmp2=getMap(content->content,bname))!=NULL){
561            char *tmpStr=(char*)malloc((strlen(tmp1->value)+strlen(tmp2->value)+1)*sizeof(char));
562            sprintf(tmpStr,"%s%s",tmp1->value,tmp2->value);
563            if((tmp2=getMap(content->content,"headers"))!=NULL){
564              char *tmpStr2=zStrdup(tmpStr);
565              free(tmpStr);
566              tmpStr=(char*)malloc((strlen(tmpStr2)+strlen(tmp2->value)+1)*sizeof(char));
567              sprintf(tmpStr,"%s%s",tmpStr2,tmp2->value);
568              free(tmpStr2);
569            }
570            md5str=getMd5(tmpStr);
571            request=zStrdup(tmpStr);
572            free(tmpStr);
573          }else{
574            char *myRequest=getFilenameForRequest(*m,tmp1->value);
575            md5str=getMd5(myRequest);
576            request=zStrdup(tmp1->value);
577            free(myRequest);
578          }
579          char* fname=(char*)malloc(sizeof(char)*(strlen(tmp->value)+strlen(md5str)+6));
580          sprintf(fname,"%s/%s.zca",tmp->value,md5str);
581          addToMap((*in)->content,cname,fname);
582          free(fname);
583        }
584        addToMap((*in)->content,sname,ltmp1);
585        addToMap((*in)->content,mname,mimeType);
586        char* origin=getProvenance(*m,request);
587        addToMap((*in)->content,oriname,origin);
588        if(memUse==NULL || strcasecmp(memUse->value,"load")==0){
589          addToCache(*m,request,fcontent,mimeType,fsize, NULL, 0);
590          free(fcontent);
591        }else{
592          addToMap((*in)->content,ufile,"true");
593          cacheFile(*m,request,mimeType,fsize,hInternet->ihandle[*index].filename);
594        }
595        free(mimeType);
596        free(request);
597        (*index)++;
598      }
599    }
600  }
601  if(shouldClean>0){
602    freeMap(&length);
603    free(length);
604  }
605  return 0;
606}
607
608/**
609 * Effectively run all the HTTP requests in the queue
610 *
611 * @param m the maps containing the settings of the main.cfg file
612 * @param inputs the maps containing the inputs (defined in the requests+added
613 *  per default based on the zcfg file)
614 * @param hInternet the HINTERNET pointer
615 * @param error the error map pointer
616 * @return 0 on success, -1 on failure
617 */
618int runHttpRequests(maps** m,maps** inputs,HINTERNET* hInternet,map** error){
619  int hasAFailure=0;
620  if(hInternet!=NULL && hInternet->nb>0){
621    AddHeaderEntries(hInternet,*m);
622    processDownloads(hInternet);
623    maps* content=*inputs;
624    int index=0;
625    while(content!=NULL){
626      if(content->child!=NULL){
627        maps* cursor=content->child;
628        while(cursor!=NULL){
629          int red=readCurrentInput(m,&cursor,&index,hInternet,error);
630          if(red<0)
631            hasAFailure=red;
632          cursor=cursor->next;
633        }
634      }
635      else{
636        int red=readCurrentInput(m,&content,&index,hInternet,error);
637        if(red<0)
638          hasAFailure=red;
639      }
640      content=content->next;
641    }
642  }
643  return hasAFailure;
644}
645
646/**
647 * Add a request in the download queue
648 *
649 * @param m the maps containing the settings of the main.cfg file
650 * @param url the url to add to the queue
651 */
652void addRequestToQueue(maps** m,HINTERNET* hInternet,const char* url,bool req){
653  hInternet->waitingRequests[hInternet->nb]=zStrdup(url);
654  if(req)
655    InternetOpenUrl(hInternet,hInternet->waitingRequests[hInternet->nb],NULL,0,INTERNET_FLAG_NO_CACHE_WRITE,0,*m);
656  maps *oreq=getMaps(*m,"orequests");
657  if(oreq==NULL){
658    oreq=createMaps("orequests");
659    oreq->content=createMap("value",url);
660    addMapsToMaps(m,oreq);
661    freeMaps(&oreq);
662    free(oreq);
663  }else{
664    setMapArray(oreq->content,"value",hInternet->nb,url);
665  }
666}
667
668/**
669 * Try to load file from cache or download a remote file if not in cache
670 *
671 * @param m the maps containing the settings of the main.cfg file
672 * @param content the map to update
673 * @param hInternet the HINTERNET pointer
674 * @param url the url to fetch
675 * @return 0
676 */
677int loadRemoteFile(maps** m,map** content,HINTERNET* hInternet,char *url){
678  char* fcontent = NULL;
679  char* cached=isInCache(*m,url);
680  char *mimeType=NULL;
681  char *origin=NULL;
682  long long fsize=0;
683  map* memUse=getMapFromMaps(*m,"main","memory");
684
685  map* t=getMap(*content,"xlink:href");
686  if(t==NULL){
687    t=getMap((*content),"href");
688    addToMap(*content,"xlink:href",url);
689  }
690
691  if(cached!=NULL){
692    zStatStruct f_status;
693    int s=zStat(cached, &f_status);
694    if(s==0){
695      zooLock* lck=lockFile(*m,cached,'r');
696      if(lck==NULL)
697        return -1;
698      fsize=f_status.st_size;
699      if(memUse==NULL || strcasecmp(memUse->value,"load")==0){
700        fcontent=(char*)malloc(sizeof(char)*(f_status.st_size+1));
701        FILE* f=fopen(cached,"rb");
702        if(f!=NULL){
703          fread(fcontent,f_status.st_size,1,f);
704          fcontent[fsize]=0;
705          fclose(f);
706        }
707      }
708      addToMap(*content,"cache_file",cached);
709      unlockFile(*m,lck);
710    }
711    map* isLocalFile=getMapFromMaps(*m,"lenv",cached);
712    if(isLocalFile==NULL){
713      cached[strlen(cached)-1]='m';
714      s=zStat(cached, &f_status);
715      if(s==0){
716        zooLock* lck=lockFile(*m,cached,'r');
717        if(lck==NULL)
718          return -1;
719        mimeType=(char*)malloc(sizeof(char)*(f_status.st_size+1));
720        FILE* f=fopen(cached,"rb");
721        fread(mimeType,f_status.st_size,1,f);
722        mimeType[f_status.st_size]=0;
723        fclose(f);
724        unlockFile(*m,lck);
725      }
726      cached[strlen(cached)-1]='p';
727      s=zStat(cached, &f_status);
728      if(s==0){
729        zooLock* lck=lockFile(*m,cached,'r');
730        if(lck==NULL)
731          return -1;
732        origin=(char*)malloc(sizeof(char)*(f_status.st_size+1));
733        FILE* f=fopen(cached,"rb");
734        fread(origin,f_status.st_size,1,f);
735        mimeType[f_status.st_size]=0;
736        fclose(f);
737        unlockFile(*m,lck);
738      }
739    }   
740  }else{   
741    addRequestToQueue(m,hInternet,url,true);
742    return 0;
743  }
744  if(fsize==0){
745    return errorException(*m, _("Unable to download the file."), "InternalError",NULL);
746  }
747  if(mimeType!=NULL){
748    addToMap(*content,"fmimeType",mimeType);
749  }
750  if(origin!=NULL){
751    addToMap(*content,"origin",origin);
752  }
753
754  map* tmpMap=getMapOrFill(content,"value","");
755  if(memUse==NULL || strcasecmp(memUse->value,"load")==0){
756    free(tmpMap->value);
757    tmpMap->value=(char*)malloc((fsize+1)*sizeof(char));
758    if(tmpMap->value==NULL || fcontent == NULL)
759      return errorException(*m, _("Unable to allocate memory"), "InternalError",NULL);
760    memcpy(tmpMap->value,fcontent,(fsize+1)*sizeof(char));
761  }
762 
763  char ltmp1[256];
764  sprintf(ltmp1,"%lld",fsize);
765  addToMap(*content,"size",ltmp1);
766  if(cached==NULL){
767    if(memUse==NULL || strcasecmp(memUse->value,"load")==0)
768      addToCache(*m,url,fcontent,mimeType,fsize, NULL, 0);
769    else
770      cacheFile(*m,url,mimeType,fsize,hInternet->ihandle[hInternet->nb-1].filename);
771  }
772  else{
773    addToMap(*content,"isCached","true");
774    map* tmp=getMapFromMaps(*m,"main","cacheDir");
775    map* tmp1=getMap((*content),"cache_file");
776    if(tmp!=NULL && tmp1==NULL){
777      map *c=getMap((*content),"xlink:href");
778      if(strncasecmp(c->value,"file://",7)!=0){
779        char *myRequest=getFilenameForRequest(*m,c->value);
780        char* md5str=getMd5(myRequest);
781        free(myRequest);
782        char* fname=(char*)malloc(sizeof(char)*(strlen(tmp->value)+strlen(md5str)+6));
783        sprintf(fname,"%s/%s.zca",tmp->value,md5str);
784        addToMap(*content,"cache_file",fname);
785        free(fname);
786        free(md5str);
787      }
788    }
789  }
790  if(fcontent!=NULL)
791    free(fcontent);
792  if(mimeType!=NULL)
793    free(mimeType);
794  if(cached!=NULL)
795    free(cached);
796  return 0;
797}
Note: See TracBrowser for help on using the repository browser.

Search

Context Navigation

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