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

Last change on this file since 880 was 880, checked in by djay, 6 years ago

Modify memory configuration option gesture. Now, in case you don't have setup memory option in the main section your main.cfg file then, the ZOO-Kernel will load everything in memory and will also store the file containing the input. In case you want the old mode, you have to set memory option to 'load' in your main.cfg file. Fix issue with loading R ZOO-Service located in a subdirectory. Support for XML Execute request containing TEXT_NODE when CDATA_NODE should be used.

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