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

Last change on this file since 605 was 605, checked in by knut, 9 years ago

Altered the path of stored response files from [tmpPath]/[serviceProvider]_[cpid].xml to [tmpPath]/[serviceName]_[cpid].xml. Added support for a new parameter, libPath, in the [main] block of main.cfg. The libPath parameter is interpreted as the absolute path of the directory containing library files. If the libPath parameter is set, it will override the metapath parameter such that library files are loaded from [libPath]/[serviceProvider] instead of [CWD]/[metapath]/[serviceProvider]. Added the option to disable the metapath parameter (for security reasons) at compile time: If the Zoo kernel is compiled with the preprocessor directive IGNORE_METAPATH, the metapath will be set to the empty string. Note however, that the libPath and IGNORE_METAPATH options so far only work for C and PHP; the functions for loading libraries written in other languages should be modified correspondingly before the documentation is updated. See also ticket no. 112 (http://www.zoo-project.org/trac/ticket/112). Fixed some spelling errors and modified the language in some of the messages returned by the Zoo kernel.

  • 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  char *strQuery=NULL;
88  if(cgiQueryString!=NULL)
89    strQuery=zStrdup(cgiQueryString);
90  map* tmpMap=NULL;
91
92  if(strncmp(cgiContentType,"text/xml",8)==0 || 
93     strncasecmp(cgiRequestMethod,"post",4)==0){
94    if(cgiContentLength==0){
95       char *buffer=new char[2];
96       char *res=NULL;
97       int r=0;
98       while((r=fread(buffer,sizeof(char),1,cgiIn))){
99         buffer[1]=0;
100         if(res==NULL){
101           res=(char*)malloc(2*sizeof(char));
102           sprintf(res,"%s",buffer);
103         }
104         else{
105           res=(char*)realloc(res,(cgiContentLength+2)*sizeof(char));
106           memcpy(res + cgiContentLength, buffer, sizeof(char));
107           res[cgiContentLength+1]=0;
108         }
109         cgiContentLength+=r;
110       }
111       delete[] buffer;
112       if(res==NULL && (strQuery==NULL || strlen(strQuery)==0)){
113         return errorException(NULL,"ZOO-Kernel failed to process your request because the request was empty.","InternalError",NULL);
114       }else{
115         if(strQuery==NULL || strlen(strQuery)==0)
116           tmpMap=createMap("request",res);
117       }
118       if(res!=NULL)
119         free(res);
120    }else{
121      char *buffer=new char[cgiContentLength+1];
122      if(fread(buffer,sizeof(char),cgiContentLength,cgiIn)>0){
123        buffer[cgiContentLength]=0;
124        tmpMap=createMap("request",buffer);
125      }else{
126        buffer[0]=0;
127        char **array, **arrayStep;
128        if (cgiFormEntries(&array) != cgiFormSuccess) {
129          return 1;
130        }
131        arrayStep = array;
132        while (*arrayStep) {
133          char *ivalue=new char[cgiContentLength];
134          cgiFormStringNoNewlines(*arrayStep, ivalue, cgiContentLength);
135          char* tmpValueFinal=(char*) malloc((strlen(*arrayStep)+strlen(ivalue)+2)*sizeof(char));       
136          sprintf(tmpValueFinal,"%s=%s",*arrayStep,ivalue);
137
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