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

Last change on this file since 830 was 790, checked in by djay, 8 years ago

Add support for nested inputs and outputs.

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc
File size: 11.7 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#include "fcgio.h"
32#include "fcgi_config.h"
33#include "fcgi_stdio.h"
34#include <sys/types.h>
35#include <unistd.h>
36#include "service_internal.h"
37#include "response_print.h"
38
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
48#ifdef WIN32
49#include "windows.h"
50#define strtok_r strtok_s
51#endif
52
53#include "service_internal.h"
54#include "request_parser.h"
55
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
67/**
68 * Main entry point for cgic.
69 * @return 0 on sucess.
70 */
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
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); 
82  fprintf (stderr, "RequestMethod: (%s) %d %d\n", cgiRequestMethod,strncasecmp(cgiRequestMethod,"post",4),strncmp(cgiContentType,"text/xml",8)==0 || strncasecmp(cgiRequestMethod,"post",4)==0); 
83  fprintf (stderr, "Request: %s\n", cgiQueryString);
84  fprintf (stderr, "ContentType: %s\n", cgiContentType);
85  fprintf (stderr, "ContentLength: %d\n", cgiContentLength);
86  fflush(stderr);
87#endif
88 
89  char *strQuery=NULL;
90  if(cgiQueryString!=NULL)
91    strQuery=zStrdup(cgiQueryString);
92  map* tmpMap=NULL;
93
94  if(strncmp(cgiContentType,"text/xml",8)==0 || 
95     strncasecmp(cgiRequestMethod,"post",4)==0){
96    if(cgiContentLength==0){
97
98       char *buffer=new char[2];
99       char *res=NULL;
100       int r=0;
101       while((r=fread(buffer,sizeof(char),1,cgiIn))){
102         buffer[1]=0;
103         if(res==NULL){
104           res=(char*)malloc(2*sizeof(char));
105           sprintf(res,"%s",buffer);
106         }
107         else{
108           res=(char*)realloc(res,(cgiContentLength+2)*sizeof(char));
109           memcpy(res + cgiContentLength, buffer, sizeof(char));
110           res[cgiContentLength+1]=0;
111         }
112         cgiContentLength+=r;
113       }
114       delete[] buffer;
115       if(res!=NULL && (strQuery==NULL || strlen(strQuery)==0))
116         tmpMap=createMap("request",res);
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)+2)*sizeof(char));       
135          sprintf(tmpValueFinal,"%s=%s",*arrayStep,ivalue);
136
137          if(strlen(buffer)==0){               
138            sprintf(buffer,"%s",tmpValueFinal);
139          }else{               
140            char *tmp=zStrdup(buffer);
141            sprintf(buffer,"%s&%s",tmp,tmpValueFinal);
142            free(tmp);
143          }       
144          free(tmpValueFinal);
145#ifdef DEBUG
146          fprintf(stderr,"(( \n %s \n %s \n ))",*arrayStep,ivalue);
147#endif
148          delete[]ivalue;
149          arrayStep++;
150        }       
151        if(tmpMap!=NULL)
152          addToMap(tmpMap,"request",buffer);
153        else
154          tmpMap=createMap("request",buffer);
155      }
156      delete[]buffer;
157    }   
158  }
159  else{
160#ifdef DEBUG
161    dumpMap(tmpMap);
162#endif
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
174      if(tmpMap!=NULL)
175        addToMap(tmpMap,*arrayStep,value);
176      else
177        tmpMap=createMap(*arrayStep,value);
178      arrayStep++;
179      delete[]value;
180    }
181    cgiStringArrayFree(array);
182  }
183
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    char *pchr=strrchr(buffer,'>');
194    cgiContentLength=strlen(buffer)-strlen(pchr)+1;
195    buffer[cgiContentLength]=0;
196    fclose(lf);
197    addToMap(tmpMap,"request",buffer);
198    free(buffer);
199  }
200#endif
201  /**
202   * In case that the POST method was used, then check if params came in XML
203   * format else try to use the attribute "request" which should be the only
204   * one.
205   */
206  if(strncasecmp(cgiRequestMethod,"post",4)==0 || 
207     (count(tmpMap)==1 && strncmp(tmpMap->value,"<",1)==0) 
208#ifdef WIN32
209     ||tmpReq!=NULL
210#endif
211     ){
212    /**
213     * Store the original XML request in xrequest map
214     */
215    map* t1=getMap(tmpMap,"request");
216    if(t1!=NULL && strncasecmp(t1->value,"<",1)==0) {
217      addToMap(tmpMap,"xrequest",t1->value);
218      xmlInitParser();
219      xmlDocPtr doc = xmlReadMemory(t1->value, cgiContentLength, "input_request.xml", NULL, XML_PARSE_RECOVER);
220      {
221        xmlXPathObjectPtr reqptr=extractFromDoc(doc,"/*[local-name()='Envelope']/*[local-name()='Body']/*");
222        if(reqptr!=NULL){
223          xmlNodeSet* req=reqptr->nodesetval;
224          if(req!=NULL && req->nodeNr==1){
225            addToMap(tmpMap,"soap","true");
226            for(int k=0;k < req->nodeNr;k++){
227              xmlDocSetRootElement(doc, req->nodeTab[k]);
228              xmlChar *xmlbuff;
229              int buffersize;
230              xmlDocDumpFormatMemoryEnc(doc, &xmlbuff, &buffersize, "utf-8", 1);
231              addToMap(tmpMap,"xrequest",(char*)xmlbuff);
232              xmlFree(xmlbuff);
233            }
234          }
235          xmlXPathFreeObject(reqptr);
236        }
237      }
238
239      xmlNodePtr cur = xmlDocGetRootElement(doc);
240      char *tval;
241      tval=NULL;
242      tval = (char*) xmlGetProp(cur,BAD_CAST "service");
243      if(tval!=NULL){
244        addToMap(tmpMap,"service",tval);
245        xmlFree(tval);
246      }
247      tval=NULL;
248      tval = (char*) xmlGetProp(cur,BAD_CAST "language");
249      if(tval!=NULL){
250        addToMap(tmpMap,"language",tval);
251        xmlFree(tval);
252      }
253      const char* requests[6]={"GetCapabilities","DescribeProcess","Execute","GetStatus","GetResult","Dismiss"};
254      for(int j=0;j<6;j++){
255        char tt[128];
256        sprintf(tt,"/*[local-name()='%s']",requests[j]);
257        xmlXPathObjectPtr reqptr=extractFromDoc(doc,tt);
258        if(reqptr!=NULL){
259          xmlNodeSet* req=reqptr->nodesetval;
260#ifdef DEBUG
261          fprintf(stderr,"%i",req->nodeNr);
262#endif
263          if(req!=NULL && req->nodeNr==1){
264            if(t1->value!=NULL)
265              free(t1->value);
266            t1->value=zStrdup(requests[j]);
267            j=5;
268          }
269          xmlXPathFreeObject(reqptr);
270        }
271      }
272      if(strncasecmp(t1->value,"GetCapabilities",15)==0){
273        xmlXPathObjectPtr versptr=extractFromDoc(doc,"/*/*/*[local-name()='Version']");
274        xmlNodeSet* vers=versptr->nodesetval;
275        if(vers!=NULL && vers->nodeTab!=NULL && vers->nodeTab[0]!=NULL){
276          xmlChar* content=xmlNodeListGetString(doc, vers->nodeTab[0]->xmlChildrenNode,1);
277          addToMap(tmpMap,"version",(char*)content);
278          xmlFree(content);
279        }
280        if(cur->ns){
281          addToMap(tmpMap,"wps_schemas",(char*)cur->ns->href);
282          int j=0;
283          for(j=0;j<2;j++)
284            if(strncasecmp(schemas[j][2],(char*)cur->ns->href,strlen(schemas[j][2]))==0){
285              char vers[6];
286              sprintf(vers,"%d.0.0",j+1);
287              addToMap(tmpMap,"version",(char*)vers);
288            }
289        }
290        xmlXPathFreeObject(versptr);
291      }else{
292        tval=NULL;
293        tval = (char*) xmlGetProp(cur,BAD_CAST "version");
294        if(tval!=NULL){
295          addToMap(tmpMap,"version",tval);
296          xmlFree(tval);
297        }
298        tval = (char*) xmlGetProp(cur,BAD_CAST "language");
299        if(tval!=NULL){
300          addToMap(tmpMap,"language",tval);
301          xmlFree(tval);
302        }
303        xmlXPathObjectPtr idptr=extractFromDoc(doc,"/*/*[local-name()='Identifier']");
304        if(idptr!=NULL){
305          xmlNodeSet* id=idptr->nodesetval;
306          if(id!=NULL){
307            char* identifiers=NULL;
308            identifiers=(char*)calloc(cgiContentLength,sizeof(char));
309            identifiers[0]=0;
310            for(int k=0;k<id->nodeNr;k++){
311              xmlChar* content=xmlNodeListGetString(doc, id->nodeTab[k]->xmlChildrenNode,1);
312              if(strlen(identifiers)>0){
313                char *tmp=zStrdup(identifiers);
314                snprintf(identifiers,strlen(tmp)+xmlStrlen(content)+2,"%s,%s",tmp,content);
315                free(tmp);
316              }
317              else{
318                snprintf(identifiers,xmlStrlen(content)+1,"%s",content);
319              }
320              xmlFree(content);
321            }
322            xmlXPathFreeObject(idptr);
323            if(identifiers[0]!=0)
324              addToMap(tmpMap,"Identifier",identifiers);
325            free(identifiers);
326          }
327        }
328        if(getMap(tmpMap,"Identifier")==NULL){
329          idptr=extractFromDoc(doc,"/*/*[local-name()='JobID']");
330          if(idptr!=NULL){
331            xmlNodeSet* id=idptr->nodesetval;
332            if(id!=NULL){
333              char* identifiers=NULL;
334              identifiers=(char*)calloc(cgiContentLength,sizeof(char));
335              identifiers[0]=0;
336              for(int k=0;k<id->nodeNr;k++){
337                  xmlChar* content=xmlNodeListGetString(doc, id->nodeTab[k]->xmlChildrenNode,1);
338                  if(strlen(identifiers)>0){
339                    char *tmp=zStrdup(identifiers);
340                    snprintf(identifiers,strlen(tmp)+xmlStrlen(content)+2,"%s,%s",tmp,content);
341                    free(tmp);
342                  }
343                  else{
344                    snprintf(identifiers,xmlStrlen(content)+1,"%s",content);
345                  }
346                  xmlFree(content);
347              }
348              xmlXPathFreeObject(idptr);
349              if(identifiers[0]!=0)
350                addToMap(tmpMap,"JobID",identifiers);
351              free(identifiers);
352            }
353          }
354        }
355      }
356      xmlFreeDoc(doc);
357      xmlCleanupParser();
358    }else{
359      freeMap(&tmpMap);
360      free(tmpMap);
361      tmpMap=createMap("not_valid","true");
362    }
363
364    char *token,*saveptr;
365    token=strtok_r(cgiQueryString,"&",&saveptr);
366    while(token!=NULL){
367      char *token1,*saveptr1;
368      char *name=NULL;
369      char *value=NULL;
370      token1=strtok_r(token,"=",&saveptr1);
371      while(token1!=NULL){
372        if(name==NULL)
373          name=zStrdup(token1);
374        else
375          value=zStrdup(token1);
376        token1=strtok_r(NULL,"=",&saveptr1);
377      }   
378      //addToMap(tmpMap,name,value);
379      /* knut: strtok(_r) ignores delimiter bytes at start and end of string;
380       * it will return non-empty string or NULL, e.g. "metapath=" yields value=NULL.
381       * This modification sets value="" instead of NULL.
382       */
383      addToMap(tmpMap,name, value != NULL ? value : "");
384      free(name);
385      free(value);
386      name=NULL;
387      value=NULL;
388      token=strtok_r(NULL,"&",&saveptr);
389    }
390  }
391
392  if(strncasecmp(cgiContentType,"multipart/form-data",19)==0){
393    map* tmp=getMap(tmpMap,"dataInputs");
394    if(tmp!=NULL){
395      if(strcasestr(strQuery,"dataInputs=")!=NULL)
396        addToMap(tmpMap,"dataInputs",strcasestr(strQuery,"dataInputs=")+11);
397      else
398        addToMap(tmpMap,"dataInputs","None");
399    }
400  }
401
402  if(strQuery!=NULL)
403    free(strQuery);
404
405  runRequest(&tmpMap);
406
407  if(tmpMap!=NULL){
408    freeMap(&tmpMap);
409    free(tmpMap);
410  }
411  return 0;
412
413}
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