/* * Author : GĂ©rald Fenoy * * Copyright 2008-2015 GeoLabs SARL. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ #include #include #include "service.h" #include "service_internal.h" #include "response_print.h" #include "caching.h" #ifdef MS_FORCE_LOCAL_FILE_USE #include "ogr_api.h" #include "mapserver.h" #endif /** * Compute md5 * * @param url the char* * @return a char* representing the md5 of the url * @warning make sure to free resources returned by this function */ char* getMd5(char* url){ EVP_MD_CTX *md5ctx=EVP_MD_CTX_create(); char* fresult=(char*)malloc((EVP_MAX_MD_SIZE+1)*sizeof(char)); unsigned char result[EVP_MAX_MD_SIZE]; unsigned int len; EVP_DigestInit(md5ctx, EVP_md5()); EVP_DigestUpdate(md5ctx, url, strlen(url)); EVP_DigestFinal_ex(md5ctx,result,&len); EVP_MD_CTX_destroy(md5ctx); int i; for(i = 0; i < len; i++){ if(i>0){ char *tmp=zStrdup(fresult); sprintf(fresult,"%s%02x", tmp,result[i]); free(tmp); } else sprintf(fresult,"%02x",result[i]); } return fresult; } /** * Compute md5 of a file * * @param file the char* * @return a char* representing the md5 of the url * @warning make sure to free resources returned by this function */ char* getMd5f(char* file){ EVP_MD_CTX *md5ctx=EVP_MD_CTX_create(); char* fresult=(char*)malloc((EVP_MAX_MD_SIZE+1)*sizeof(char)); unsigned char result[EVP_MAX_MD_SIZE]; unsigned int len; int bytes; int dlen=65536; unsigned char data[65537]; FILE *inFile = fopen (file, "rb"); EVP_DigestInit(md5ctx, EVP_md5()); while ((bytes = fread (data, sizeof(unsigned char), dlen, inFile)) != 0) EVP_DigestUpdate(md5ctx, data, bytes); EVP_DigestFinal_ex(md5ctx,result,&len); EVP_MD_CTX_destroy(md5ctx); int i; for(i = 0; i < len; i++){ if(i>0){ char *tmp=zStrdup(fresult); sprintf(fresult,"%s%02x", tmp,result[i]); free(tmp); } else sprintf(fresult,"%02x",result[i]); } fclose (inFile); return fresult; } /** * Create a URL by appending every request header listed in the security * section.This imply that the URL will contain any authentication * informations that should be fowarded to the server from which de input * was download. * @param conf the main configuration maps * @param request the URL to transform. * @return a char* that contain the original URL plus potential header (only for * hosts that are not shared). * @warning Be sure to free the memory returned by this function. */ char* getFilenameForRequest(maps* conf, const char* request){ map* passThrough=getMapFromMaps(conf,"security","attributes"); map* targetHosts=getMapFromMaps(conf,"security","hosts"); char* passedHeader[10]; int cnt=0; char *res=zStrdup(request); char *toAppend=NULL; if(passThrough!=NULL && targetHosts!=NULL){ char *tmp=zStrdup(passThrough->value); char *token, *saveptr; token = strtok_r (tmp, ",", &saveptr); int i; if((strstr(targetHosts->value,"*")!=NULL || isProtectedHost(targetHosts->value,request)==1) && strncasecmp(getProvenance(conf,request),"SHARED",6)!=0){ while (token != NULL){ int length=strlen(token)+6; char* tmp1=(char*)malloc(length*sizeof(char)); map* tmpMap; snprintf(tmp1,6,"HTTP_"); int j; for(j=0;token[j]!='\0';j++){ if(token[j]!='-') tmp1[5+j]=toupper(token[j]); else tmp1[5+j]='_'; tmp1[5+j+1]='\0'; } tmpMap = getMapFromMaps(conf,"renv",tmp1); if(tmpMap!=NULL){ if(toAppend==NULL){ toAppend=(char*)malloc((strlen(tmpMap->value)+1)*sizeof(char)); sprintf(toAppend,"%s",tmpMap->value); }else{ char *tmp3=zStrdup(toAppend); toAppend=(char*)realloc(toAppend,(strlen(tmpMap->value)+strlen(tmp3)+2)*sizeof(char)); sprintf(toAppend,"%s,%s",tmp3,tmpMap->value); free(tmp3); } } free(tmp1); cnt+=1; token = strtok_r (NULL, ",", &saveptr); } } free(tmp); } if(toAppend!=NULL){ char *tmp3=zStrdup(res); res=(char*)realloc(res,(strlen(tmp3)+strlen(toAppend)+1)*sizeof(char)); sprintf(res,"%s%s",tmp3,toAppend); free(tmp3); free(toAppend); } return res; } /** * Store MD5 of the content of a file * @file char* the full path of the file */ int storeMd5(char* file){ char* storage=zStrdup(file); char* md5fstr=getMd5f(file); storage[strlen(storage)-2]='m'; storage[strlen(storage)-1]='d'; FILE* fo=fopen(storage,"w+"); if(fo==NULL) return 1; fwrite(md5fstr,sizeof(char),strlen(md5fstr),fo); free(md5fstr); free(storage); fclose(fo); return 0; } /** * Cache a file for a given request. * For each cached file, the are two files stored, a .zca and a .zcm containing * the downloaded content and the mimeType respectively. * * @param conf the maps containing the settings of the main.cfg file * @param request the url used too fetch the content * @param content the downloaded content * @param mimeType the content mimeType * @param length the content size * @param filepath a buffer for storing the path of the cached file; may be NULL * @param max_path the size of the allocated filepath buffer */ void cacheFile(maps* conf,char* request,char* mimeType,int length,char* filename){ map* tmp=getMapFromMaps(conf,"main","cacheDir"); char contentr[4096]; int cred=0; if(tmp!=NULL){ char* myRequest=getFilenameForRequest(conf,request); char* md5str=getMd5(myRequest); free(myRequest); char* fname=(char*)malloc(sizeof(char)*(strlen(tmp->value)+strlen(md5str)+6)); // Store md5 char* md5fstr=getMd5f(filename); sprintf(fname,"%s/%s.zmd",tmp->value,md5str); FILE* fo=fopen(fname,"w+"); #ifdef DEBUG fprintf(stderr,"filename: %s\n",filename); fprintf(stderr,"MD5: %s\n",md5fstr); #endif fwrite(md5fstr,sizeof(char),strlen(md5fstr),fo); free(md5fstr); fclose(fo); sprintf(fname,"%s/%s.zca",tmp->value,md5str); zooLock* lck=lockFile(conf,fname,'w'); if(lck!=NULL){ #ifdef DEBUG fprintf(stderr,"Cache list : %s\n",fname); fflush(stderr); #endif FILE* fi=fopen(filename,"rb"); sprintf(fname,"%s/%s.zca",tmp->value,md5str); fo=fopen(fname,"w+"); if(fo==NULL){ #ifdef DEBUG fprintf (stderr, "Failed to open %s for writing: %s\n",fname, strerror(errno)); #endif unlockFile(conf,lck); return; } if(fi==NULL){ #ifdef DEBUG fprintf (stderr, "Failed to open %s for reading: %s\n",filename, strerror(errno)); #endif unlockFile(conf,lck); return; } memset(contentr,0,4096); while((cred=fread(contentr,sizeof(char),4096,fi))>0){ fwrite(contentr,sizeof(char),cred,fo); fflush(fo); memset(contentr,0,4096); } unlockFile(conf,lck); fclose(fo); fclose(fi); // Store mimeType sprintf(fname,"%s/%s.zcm",tmp->value,md5str); fo=fopen(fname,"w+"); #ifdef DEBUG fprintf(stderr,"MIMETYPE: %s\n",mimeType); #endif fwrite(mimeType,sizeof(char),strlen(mimeType),fo); fclose(fo); // Store provenance sprintf(fname,"%s/%s.zcp",tmp->value,md5str); fo=fopen(fname,"w+"); char* origin=getProvenance(conf,request); #ifdef DEBUG fprintf(stderr,"ORIGIN: %s\n",mimeType); #endif fwrite(origin,sizeof(char),strlen(origin),fo); fclose(fo); free(md5str); } free(fname); } } /** * Cache a file for a given request. * For each cached file, the are two files stored, a .zca and a .zcm containing * the downloaded content and the mimeType respectively. * * @param conf the maps containing the settings of the main.cfg file * @param request the url used too fetch the content * @param content the downloaded content * @param mimeType the content mimeType * @param length the content size * @param filepath a buffer for storing the path of the cached file; may be NULL * @param max_path the size of the allocated filepath buffer */ void addToCache(maps* conf,char* request,char* content,char* mimeType,int length, char* filepath, size_t max_path){ map* tmp=getMapFromMaps(conf,"main","cacheDir"); if(tmp!=NULL){ char* myRequest=getFilenameForRequest(conf,request); char* md5str=getMd5(myRequest); free(myRequest); char* fname=(char*)malloc(sizeof(char)*(strlen(tmp->value)+strlen(md5str)+6)); sprintf(fname,"%s/%s.zca",tmp->value,md5str); zooLock* lck=lockFile(conf,fname,'w'); if(lck!=NULL){ #ifdef DEBUG fprintf(stderr,"Cache list : %s\n",fname); fflush(stderr); #endif FILE* fo=fopen(fname,"w+"); if(fo==NULL){ #ifdef DEBUG fprintf (stderr, "Failed to open %s for writing: %s\n",fname, strerror(errno)); #endif filepath = NULL; unlockFile(conf,lck); return; } fwrite(content,sizeof(char),length,fo); unlockFile(conf,lck); fclose(fo); if (filepath != NULL) { strncpy(filepath, fname, max_path); } sprintf(fname,"%s/%s.zcm",tmp->value,md5str); fo=fopen(fname,"w+"); #ifdef DEBUG fprintf(stderr,"MIMETYPE: %s\n",mimeType); #endif fwrite(mimeType,sizeof(char),strlen(mimeType),fo); fclose(fo); sprintf(fname,"%s/%s.zcp",tmp->value,md5str); fo=fopen(fname,"w+"); char* origin=getProvenance(conf,request); #ifdef DEBUG fprintf(stderr,"ORIGIN: %s\n",mimeType); #endif fwrite(origin,sizeof(char),strlen(origin),fo); fclose(fo); free(md5str); free(fname); } } else { filepath = NULL; } } /** * Verify if a url is available in the cache * * @param conf the maps containing the settings of the main.cfg file * @param request the url * @return the full name of the cached file if any, NULL in other case * @warning make sure to free resources returned by this function (if not NULL) */ char* isInCache(maps* conf,char* request){ map* tmpUrl=getMapFromMaps(conf,"main","tmpUrl"); map* tmpM=getMapFromMaps(conf,"main","cacheDir"); if(tmpM==NULL) tmpM=getMapFromMaps(conf,"main","tmpPath"); if(strstr(request,tmpUrl->value)!=NULL){ map* tmpPath=getMapFromMaps(conf,"main","tmpPath"); char* tmpStr=strstr(request,tmpUrl->value); char* tmpStr1=zStrdup(tmpStr+strlen(tmpUrl->value)); char* res=(char*) malloc((strlen(tmpPath->value)+strlen(tmpStr1)+2)*sizeof(char)); sprintf(res,"%s/%s",tmpPath->value,tmpStr1); free(tmpStr1); return res; } #ifdef MS_FORCE_LOCAL_FILE_USE map* msUrl=getMapFromMaps(conf,"main","mapserverAddress"); if(msUrl!=NULL && strstr(request,msUrl->value)!=NULL){ char *tmpStr=strstr(request,"?"); char *cursor=zStrdup(tmpStr+1); char *token, *saveptr; token = strtok_r (cursor, "&", &saveptr); while(token!=NULL){ char *token1, *saveptr1; token1 = strtok_r (token, "=", &saveptr1); char *name=NULL; while(token1!=NULL){ if(name==NULL) name=zStrdup(token1); else if(strcasecmp(name,"map")==0){ mapObj *myMap=msLoadMap(token1,NULL); char * res=zStrdup(myMap->layers[0]->data); free(name); free(cursor); msFreeMap(myMap); return res; } token1 = strtok_r (NULL, "=", &saveptr1); } token = strtok_r (NULL, "&", &saveptr); } free(cursor); } #endif if(strncasecmp(request,"file://",7)==0){ char* tmpStr=zStrdup(request+7); setMapInMaps(conf,"lenv",tmpStr,"local"); return tmpStr; } else{ char* myRequest=getFilenameForRequest(conf,request); char* md5str=getMd5(myRequest); free(myRequest); #ifdef DEBUG fprintf(stderr,"MD5STR : (%s)\n\n",md5str); #endif char* fname=(char*)malloc(sizeof(char)*(strlen(tmpM->value)+strlen(md5str)+6)); sprintf(fname,"%s/%s.zca",tmpM->value,md5str); zStatStruct f_status; int s=zStat(fname, &f_status); if(s==0 && f_status.st_size>0){ free(md5str); return fname; } free(md5str); free(fname); } return NULL; } /** * Read the downloaded file for a specific input * * @param m the maps containing the settings of the main.cfg file * @param in the input * @param index the input index * @param hInternet the internet connection * @param error the error map pointer * @return 0 in case of success, -1 in case of failure */ int readCurrentInput(maps** m,maps** in,int* index,HINTERNET* hInternet,map** error){ int shouldClean=-1; map* tmp1; char sindex[5]; maps* content=*in; map* length=getMap(content->content,"length"); map* memUse=getMapFromMaps(*m,"main","memory"); if(length==NULL){ length=createMap("length","1"); shouldClean=1; } for(int i=0;ivalue);i++){ char* fcontent; char *mimeType=NULL; int fsize=0; char oriname[12]; char cname[15]; char vname[11]; char vname1[11]; char sname[9]; char mname[15]; char icname[14]; char xname[16]; char bname[8]; char hname[11]; char oname[12]; char ufile[12]; if(*index>0) sprintf(vname1,"value_%d",*index); else sprintf(vname1,"value"); if(i>0){ sprintf(cname,"cache_file_%d",i); tmp1=getMap(content->content,cname); sprintf(oriname,"origin_%d",i); sprintf(vname,"value_%d",i); sprintf(sname,"size_%d",i); sprintf(mname,"mimeType_%d",i); sprintf(icname,"isCached_%d",i); sprintf(xname,"Reference_%d",i); sprintf(bname,"body_%d",i); sprintf(hname,"headers_%d",i); sprintf(oname,"Order_%d",i); sprintf(ufile,"use_file_%d",i); }else{ sprintf(cname,"cache_file"); sprintf(oriname,"origin"); sprintf(vname,"value"); sprintf(sname,"size"); sprintf(mname,"mimeType"); sprintf(icname,"isCached"); sprintf(xname,"Reference"); sprintf(bname,"body"); sprintf(hname,"headers"); sprintf(oname,"Order"); sprintf(ufile,"use_file"); } map* tmap=getMap(content->content,oname); sprintf(sindex,"%d",*index+1); if((tmp1=getMap(content->content,xname))!=NULL && tmap!=NULL && strcasecmp(tmap->value,sindex)==0){ if(getMap(content->content,icname)==NULL) { if(memUse==NULL || strcasecmp(memUse->value,"load")==0){ fcontent=(char*)malloc((hInternet->ihandle[*index].nDataLen+1)*sizeof(char)); if(fcontent == NULL){ errorException(*m, _("Unable to allocate memory"), "InternalError",NULL); return -1; } size_t dwRead; InternetReadFile(hInternet->ihandle[*index], (LPVOID)fcontent, hInternet->ihandle[*index].nDataLen, &dwRead); fcontent[hInternet->ihandle[*index].nDataLen]=0; } fsize=hInternet->ihandle[*index].nDataLen; if(hInternet->ihandle[*index].mimeType==NULL) mimeType=zStrdup("none"); else mimeType=zStrdup(hInternet->ihandle[*index].mimeType); map* tmpMap=getMapOrFill(&(*in)->content,vname,""); if(memUse==NULL || strcasecmp(memUse->value,"load")==0){ free(tmpMap->value); tmpMap->value=(char*)malloc((fsize+1)*sizeof(char)); if(tmpMap->value==NULL){ return errorException(*m, _("Unable to allocate memory"), "InternalError",NULL); } memcpy(tmpMap->value,fcontent,(fsize+1)*sizeof(char)); }else addToMap((*in)->content,ufile,"true"); if(hInternet->ihandle[*index].code!=200){ const char *error_rep_str=_("Unable to download the file for the input <%s>, response code was : %d."); char *error_msg=(char*)malloc((strlen(error_rep_str)+strlen(content->name)+4)*sizeof(char)); sprintf(error_msg,error_rep_str,content->name,hInternet->ihandle[*index].code); if(*error==NULL){ *error=createMap("text",error_msg); addToMap(*error,"locator",content->name); addToMap(*error,"code","InvalidParameterValue"); }else{ int nb=1; map* tmpMap=getMap(*error,"length"); if(tmpMap!=NULL) nb=atoi(tmpMap->value); setMapArray(*error,"text",nb,error_msg); setMapArray(*error,"locator",nb,content->name); setMapArray(*error,"code",nb,"InvalidParameterValue"); } return -1; } char ltmp1[256]; sprintf(ltmp1,"%d",fsize); map* tmp=getMapFromMaps(*m,"main","cacheDir"); char *request=NULL; if(tmp!=NULL){ map* tmp2; char* md5str=NULL; if((tmp2=getMap(content->content,bname))!=NULL){ char *tmpStr=(char*)malloc((strlen(tmp1->value)+strlen(tmp2->value)+1)*sizeof(char)); sprintf(tmpStr,"%s%s",tmp1->value,tmp2->value); if((tmp2=getMap(content->content,"headers"))!=NULL){ char *tmpStr2=zStrdup(tmpStr); free(tmpStr); tmpStr=(char*)malloc((strlen(tmpStr2)+strlen(tmp2->value)+1)*sizeof(char)); sprintf(tmpStr,"%s%s",tmpStr2,tmp2->value); free(tmpStr2); } md5str=getMd5(tmpStr); request=zStrdup(tmpStr); free(tmpStr); }else{ char *myRequest=getFilenameForRequest(*m,tmp1->value); md5str=getMd5(myRequest); request=zStrdup(tmp1->value); free(myRequest); } char* fname=(char*)malloc(sizeof(char)*(strlen(tmp->value)+strlen(md5str)+6)); sprintf(fname,"%s/%s.zca",tmp->value,md5str); addToMap((*in)->content,cname,fname); free(fname); } addToMap((*in)->content,sname,ltmp1); addToMap((*in)->content,mname,mimeType); char* origin=getProvenance(*m,request); addToMap((*in)->content,oriname,origin); if(memUse==NULL || strcasecmp(memUse->value,"load")==0){ addToCache(*m,request,fcontent,mimeType,fsize, NULL, 0); free(fcontent); }else{ addToMap((*in)->content,ufile,"true"); cacheFile(*m,request,mimeType,fsize,hInternet->ihandle[*index].filename); } free(mimeType); free(request); (*index)++; } } } if(shouldClean>0){ freeMap(&length); free(length); } return 0; } /** * Effectively run all the HTTP requests in the queue * * @param m the maps containing the settings of the main.cfg file * @param inputs the maps containing the inputs (defined in the requests+added * per default based on the zcfg file) * @param hInternet the HINTERNET pointer * @param error the error map pointer * @return 0 on success, -1 on failure */ int runHttpRequests(maps** m,maps** inputs,HINTERNET* hInternet,map** error){ int hasAFailure=0; if(hInternet!=NULL && hInternet->nb>0){ AddHeaderEntries(hInternet,*m); processDownloads(hInternet); maps* content=*inputs; int index=0; while(content!=NULL){ if(content->child!=NULL){ maps* cursor=content->child; while(cursor!=NULL){ int red=readCurrentInput(m,&cursor,&index,hInternet,error); if(red<0) hasAFailure=red; cursor=cursor->next; } } else{ int red=readCurrentInput(m,&content,&index,hInternet,error); if(red<0) hasAFailure=red; } content=content->next; } } return hasAFailure; } /** * Add a request in the download queue * * @param m the maps containing the settings of the main.cfg file * @param url the url to add to the queue */ void addRequestToQueue(maps** m,HINTERNET* hInternet,const char* url,bool req){ hInternet->waitingRequests[hInternet->nb]=zStrdup(url); if(req) InternetOpenUrl(hInternet,hInternet->waitingRequests[hInternet->nb],NULL,0,INTERNET_FLAG_NO_CACHE_WRITE,0,*m); maps *oreq=getMaps(*m,"orequests"); if(oreq==NULL){ oreq=createMaps("orequests"); oreq->content=createMap("value",url); addMapsToMaps(m,oreq); freeMaps(&oreq); free(oreq); }else{ setMapArray(oreq->content,"value",hInternet->nb,url); } } /** * Try to load file from cache or download a remote file if not in cache * * @param m the maps containing the settings of the main.cfg file * @param content the map to update * @param hInternet the HINTERNET pointer * @param url the url to fetch * @return 0 */ int loadRemoteFile(maps** m,map** content,HINTERNET* hInternet,char *url){ char* fcontent = NULL; char* cached=isInCache(*m,url); char *mimeType=NULL; char *origin=NULL; long long fsize=0; map* memUse=getMapFromMaps(*m,"main","memory"); map* t=getMap(*content,"xlink:href"); if(t==NULL){ t=getMap((*content),"href"); addToMap(*content,"xlink:href",url); } if(cached!=NULL){ zStatStruct f_status; int s=zStat(cached, &f_status); if(s==0){ zooLock* lck=lockFile(*m,cached,'r'); if(lck==NULL) return -1; fsize=f_status.st_size; if(memUse==NULL || strcasecmp(memUse->value,"load")==0){ fcontent=(char*)malloc(sizeof(char)*(f_status.st_size+1)); FILE* f=fopen(cached,"rb"); if(f!=NULL){ fread(fcontent,f_status.st_size,1,f); fcontent[fsize]=0; fclose(f); } } addToMap(*content,"cache_file",cached); unlockFile(*m,lck); } map* isLocalFile=getMapFromMaps(*m,"lenv",cached); if(isLocalFile==NULL){ cached[strlen(cached)-1]='m'; s=zStat(cached, &f_status); if(s==0){ zooLock* lck=lockFile(*m,cached,'r'); if(lck==NULL) return -1; mimeType=(char*)malloc(sizeof(char)*(f_status.st_size+1)); FILE* f=fopen(cached,"rb"); fread(mimeType,f_status.st_size,1,f); mimeType[f_status.st_size]=0; fclose(f); unlockFile(*m,lck); } cached[strlen(cached)-1]='p'; s=zStat(cached, &f_status); if(s==0){ zooLock* lck=lockFile(*m,cached,'r'); if(lck==NULL) return -1; origin=(char*)malloc(sizeof(char)*(f_status.st_size+1)); FILE* f=fopen(cached,"rb"); fread(origin,f_status.st_size,1,f); mimeType[f_status.st_size]=0; fclose(f); unlockFile(*m,lck); } } }else{ addRequestToQueue(m,hInternet,url,true); return 0; } if(fsize==0){ return errorException(*m, _("Unable to download the file."), "InternalError",NULL); } if(mimeType!=NULL){ addToMap(*content,"fmimeType",mimeType); } if(origin!=NULL){ addToMap(*content,"origin",origin); } map* tmpMap=getMapOrFill(content,"value",""); if(memUse==NULL || strcasecmp(memUse->value,"load")==0){ free(tmpMap->value); tmpMap->value=(char*)malloc((fsize+1)*sizeof(char)); if(tmpMap->value==NULL || fcontent == NULL) return errorException(*m, _("Unable to allocate memory"), "InternalError",NULL); memcpy(tmpMap->value,fcontent,(fsize+1)*sizeof(char)); } char ltmp1[256]; sprintf(ltmp1,"%lld",fsize); addToMap(*content,"size",ltmp1); if(cached==NULL){ if(memUse==NULL || strcasecmp(memUse->value,"load")==0) addToCache(*m,url,fcontent,mimeType,fsize, NULL, 0); else cacheFile(*m,url,mimeType,fsize,hInternet->ihandle[hInternet->nb-1].filename); } else{ addToMap(*content,"isCached","true"); map* tmp=getMapFromMaps(*m,"main","cacheDir"); map* tmp1=getMap((*content),"cache_file"); if(tmp!=NULL && tmp1==NULL){ map *c=getMap((*content),"xlink:href"); if(strncasecmp(c->value,"file://",7)!=0){ char *myRequest=getFilenameForRequest(*m,c->value); char* md5str=getMd5(myRequest); free(myRequest); char* fname=(char*)malloc(sizeof(char)*(strlen(tmp->value)+strlen(md5str)+6)); sprintf(fname,"%s/%s.zca",tmp->value,md5str); addToMap(*content,"cache_file",fname); free(fname); free(md5str); } } } if(fcontent!=NULL) free(fcontent); if(mimeType!=NULL) free(mimeType); if(cached!=NULL) free(cached); return 0; }