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

Last change on this file since 587 was 587, checked in by knut, 10 years ago

Implemented asynchronous HTTP POST Execute requests on Windows platform (via caching). Fixed bug that caused only the last output variable in a HTTP POST Execute request to be returned. Modified the addToCache function so that the path of the cached file can be retrieved. Changed the parsing of KVPs in zoo_loader.c so that keys with missing values (e.g. "metapath=") are assigned the empty string instead of NULL (avoids segmentation fault in some situations). Added conditional definition of ZEND_DEBUG in service_internal_php.c. Deallocation of memory in function createProcess. In zoo_loader.c, applied url_decode to CGI form string (WIN32 only, but should check if this should apply to other platforms as well).

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