source: trunk/zoo-kernel/zoo_loader.c @ 286

Last change on this file since 286 was 286, checked in by djay, 13 years ago

Fix behavior for empty post requests (cf. #57).

File size: 8.7 KB
RevLine 
[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
[216]28#ifdef WIN32
29#include "windows.h"
30#endif
[1]31/**
32 * Specific includes
33 */
34#include "fcgio.h"
35#include "fcgi_config.h"
36#include "fcgi_stdio.h"
37#include <sys/types.h>
38#include <unistd.h>
[9]39#include "service_internal.h"
40
[1]41extern "C" {
42#include "cgic.h"
43#include <libxml/tree.h>
44#include <libxml/xmlmemory.h>
45#include <libxml/parser.h>
46#include <libxml/xpath.h>
47#include <libxml/xpathInternals.h>
48}
49
[280]50#include "service_internal.h"
51
[114]52xmlXPathObjectPtr extractFromDoc(xmlDocPtr,const char*);
[9]53int runRequest(map*);
54
55using namespace std;
56
57#define TRUE 1
[1]58#define FALSE -1
59
60int cgiMain(){
61  /**
62   * We'll use cgiOut as the default output (stdout) to produce plain text
63   * response.
64   */
65  dup2(fileno(cgiOut),fileno(stdout));
66#ifdef DEBUG
[9]67  fprintf(cgiOut,"Content-Type: text/plain; charset=utf-8\r\nStatus: 200 OK\r\n\r\n");
68  fprintf(cgiOut,"Welcome on ZOO verbose debuging mode \r\n\r\n");
69  fflush(cgiOut);
[1]70#endif
71 
72#ifdef DEBUG
[9]73  fprintf (stderr, "Addr:%s\n", cgiRemoteAddr); 
[280]74  fprintf (stderr, "RequestMethod: (%s) %d %d\n", cgiRequestMethod,strncasecmp(cgiRequestMethod,"post",4),strncmp(cgiContentType,"text/xml",8)==0 || strncasecmp(cgiRequestMethod,"post",4)==0); 
[9]75  fprintf (stderr, "Request: %s\n", cgiQueryString);
[1]76#endif
77
[9]78  map* tmpMap=NULL;
[69]79
[99]80  if(strncmp(cgiContentType,"text/xml",8)==0 || 
81     strncasecmp(cgiRequestMethod,"post",4)==0){
[280]82    if(cgiContentLength==NULL){
83       cgiContentLength=0;
84       char *buffer=new char[2];
85       char *res=NULL;
86       int r=0;
87       while(r=fread(buffer,sizeof(char),1,cgiIn)){
88         cgiContentLength+=r;
89         if(res==NULL){
90           res=(char*)malloc(1*sizeof(char));
91           sprintf(res,"%s",buffer);
92         }
93         else{
94           res=(char*)realloc(res,(cgiContentLength+1)*sizeof(char));
95           char *tmp=strdup(res);
96           sprintf(res,"%s%s",tmp,buffer);
97           free(tmp);
98         }
99       }
[286]100       if(res==NULL){
101         return errorException(NULL,"ZOO-Kernel failed to process your request cause the request was emtpty.","InternalError");
102       }else
103         tmpMap=createMap("request",res);
[1]104    }else{
[280]105      char *buffer=new char[cgiContentLength+1];
106      if(fread(buffer,sizeof(char),cgiContentLength,cgiIn)){
107        buffer[cgiContentLength]=0;
108        tmpMap=createMap("request",buffer);
109        dumpMap(tmpMap);
110      }else{
111        buffer[0]=0;
112        char **array, **arrayStep;
113        if (cgiFormEntries(&array) != cgiFormSuccess) {
114          return 1;
115        }
116        arrayStep = array;
117        while (*arrayStep) {
118          char *ivalue=new char[cgiContentLength];
119          cgiFormStringNoNewlines(*arrayStep, ivalue, cgiContentLength);
120          char* tmpValueFinal=(char*) malloc((strlen(*arrayStep)+strlen(ivalue)+1)*sizeof(char));
121          sprintf(tmpValueFinal,"%s=%s",*arrayStep,ivalue);
122          if(strlen(buffer)==0){
123            sprintf(buffer,"%s",tmpValueFinal);
124          }else{
125            char *tmp=strdup(buffer);
126            sprintf(buffer,"%s&%s",tmp,tmpValueFinal);
127            free(tmp);
128          }
129         
130          sprintf(tmpValueFinal,"%s=%s",*arrayStep,ivalue);
131          free(tmpValueFinal);
[99]132#ifdef DEBUG
[280]133          fprintf(stderr,"(( \n %s \n %s \n ))",*arrayStep,ivalue);
[99]134#endif
[280]135          delete[]ivalue;
136          arrayStep++;
137        }
138        tmpMap=createMap("request",buffer);
[99]139      }
[280]140      delete[]buffer;
[1]141    }
142  }
143  else{
144    char **array, **arrayStep;
145    if (cgiFormEntries(&array) != cgiFormSuccess) {
146      return 1;
147    }
148    arrayStep = array;
149    while (*arrayStep) {
150      char *value=new char[cgiContentLength];
151      cgiFormStringNoNewlines(*arrayStep, value, cgiContentLength);
152#ifdef DEBUG
153      fprintf(stderr,"(( \n %s \n %s \n ))",*arrayStep,value);
154#endif
[9]155      if(tmpMap!=NULL)
156        addToMap(tmpMap,*arrayStep,value);
[1]157      else
[9]158        tmpMap=createMap(*arrayStep,value);
[1]159      arrayStep++;
[9]160      delete[]value;
[1]161    }
162    cgiStringArrayFree(array);
163  }
164
165  /**
166   * In case that the POST method was used, then check if params came in XML
[9]167   * format else try to use the attribute "request" which should be the only
168   * one.
[1]169   */
[10]170  if(strncasecmp(cgiRequestMethod,"post",4)==0 || 
171     (count(tmpMap)==1 && strncmp(tmpMap->value,"<",1)==0)){
[1]172    /**
173     * First include the MetaPath and the ServiceProvider default parameters
174     * (which should be always available in GET params so in cgiQueryString)
175     */
[19]176    char *str1;
[1]177    str1=cgiQueryString;
178    /**
179     * Store the original XML request in xrequest map
180     */
[9]181    map* t1=getMap(tmpMap,"request");
[1]182    if(t1!=NULL){
[9]183      addToMap(tmpMap,"xrequest",t1->value);
[1]184      xmlInitParser();
[9]185      xmlDocPtr doc = xmlParseMemory(t1->value,cgiContentLength);
[280]186
187
188      {
189        xmlXPathObjectPtr reqptr=extractFromDoc(doc,"/*[local-name()='Envelope']/*[local-name()='Body']/*");
190        if(reqptr!=NULL){
191          xmlNodeSet* req=reqptr->nodesetval;
192          if(req!=NULL && req->nodeNr==1){
193            addToMap(tmpMap,"soap","true");
194            int k=0;
195            for(k;k < req->nodeNr;k++){
196              xmlNsPtr ns=xmlNewNs(req->nodeTab[k],BAD_CAST "http://www.w3.org/2001/XMLSchema-instance",BAD_CAST "xsi");
197              xmlDocSetRootElement(doc, req->nodeTab[k]);
198              xmlChar *xmlbuff;
199              int buffersize;
200              xmlDocDumpFormatMemoryEnc(doc, &xmlbuff, &buffersize, "utf-8", 1);
201              addToMap(tmpMap,"xrequest",(char*)xmlbuff);
202              char *tmp=(char*)xmlbuff;
203              fprintf(stderr,"%s\n",tmp);
204              xmlFree(xmlbuff);
205            }
206          }
207        }
208      }
209
[1]210      xmlNodePtr cur = xmlDocGetRootElement(doc);
211      char *tval;
212      tval=NULL;
213      tval = (char*) xmlGetProp(cur,BAD_CAST "service");
214      if(tval!=NULL)
[9]215        addToMap(tmpMap,"service",tval);
[1]216      tval=NULL;
217      tval = (char*) xmlGetProp(cur,BAD_CAST "language");
218      if(tval!=NULL)
[9]219        addToMap(tmpMap,"language",tval);
[280]220      const char* requests[3]={"GetCapabilities","DescribeProcess","Execute"};
[1]221      for(int j=0;j<3;j++){
[280]222        char tt[128];
[1]223        sprintf(tt,"/*[local-name()='%s']",requests[j]);
[9]224        xmlXPathObjectPtr reqptr=extractFromDoc(doc,tt);
225        if(reqptr!=NULL){
226          xmlNodeSet* req=reqptr->nodesetval;
[1]227#ifdef DEBUG
[9]228          fprintf(stderr,"%i",req->nodeNr);
[1]229#endif
[9]230          if(req!=NULL && req->nodeNr==1){
[114]231            t1->value=strdup(requests[j]);
[9]232            j=2;
233          }
234          xmlXPathFreeObject(reqptr);
[1]235        }
[9]236        //xmlFree(req);
[1]237      }
[9]238      if(strncasecmp(t1->value,"GetCapabilities",15)==0){
239        xmlXPathObjectPtr versptr=extractFromDoc(doc,"/*/*/*[local-name()='Version']");
240        xmlNodeSet* vers=versptr->nodesetval;
[1]241        xmlChar* content=xmlNodeListGetString(doc, vers->nodeTab[0]->xmlChildrenNode,1);
[9]242        addToMap(tmpMap,"version",(char*)content);
243        xmlXPathFreeObject(versptr);
244        //xmlFree(vers);
[1]245        xmlFree(content);
246      }else{
247        tval=NULL;
248        tval = (char*) xmlGetProp(cur,BAD_CAST "version");
249        if(tval!=NULL)
[9]250          addToMap(tmpMap,"version",tval);
[1]251        xmlFree(tval);
252        tval = (char*) xmlGetProp(cur,BAD_CAST "language");
253        if(tval!=NULL)
[9]254          addToMap(tmpMap,"language",tval);
255        xmlXPathObjectPtr idptr=extractFromDoc(doc,"/*/*[local-name()='Identifier']");
256        if(idptr!=NULL){
257          xmlNodeSet* id=idptr->nodesetval;
258          if(id!=NULL){
259            char* identifiers=NULL;
260            identifiers=(char*)calloc(cgiContentLength,sizeof(char));
261            identifiers[0]=0;
262            for(int k=0;k<id->nodeNr;k++){
263              xmlChar* content=xmlNodeListGetString(doc, id->nodeTab[k]->xmlChildrenNode,1);
264              if(strlen(identifiers)>0){
265                char *tmp=strdup(identifiers);
266                snprintf(identifiers,strlen(tmp)+xmlStrlen(content)+2,"%s,%s",tmp,content);
267                free(tmp);
268              }
269              else{
270                snprintf(identifiers,xmlStrlen(content)+1,"%s",content);
271              }
272              xmlFree(content);
273            }
274            xmlXPathFreeObject(idptr);
275            addToMap(tmpMap,"Identifier",identifiers);
276            free(identifiers);
[1]277          }
278        }
[9]279        //xmlFree(id);
[1]280      }
281      xmlFree(tval);
[9]282      xmlFreeDoc(doc);
283      xmlCleanupParser();
[1]284    }
285  }
286
[9]287  runRequest(tmpMap);
288
289  /**
290   * Required but can't be made after executing a process using POST requests.
291   */
292  if(strncasecmp(cgiRequestMethod,"post",4)!=0 && count(tmpMap)!=1 && tmpMap!=NULL){
293    freeMap(&tmpMap);
294    free(tmpMap);
295  }
[1]296  return 0;
297
298}
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