source: branches/prototype-v0/zoo-project/zoo-kernel/caching.c @ 899

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

Fix header files location

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