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

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

Major update. Creation of a basic parsing api. Call validateRequest after fork if any.

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