source: trunk/zoo-project/zoo-kernel/zoo_loader.c @ 490

Last change on this file since 490 was 490, checked in by djay, 10 years ago

Remove memory leaks from ZOO-Kernel. Fix issue #99.

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc
File size: 10.3 KB
RevLine 
[1]1/**
2 * Author : Gérald FENOY
3 *
[69]4 *  Copyright 2008-2011 GeoLabs SARL. All rights reserved.
[1]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
[9]25#define MALLOC_CHECK_ 0
26#define MALLOC_CHECK 0
27
[1]28/**
29 * Specific includes
30 */
[364]31#ifndef WIN32
[1]32#include "fcgio.h"
33#include "fcgi_config.h"
34#include "fcgi_stdio.h"
[364]35#endif
[1]36#include <sys/types.h>
37#include <unistd.h>
[9]38#include "service_internal.h"
[364]39#ifdef WIN32
40#include "windows.h"
41#define strtok_r strtok_s
42#endif
[9]43
[1]44extern "C" {
45#include "cgic.h"
46#include <libxml/tree.h>
47#include <libxml/xmlmemory.h>
48#include <libxml/parser.h>
49#include <libxml/xpath.h>
50#include <libxml/xpathInternals.h>
51}
52
[280]53#include "service_internal.h"
54
[114]55xmlXPathObjectPtr extractFromDoc(xmlDocPtr,const char*);
[490]56int runRequest(map**);
[9]57
58using namespace std;
59
[364]60#ifndef TRUE
[9]61#define TRUE 1
[364]62#endif
63#ifndef FALSE
[1]64#define FALSE -1
[364]65#endif
[1]66
67int cgiMain(){
68  /**
69   * We'll use cgiOut as the default output (stdout) to produce plain text
70   * response.
71   */
72  dup2(fileno(cgiOut),fileno(stdout));
73#ifdef DEBUG
[9]74  fprintf(cgiOut,"Content-Type: text/plain; charset=utf-8\r\nStatus: 200 OK\r\n\r\n");
75  fprintf(cgiOut,"Welcome on ZOO verbose debuging mode \r\n\r\n");
76  fflush(cgiOut);
77  fprintf (stderr, "Addr:%s\n", cgiRemoteAddr); 
[280]78  fprintf (stderr, "RequestMethod: (%s) %d %d\n", cgiRequestMethod,strncasecmp(cgiRequestMethod,"post",4),strncmp(cgiContentType,"text/xml",8)==0 || strncasecmp(cgiRequestMethod,"post",4)==0); 
[9]79  fprintf (stderr, "Request: %s\n", cgiQueryString);
[380]80  fprintf (stderr, "ContentType: %s\n", cgiContentType);
81  fprintf (stderr, "ContentLength: %d\n", cgiContentLength);
[376]82  fflush(stderr);
[1]83#endif
84
[381]85 
86  char *strQuery=NULL;
87  if(cgiQueryString!=NULL)
[453]88    strQuery=zStrdup(cgiQueryString);
[9]89  map* tmpMap=NULL;
[69]90
[99]91  if(strncmp(cgiContentType,"text/xml",8)==0 || 
92     strncasecmp(cgiRequestMethod,"post",4)==0){
[490]93    if(cgiContentLength==0){
[280]94       char *buffer=new char[2];
95       char *res=NULL;
96       int r=0;
[381]97       while((r=fread(buffer,sizeof(char),1,cgiIn))){
[490]98         buffer[1]=0;
[280]99         cgiContentLength+=r;
100         if(res==NULL){
[490]101           res=(char*)malloc(2*sizeof(char));
[280]102           sprintf(res,"%s",buffer);
103         }
104         else{
[453]105           char *tmp=zStrdup(res);
[490]106           res=(char*)realloc(res,(strlen(tmp)+2)*sizeof(char));
[280]107           sprintf(res,"%s%s",tmp,buffer);
108           free(tmp);
109         }
110       }
[490]111       delete[] buffer;
[376]112       if(res==NULL && (strQuery==NULL || strlen(strQuery)==0)){
[459]113         return errorException(NULL,"ZOO-Kernel failed to process your request cause the request was emtpty.","InternalError",NULL);
[376]114       }else{
115         if(strQuery==NULL || strlen(strQuery)==0)
116           tmpMap=createMap("request",res);
[490]117       }
118       if(res!=NULL)
119         free(res);
[1]120    }else{
[280]121      char *buffer=new char[cgiContentLength+1];
[490]122      if(fread(buffer,sizeof(char),cgiContentLength,cgiIn)>0){
[280]123        buffer[cgiContentLength]=0;
124        tmpMap=createMap("request",buffer);
125      }else{
126        buffer[0]=0;
127        char **array, **arrayStep;
128        if (cgiFormEntries(&array) != cgiFormSuccess) {
129          return 1;
130        }
131        arrayStep = array;
132        while (*arrayStep) {
133          char *ivalue=new char[cgiContentLength];
134          cgiFormStringNoNewlines(*arrayStep, ivalue, cgiContentLength);
135          char* tmpValueFinal=(char*) malloc((strlen(*arrayStep)+strlen(ivalue)+1)*sizeof(char));
136          sprintf(tmpValueFinal,"%s=%s",*arrayStep,ivalue);
137          if(strlen(buffer)==0){
138            sprintf(buffer,"%s",tmpValueFinal);
139          }else{
[453]140            char *tmp=zStrdup(buffer);
[280]141            sprintf(buffer,"%s&%s",tmp,tmpValueFinal);
142            free(tmp);
143          }
144          free(tmpValueFinal);
[99]145#ifdef DEBUG
[280]146          fprintf(stderr,"(( \n %s \n %s \n ))",*arrayStep,ivalue);
[99]147#endif
[280]148          delete[]ivalue;
149          arrayStep++;
150        }
[490]151        if(tmpMap!=NULL)
152          addToMap(tmpMap,"request",buffer);
153        else
154          tmpMap=createMap("request",buffer);
[99]155      }
[280]156      delete[]buffer;
[1]157    }
158  }
159  else{
[364]160#ifdef DEBUG
[331]161    dumpMap(tmpMap);
[364]162#endif
[1]163    char **array, **arrayStep;
164    if (cgiFormEntries(&array) != cgiFormSuccess) {
165      return 1;
166    }
167    arrayStep = array;
168    while (*arrayStep) {
169      char *value=new char[cgiContentLength];
170      cgiFormStringNoNewlines(*arrayStep, value, cgiContentLength);
171#ifdef DEBUG
172      fprintf(stderr,"(( \n %s \n %s \n ))",*arrayStep,value);
173#endif
[9]174      if(tmpMap!=NULL)
175        addToMap(tmpMap,*arrayStep,value);
[1]176      else
[9]177        tmpMap=createMap(*arrayStep,value);
[1]178      arrayStep++;
[9]179      delete[]value;
[1]180    }
181    cgiStringArrayFree(array);
182  }
183
[458]184#ifdef WIN32
185  map *tmpReq=getMap(tmpMap,"rfile");
186  if(tmpReq!=NULL){
187    FILE *lf=fopen(tmpReq->value,"r");
188    fseek(lf,0,SEEK_END);
189    long flen=ftell(lf);
190    fseek(lf,0,SEEK_SET);
191    char *buffer=(char*)malloc((flen+1)*sizeof(char));
192    fread(buffer,flen,1,lf);
193    fclose(lf);
194    addToMap(tmpMap,"request",buffer);
195    free(buffer);
196    cgiContentLength=flen+9;
197  }
198#endif
[1]199  /**
200   * In case that the POST method was used, then check if params came in XML
[9]201   * format else try to use the attribute "request" which should be the only
202   * one.
[1]203   */
[10]204  if(strncasecmp(cgiRequestMethod,"post",4)==0 || 
[458]205     (count(tmpMap)==1 && strncmp(tmpMap->value,"<",1)==0) 
206#ifdef WIN32
207     ||tmpReq!=NULL
208#endif
209     ){
[1]210    /**
211     * Store the original XML request in xrequest map
212     */
[9]213    map* t1=getMap(tmpMap,"request");
[331]214    if(t1!=NULL && strncasecmp(t1->value,"<",1)==0){
[9]215      addToMap(tmpMap,"xrequest",t1->value);
[1]216      xmlInitParser();
[9]217      xmlDocPtr doc = xmlParseMemory(t1->value,cgiContentLength);
[280]218      {
219        xmlXPathObjectPtr reqptr=extractFromDoc(doc,"/*[local-name()='Envelope']/*[local-name()='Body']/*");
220        if(reqptr!=NULL){
221          xmlNodeSet* req=reqptr->nodesetval;
222          if(req!=NULL && req->nodeNr==1){
223            addToMap(tmpMap,"soap","true");
[465]224            for(int k=0;k < req->nodeNr;k++){
225              //xmlNsPtr ns=xmlNewNs(req->nodeTab[k],BAD_CAST "http://www.w3.org/2001/XMLSchema-instance",BAD_CAST "xsi");
[280]226              xmlDocSetRootElement(doc, req->nodeTab[k]);
227              xmlChar *xmlbuff;
228              int buffersize;
229              xmlDocDumpFormatMemoryEnc(doc, &xmlbuff, &buffersize, "utf-8", 1);
230              addToMap(tmpMap,"xrequest",(char*)xmlbuff);
231              xmlFree(xmlbuff);
232            }
233          }
[490]234          xmlXPathFreeObject(reqptr);
[280]235        }
236      }
237
[1]238      xmlNodePtr cur = xmlDocGetRootElement(doc);
239      char *tval;
240      tval=NULL;
241      tval = (char*) xmlGetProp(cur,BAD_CAST "service");
[490]242      if(tval!=NULL){
[9]243        addToMap(tmpMap,"service",tval);
[490]244        xmlFree(tval);
245      }
[1]246      tval=NULL;
247      tval = (char*) xmlGetProp(cur,BAD_CAST "language");
[490]248      if(tval!=NULL){
[9]249        addToMap(tmpMap,"language",tval);
[490]250        xmlFree(tval);
251      }
[280]252      const char* requests[3]={"GetCapabilities","DescribeProcess","Execute"};
[1]253      for(int j=0;j<3;j++){
[280]254        char tt[128];
[1]255        sprintf(tt,"/*[local-name()='%s']",requests[j]);
[9]256        xmlXPathObjectPtr reqptr=extractFromDoc(doc,tt);
257        if(reqptr!=NULL){
258          xmlNodeSet* req=reqptr->nodesetval;
[1]259#ifdef DEBUG
[9]260          fprintf(stderr,"%i",req->nodeNr);
[1]261#endif
[9]262          if(req!=NULL && req->nodeNr==1){
[490]263            if(t1->value!=NULL)
264              free(t1->value);
[453]265            t1->value=zStrdup(requests[j]);
[9]266            j=2;
267          }
268          xmlXPathFreeObject(reqptr);
[1]269        }
270      }
[9]271      if(strncasecmp(t1->value,"GetCapabilities",15)==0){
272        xmlXPathObjectPtr versptr=extractFromDoc(doc,"/*/*/*[local-name()='Version']");
273        xmlNodeSet* vers=versptr->nodesetval;
[1]274        xmlChar* content=xmlNodeListGetString(doc, vers->nodeTab[0]->xmlChildrenNode,1);
[9]275        addToMap(tmpMap,"version",(char*)content);
276        xmlXPathFreeObject(versptr);
[1]277        xmlFree(content);
278      }else{
279        tval=NULL;
280        tval = (char*) xmlGetProp(cur,BAD_CAST "version");
[490]281        if(tval!=NULL){
[9]282          addToMap(tmpMap,"version",tval);
[490]283          xmlFree(tval);
284        }
[1]285        tval = (char*) xmlGetProp(cur,BAD_CAST "language");
[490]286        if(tval!=NULL){
[9]287          addToMap(tmpMap,"language",tval);
[490]288          xmlFree(tval);
289        }
[9]290        xmlXPathObjectPtr idptr=extractFromDoc(doc,"/*/*[local-name()='Identifier']");
291        if(idptr!=NULL){
292          xmlNodeSet* id=idptr->nodesetval;
293          if(id!=NULL){
294            char* identifiers=NULL;
295            identifiers=(char*)calloc(cgiContentLength,sizeof(char));
296            identifiers[0]=0;
297            for(int k=0;k<id->nodeNr;k++){
298              xmlChar* content=xmlNodeListGetString(doc, id->nodeTab[k]->xmlChildrenNode,1);
299              if(strlen(identifiers)>0){
[453]300                char *tmp=zStrdup(identifiers);
[9]301                snprintf(identifiers,strlen(tmp)+xmlStrlen(content)+2,"%s,%s",tmp,content);
302                free(tmp);
303              }
304              else{
305                snprintf(identifiers,xmlStrlen(content)+1,"%s",content);
306              }
307              xmlFree(content);
308            }
309            xmlXPathFreeObject(idptr);
310            addToMap(tmpMap,"Identifier",identifiers);
311            free(identifiers);
[1]312          }
313        }
314      }
[9]315      xmlFreeDoc(doc);
316      xmlCleanupParser();
[331]317    }else{
318      freeMap(&tmpMap);
319      free(tmpMap);
320      tmpMap=createMap("not_valid","true");
[1]321    }
[329]322
323    char *token,*saveptr;
324    token=strtok_r(cgiQueryString,"&",&saveptr);
325    while(token!=NULL){
326      char *token1,*saveptr1;
327      char *name=NULL;
328      char *value=NULL;
329      token1=strtok_r(token,"=",&saveptr1);
330      while(token1!=NULL){
331        if(name==NULL)
[453]332          name=zStrdup(token1);
[329]333        else
[453]334          value=zStrdup(token1);
[329]335        token1=strtok_r(NULL,"=",&saveptr1);
336      }
[331]337      addToMap(tmpMap,name,value);
[329]338      free(name);
339      free(value);
[331]340      name=NULL;
341      value=NULL;
[329]342      token=strtok_r(NULL,"&",&saveptr);
343    }
344   
[1]345  }
346
[331]347  if(strncasecmp(cgiContentType,"multipart/form-data",19)==0){
[376]348    map* tmp=getMap(tmpMap,"dataInputs");
349    if(tmp!=NULL){
350      addToMap(tmpMap,"dataInputs",strstr(strQuery,"dataInputs=")+11);
[331]351    }
[376]352  }
[331]353
[381]354  if(strQuery!=NULL)
355    free(strQuery);
[9]356
[490]357  runRequest(&tmpMap);
358
[9]359  /**
360   * Required but can't be made after executing a process using POST requests.
361   */
[490]362  if(/*strncasecmp(cgiRequestMethod,"post",4)!=0 && count(tmpMap)!=1 && */tmpMap!=NULL){
[9]363    freeMap(&tmpMap);
364    free(tmpMap);
365  }
[1]366  return 0;
367
368}
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