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

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

Make this ZOO-Kernel working properly on windows platform again.

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