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

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

Check for md5sum of any file in the cache to avoid sending the same file on HPC server twice. Add the multiple LiteralData? inputs support for HPC services. Remove condition for defining SCALE for every band in the outputed MapServer? mapfile.

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