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

Last change on this file since 784 was 745, checked in by djay, 8 years ago

Fix issue when XML request contains empty nodes for inputs

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