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

Last change on this file since 510 was 510, checked in by djay, 9 years ago

Fix leaks in ZOO-Kernel.

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