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

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

Add support for output style definition depending on geometry type (msStylePoly, msStylePoint, msStrylLine). Upload shared data in remote_persitent_data_path rather than remote_data_path (used for not shared data). In case output data should be published and the data is empty (nb_pixels or nb_features is set to 0) then, the ZOO-Kernel returns an ExceptionReport? with an Exception for every output.

  • Property svn:keywords set to Id
File size: 22.1 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=strdup(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[dlen+1];
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* tmpM=getMapFromMaps(conf,"main","cacheDir");
359  if(tmpM!=NULL){
360    if(strncasecmp(request,"file://",7)==0){
361      char* tmpStr=zStrdup(request+7);
362      fprintf(stderr,"**** %s %d %s \n",__FILE__,__LINE__,tmpStr);
363      return tmpStr;
364    }
365    else{
366      char* myRequest=getFilenameForRequest(conf,request);
367      char* md5str=getMd5(myRequest);
368      free(myRequest);
369#ifdef DEBUG
370      fprintf(stderr,"MD5STR : (%s)\n\n",md5str);
371#endif
372      char* fname=(char*)malloc(sizeof(char)*(strlen(tmpM->value)+strlen(md5str)+6));
373      sprintf(fname,"%s/%s.zca",tmpM->value,md5str);
374      struct stat f_status;
375      int s=stat(fname, &f_status);
376      if(s==0 && f_status.st_size>0){
377        free(md5str);
378        return fname;
379      }
380      free(md5str);
381      free(fname);
382    }
383  }
384  return NULL;
385}
386
387/**
388 * Read the downloaded file for a specific input
389 *
390 * @param m the maps containing the settings of the main.cfg file
391 * @param in the input
392 * @param index the input index
393 * @param hInternet the internet connection
394 * @param error the error map pointer
395 * @return 0 in case of success, -1 in case of failure
396 */
397int readCurrentInput(maps** m,maps** in,int* index,HINTERNET* hInternet,map** error){
398 
399  int shouldClean=-1;
400  map* tmp1;
401  char sindex[5];
402  maps* content=*in;
403  map* length=getMap(content->content,"length");
404  map* memUse=getMapFromMaps(*m,"main","memory");
405  if(length==NULL){
406    length=createMap("length","1");
407    shouldClean=1;
408  }
409  for(int i=0;i<atoi(length->value);i++){
410    char* fcontent;
411    char *mimeType=NULL;
412    int fsize=0;
413    char oriname[12];
414    char cname[15];
415    char vname[11];
416    char vname1[11];
417    char sname[9];
418    char mname[15];
419    char icname[14];
420    char xname[16];
421    char bname[8];
422    char hname[11];
423    char oname[12];
424    char ufile[12];   
425    if(*index>0)
426      sprintf(vname1,"value_%d",*index);
427    else
428      sprintf(vname1,"value");
429   
430    if(i>0){
431      sprintf(cname,"cache_file_%d",i);
432      tmp1=getMap(content->content,cname);
433      sprintf(oriname,"origin_%d",i);
434      sprintf(vname,"value_%d",i);
435      sprintf(sname,"size_%d",i);
436      sprintf(mname,"mimeType_%d",i);
437      sprintf(icname,"isCached_%d",i);
438      sprintf(xname,"Reference_%d",i);
439      sprintf(bname,"body_%d",i);
440      sprintf(hname,"headers_%d",i);
441      sprintf(oname,"Order_%d",i);
442      sprintf(ufile,"use_file_%d",i);
443    }else{
444      sprintf(cname,"cache_file");
445      sprintf(oriname,"origin");
446      sprintf(vname,"value");
447      sprintf(sname,"size");
448      sprintf(mname,"mimeType");
449      sprintf(icname,"isCached");
450      sprintf(xname,"Reference");
451      sprintf(bname,"body");
452      sprintf(hname,"headers");
453      sprintf(oname,"Order");
454      sprintf(ufile,"use_file");
455    }
456   
457    map* tmap=getMap(content->content,oname);
458    sprintf(sindex,"%d",*index+1);
459    if((tmp1=getMap(content->content,xname))!=NULL && tmap!=NULL && strcasecmp(tmap->value,sindex)==0){
460
461      if(getMap(content->content,icname)==NULL) {
462        if(memUse==NULL || strcasecmp(memUse->value,"load")==0){
463          fcontent=(char*)malloc((hInternet->ihandle[*index].nDataLen+1)*sizeof(char));
464          if(fcontent == NULL){
465            errorException(*m, _("Unable to allocate memory"), "InternalError",NULL);
466            return -1;
467          }
468          size_t dwRead;
469          InternetReadFile(hInternet->ihandle[*index], 
470                           (LPVOID)fcontent, 
471                           hInternet->ihandle[*index].nDataLen, 
472                           &dwRead);
473          fcontent[hInternet->ihandle[*index].nDataLen]=0;
474        }
475        fsize=hInternet->ihandle[*index].nDataLen;
476        if(hInternet->ihandle[*index].mimeType==NULL)
477          mimeType=zStrdup("none");
478        else
479          mimeType=zStrdup(hInternet->ihandle[*index].mimeType);             
480       
481        map* tmpMap=getMapOrFill(&(*in)->content,vname,"");
482        if(memUse==NULL || strcasecmp(memUse->value,"load")==0){
483          free(tmpMap->value);
484          tmpMap->value=(char*)malloc((fsize+1)*sizeof(char));
485          if(tmpMap->value==NULL){
486            return errorException(*m, _("Unable to allocate memory"), "InternalError",NULL);
487          }
488          memcpy(tmpMap->value,fcontent,(fsize+1)*sizeof(char));
489        }else
490          addToMap((*in)->content,ufile,"true");
491        if(hInternet->ihandle[*index].code!=200){
492          char *error_rep_str=_("Unable to download the file for the input <%s>, response code was : %d.");
493          char *error_msg=(char*)malloc((strlen(error_rep_str)+strlen(content->name)+4)*sizeof(char));
494          sprintf(error_msg,error_rep_str,content->name,hInternet->ihandle[*index].code);
495          if(*error==NULL){
496            *error=createMap("text",error_msg);
497            addToMap(*error,"locator",content->name);
498            addToMap(*error,"code","InvalidParameterValue");
499          }else{
500            int nb=1;
501            map* tmpMap=getMap(*error,"length");
502            if(tmpMap!=NULL)
503              nb=atoi(tmpMap->value);
504            setMapArray(*error,"text",nb,error_msg);
505            setMapArray(*error,"locator",nb,content->name);
506            setMapArray(*error,"code",nb,"InvalidParameterValue");
507          }
508          return -1;
509        }
510       
511        char ltmp1[256];
512        sprintf(ltmp1,"%d",fsize);
513        map* tmp=getMapFromMaps(*m,"main","cacheDir");
514        char *request=NULL;
515        if(tmp!=NULL){
516          map* tmp2;
517          char* md5str=NULL;
518          if((tmp2=getMap(content->content,bname))!=NULL){
519            char *tmpStr=(char*)malloc((strlen(tmp1->value)+strlen(tmp2->value)+1)*sizeof(char));
520            sprintf(tmpStr,"%s%s",tmp1->value,tmp2->value);
521            if((tmp2=getMap(content->content,"headers"))!=NULL){
522              char *tmpStr2=zStrdup(tmpStr);
523              free(tmpStr);
524              tmpStr=(char*)malloc((strlen(tmpStr2)+strlen(tmp2->value)+1)*sizeof(char));
525              sprintf(tmpStr,"%s%s",tmpStr2,tmp2->value);
526              free(tmpStr2);
527            }
528            md5str=getMd5(tmpStr);
529            request=zStrdup(tmpStr);
530            free(tmpStr);
531          }else{
532            char *myRequest=getFilenameForRequest(*m,tmp1->value);
533            md5str=getMd5(myRequest);
534            request=zStrdup(tmp1->value);
535            free(myRequest);
536          }
537          char* fname=(char*)malloc(sizeof(char)*(strlen(tmp->value)+strlen(md5str)+6));
538          sprintf(fname,"%s/%s.zca",tmp->value,md5str);
539          addToMap((*in)->content,cname,fname);
540          free(fname);
541        }
542        addToMap((*in)->content,sname,ltmp1);
543        addToMap((*in)->content,mname,mimeType);
544        char* origin=getProvenance(*m,request);
545        addToMap((*in)->content,oriname,origin);
546        if(memUse==NULL || strcasecmp(memUse->value,"load")==0){
547          addToCache(*m,request,fcontent,mimeType,fsize, NULL, 0);
548          free(fcontent);
549        }else{
550          addToMap((*in)->content,ufile,"true");
551          cacheFile(*m,request,mimeType,fsize,hInternet->ihandle[*index].filename);
552        }
553        free(mimeType);
554        free(request);
555        (*index)++;
556      }
557    }
558  }
559  if(shouldClean>0){
560    freeMap(&length);
561    free(length);
562  }
563  return 0;
564}
565
566/**
567 * Effectively run all the HTTP requests in the queue
568 *
569 * @param m the maps containing the settings of the main.cfg file
570 * @param inputs the maps containing the inputs (defined in the requests+added
571 *  per default based on the zcfg file)
572 * @param hInternet the HINTERNET pointer
573 * @param error the error map pointer
574 * @return 0 on success, -1 on failure
575 */
576int runHttpRequests(maps** m,maps** inputs,HINTERNET* hInternet,map** error){
577  int hasAFailure=0;
578  if(hInternet!=NULL && hInternet->nb>0){
579    AddHeaderEntries(hInternet,*m);
580    processDownloads(hInternet);
581    maps* content=*inputs;
582    int index=0;
583    while(content!=NULL){
584      if(content->child!=NULL){
585        maps* cursor=content->child;
586        while(cursor!=NULL){
587          int red=readCurrentInput(m,&cursor,&index,hInternet,error);
588          if(red<0)
589            hasAFailure=red;
590          cursor=cursor->next;
591        }
592      }
593      else{
594        int red=readCurrentInput(m,&content,&index,hInternet,error);
595        if(red<0)
596          hasAFailure=red;
597      }
598      content=content->next;
599    }
600  }
601  return hasAFailure;
602}
603
604/**
605 * Add a request in the download queue
606 *
607 * @param m the maps containing the settings of the main.cfg file
608 * @param url the url to add to the queue
609 */
610void addRequestToQueue(maps** m,HINTERNET* hInternet,const char* url,bool req){
611  hInternet->waitingRequests[hInternet->nb]=strdup(url);
612  if(req)
613    InternetOpenUrl(hInternet,hInternet->waitingRequests[hInternet->nb],NULL,0,INTERNET_FLAG_NO_CACHE_WRITE,0,*m);
614  maps *oreq=getMaps(*m,"orequests");
615  if(oreq==NULL){
616    oreq=createMaps("orequests");
617    oreq->content=createMap("value",url);
618    addMapsToMaps(m,oreq);
619    freeMaps(&oreq);
620    free(oreq);
621  }else{
622    setMapArray(oreq->content,"value",hInternet->nb,url);
623  }
624}
625
626/**
627 * Try to load file from cache or download a remote file if not in cache
628 *
629 * @param m the maps containing the settings of the main.cfg file
630 * @param content the map to update
631 * @param hInternet the HINTERNET pointer
632 * @param url the url to fetch
633 * @return 0
634 */
635int loadRemoteFile(maps** m,map** content,HINTERNET* hInternet,char *url){
636  char* fcontent = NULL;
637  char* cached=isInCache(*m,url);
638  char *mimeType=NULL;
639  char *origin=NULL;
640  int fsize=0;
641  map* memUse=getMapFromMaps(*m,"main","memory");
642
643  map* t=getMap(*content,"xlink:href");
644  if(t==NULL){
645    t=getMap((*content),"href");
646    addToMap(*content,"xlink:href",url);
647  }
648
649  if(cached!=NULL){
650    struct stat f_status;
651    int s=stat(cached, &f_status);
652    if(s==0){
653      zooLock* lck=lockFile(*m,cached,'r');
654      if(lck==NULL)
655        return -1;
656      fsize=f_status.st_size;
657      if(memUse==NULL || strcasecmp(memUse->value,"load")==0){
658        fcontent=(char*)malloc(sizeof(char)*(f_status.st_size+1));
659        FILE* f=fopen(cached,"rb");
660        if(f!=NULL){
661          fread(fcontent,f_status.st_size,1,f);
662          fcontent[fsize]=0;
663          fclose(f);
664        }
665      }
666      addToMap(*content,"cache_file",cached);
667      unlockFile(*m,lck);
668    }
669    cached[strlen(cached)-1]='m';
670    s=stat(cached, &f_status);
671    if(s==0){
672      zooLock* lck=lockFile(*m,cached,'r');
673      if(lck==NULL)
674        return -1;
675      mimeType=(char*)malloc(sizeof(char)*(f_status.st_size+1));
676      FILE* f=fopen(cached,"rb");
677      fread(mimeType,f_status.st_size,1,f);
678      mimeType[f_status.st_size]=0;
679      fclose(f);
680      unlockFile(*m,lck);
681    }
682    cached[strlen(cached)-1]='p';
683    s=stat(cached, &f_status);
684    if(s==0){
685      zooLock* lck=lockFile(*m,cached,'r');
686      if(lck==NULL)
687        return -1;
688      origin=(char*)malloc(sizeof(char)*(f_status.st_size+1));
689      FILE* f=fopen(cached,"rb");
690      fread(origin,f_status.st_size,1,f);
691      mimeType[f_status.st_size]=0;
692      fclose(f);
693      unlockFile(*m,lck);
694    }
695  }else{   
696    addRequestToQueue(m,hInternet,url,true);
697    return 0;
698  }
699  if(fsize==0){
700    return errorException(*m, _("Unable to download the file."), "InternalError",NULL);
701  }
702  if(mimeType!=NULL){
703    addToMap(*content,"fmimeType",mimeType);
704  }
705  if(origin!=NULL){
706    addToMap(*content,"origin",origin);
707  }
708
709  map* tmpMap=getMapOrFill(content,"value","");
710  if(memUse==NULL || strcasecmp(memUse->value,"load")==0){
711    free(tmpMap->value);
712    tmpMap->value=(char*)malloc((fsize+1)*sizeof(char));
713    if(tmpMap->value==NULL || fcontent == NULL)
714      return errorException(*m, _("Unable to allocate memory"), "InternalError",NULL);
715    memcpy(tmpMap->value,fcontent,(fsize+1)*sizeof(char));
716  }
717 
718  char ltmp1[256];
719  sprintf(ltmp1,"%d",fsize);
720  addToMap(*content,"size",ltmp1);
721  if(cached==NULL){
722    if(memUse==NULL || strcasecmp(memUse->value,"load")==0)
723      addToCache(*m,url,fcontent,mimeType,fsize, NULL, 0);
724    else
725      cacheFile(*m,url,mimeType,fsize,hInternet->ihandle[hInternet->nb-1].filename);
726  }
727  else{
728    addToMap(*content,"isCached","true");
729    map* tmp=getMapFromMaps(*m,"main","cacheDir");
730    if(tmp!=NULL){
731      map *c=getMap((*content),"xlink:href");
732      if(strncasecmp(c->value,"file://",7)!=0){
733        char *myRequest=getFilenameForRequest(*m,c->value);
734        char* md5str=getMd5(myRequest);
735        free(myRequest);
736        char* fname=(char*)malloc(sizeof(char)*(strlen(tmp->value)+strlen(md5str)+6));
737        sprintf(fname,"%s/%s.zca",tmp->value,md5str);
738        addToMap(*content,"cache_file",fname);
739        free(fname);
740        free(md5str);
741      }
742    }
743  }
744  free(fcontent);
745  free(mimeType);
746  free(cached);
747  return 0;
748}
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