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

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

Do not call errorException when reading the request content.

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