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

Last change on this file since 453 was 453, checked in by djay, 10 years ago

Add the optional Ruby Language Support to the ZOO-Kernel with an API similar to the Python ZOO-API. Small rewrite of Python support. Fix issue #86 and #87. Add usid in [lenv] section, this value is used to generate an unique identifier based on time and the process identifier. This usid is now used to name the stored result or the mapfile generated. Remove *some* warning messages displayed at compilation time.

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc
File size: 9.8 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#ifdef WIN32
40#include "windows.h"
41#define strtok_r strtok_s
42#endif
43
44extern "C" {
45#include "cgic.h"
46#include <libxml/tree.h>
47#include <libxml/xmlmemory.h>
48#include <libxml/parser.h>
49#include <libxml/xpath.h>
50#include <libxml/xpathInternals.h>
51}
52
53#include "service_internal.h"
54
55xmlXPathObjectPtr extractFromDoc(xmlDocPtr,const char*);
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
67int cgiMain(){
68  /**
69   * We'll use cgiOut as the default output (stdout) to produce plain text
70   * response.
71   */
72  dup2(fileno(cgiOut),fileno(stdout));
73#ifdef DEBUG
74  fprintf(cgiOut,"Content-Type: text/plain; charset=utf-8\r\nStatus: 200 OK\r\n\r\n");
75  fprintf(cgiOut,"Welcome on ZOO verbose debuging mode \r\n\r\n");
76  fflush(cgiOut);
77  fprintf (stderr, "Addr:%s\n", cgiRemoteAddr); 
78  fprintf (stderr, "RequestMethod: (%s) %d %d\n", cgiRequestMethod,strncasecmp(cgiRequestMethod,"post",4),strncmp(cgiContentType,"text/xml",8)==0 || strncasecmp(cgiRequestMethod,"post",4)==0); 
79  fprintf (stderr, "Request: %s\n", cgiQueryString);
80  fprintf (stderr, "ContentType: %s\n", cgiContentType);
81  fprintf (stderr, "ContentLength: %d\n", cgiContentLength);
82  fflush(stderr);
83#endif
84
85 
86  char *strQuery=NULL;
87  if(cgiQueryString!=NULL)
88    strQuery=zStrdup(cgiQueryString);
89  map* tmpMap=NULL;
90
91  if(strncmp(cgiContentType,"text/xml",8)==0 || 
92     strncasecmp(cgiRequestMethod,"post",4)==0){
93    if(cgiContentLength==NULL){
94       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         cgiContentLength+=r;
100         if(res==NULL){
101           res=(char*)malloc(1*sizeof(char));
102           sprintf(res,"%s",buffer);
103         }
104         else{
105           res=(char*)realloc(res,(cgiContentLength+1)*sizeof(char));
106           char *tmp=zStrdup(res);
107           sprintf(res,"%s%s",tmp,buffer);
108           free(tmp);
109         }
110       }
111       if(res==NULL && (strQuery==NULL || strlen(strQuery)==0)){
112         return errorException(NULL,"ZOO-Kernel failed to process your request cause the request was emtpty.","InternalError");
113       }else{
114         if(strQuery==NULL || strlen(strQuery)==0)
115           tmpMap=createMap("request",res);
116       }
117    }else{
118      char *buffer=new char[cgiContentLength+1];
119      int r=0;
120      if(fread(buffer,sizeof(char),cgiContentLength,cgiIn)>=0){
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);
133          char* tmpValueFinal=(char*) malloc((strlen(*arrayStep)+strlen(ivalue)+1)*sizeof(char));
134          sprintf(tmpValueFinal,"%s=%s",*arrayStep,ivalue);
135          if(strlen(buffer)==0){
136            sprintf(buffer,"%s",tmpValueFinal);
137          }else{
138            char *tmp=zStrdup(buffer);
139            sprintf(buffer,"%s&%s",tmp,tmpValueFinal);
140            free(tmp);
141          }
142          free(tmpValueFinal);
143#ifdef DEBUG
144          fprintf(stderr,"(( \n %s \n %s \n ))",*arrayStep,ivalue);
145#endif
146          delete[]ivalue;
147          arrayStep++;
148        }
149        tmpMap=createMap("request",buffer);
150      }
151      delete[]buffer;
152    }
153  }
154  else{
155#ifdef DEBUG
156    dumpMap(tmpMap);
157#endif
158    char **array, **arrayStep;
159    if (cgiFormEntries(&array) != cgiFormSuccess) {
160      return 1;
161    }
162    arrayStep = array;
163    while (*arrayStep) {
164      char *value=new char[cgiContentLength];
165      cgiFormStringNoNewlines(*arrayStep, value, cgiContentLength);
166#ifdef DEBUG
167      fprintf(stderr,"(( \n %s \n %s \n ))",*arrayStep,value);
168#endif
169      if(tmpMap!=NULL)
170        addToMap(tmpMap,*arrayStep,value);
171      else
172        tmpMap=createMap(*arrayStep,value);
173      arrayStep++;
174      delete[]value;
175    }
176    cgiStringArrayFree(array);
177  }
178
179  /**
180   * In case that the POST method was used, then check if params came in XML
181   * format else try to use the attribute "request" which should be the only
182   * one.
183   */
184  if(strncasecmp(cgiRequestMethod,"post",4)==0 || 
185     (count(tmpMap)==1 && strncmp(tmpMap->value,"<",1)==0)){
186    /**
187     * First include the MetaPath and the ServiceProvider default parameters
188     * (which should be always available in GET params so in cgiQueryString)
189     */
190    char *str1;
191    str1=cgiQueryString;
192    /**
193     * Store the original XML request in xrequest map
194     */
195    map* t1=getMap(tmpMap,"request");
196    if(t1!=NULL && strncasecmp(t1->value,"<",1)==0){
197      addToMap(tmpMap,"xrequest",t1->value);
198      xmlInitParser();
199      xmlDocPtr doc = xmlParseMemory(t1->value,cgiContentLength);
200      {
201        xmlXPathObjectPtr reqptr=extractFromDoc(doc,"/*[local-name()='Envelope']/*[local-name()='Body']/*");
202        if(reqptr!=NULL){
203          xmlNodeSet* req=reqptr->nodesetval;
204          if(req!=NULL && req->nodeNr==1){
205            addToMap(tmpMap,"soap","true");
206            int k=0;
207            for(k;k < req->nodeNr;k++){
208              xmlNsPtr ns=xmlNewNs(req->nodeTab[k],BAD_CAST "http://www.w3.org/2001/XMLSchema-instance",BAD_CAST "xsi");
209              xmlDocSetRootElement(doc, req->nodeTab[k]);
210              xmlChar *xmlbuff;
211              int buffersize;
212              xmlDocDumpFormatMemoryEnc(doc, &xmlbuff, &buffersize, "utf-8", 1);
213              addToMap(tmpMap,"xrequest",(char*)xmlbuff);
214              char *tmp=(char*)xmlbuff;
215              xmlFree(xmlbuff);
216            }
217          }
218        }
219      }
220
221      xmlNodePtr cur = xmlDocGetRootElement(doc);
222      char *tval;
223      tval=NULL;
224      tval = (char*) xmlGetProp(cur,BAD_CAST "service");
225      if(tval!=NULL)
226        addToMap(tmpMap,"service",tval);
227      tval=NULL;
228      tval = (char*) xmlGetProp(cur,BAD_CAST "language");
229      if(tval!=NULL)
230        addToMap(tmpMap,"language",tval);
231      const char* requests[3]={"GetCapabilities","DescribeProcess","Execute"};
232      for(int j=0;j<3;j++){
233        char tt[128];
234        sprintf(tt,"/*[local-name()='%s']",requests[j]);
235        xmlXPathObjectPtr reqptr=extractFromDoc(doc,tt);
236        if(reqptr!=NULL){
237          xmlNodeSet* req=reqptr->nodesetval;
238#ifdef DEBUG
239          fprintf(stderr,"%i",req->nodeNr);
240#endif
241          if(req!=NULL && req->nodeNr==1){
242            t1->value=zStrdup(requests[j]);
243            j=2;
244          }
245          xmlXPathFreeObject(reqptr);
246        }
247      }
248      if(strncasecmp(t1->value,"GetCapabilities",15)==0){
249        xmlXPathObjectPtr versptr=extractFromDoc(doc,"/*/*/*[local-name()='Version']");
250        xmlNodeSet* vers=versptr->nodesetval;
251        xmlChar* content=xmlNodeListGetString(doc, vers->nodeTab[0]->xmlChildrenNode,1);
252        addToMap(tmpMap,"version",(char*)content);
253        xmlXPathFreeObject(versptr);
254        xmlFree(content);
255      }else{
256        tval=NULL;
257        tval = (char*) xmlGetProp(cur,BAD_CAST "version");
258        if(tval!=NULL)
259          addToMap(tmpMap,"version",tval);
260        tval = (char*) xmlGetProp(cur,BAD_CAST "language");
261        if(tval!=NULL)
262          addToMap(tmpMap,"language",tval);
263        xmlXPathObjectPtr idptr=extractFromDoc(doc,"/*/*[local-name()='Identifier']");
264        if(idptr!=NULL){
265          xmlNodeSet* id=idptr->nodesetval;
266          if(id!=NULL){
267            char* identifiers=NULL;
268            identifiers=(char*)calloc(cgiContentLength,sizeof(char));
269            identifiers[0]=0;
270            for(int k=0;k<id->nodeNr;k++){
271              xmlChar* content=xmlNodeListGetString(doc, id->nodeTab[k]->xmlChildrenNode,1);
272              if(strlen(identifiers)>0){
273                char *tmp=zStrdup(identifiers);
274                snprintf(identifiers,strlen(tmp)+xmlStrlen(content)+2,"%s,%s",tmp,content);
275                free(tmp);
276              }
277              else{
278                snprintf(identifiers,xmlStrlen(content)+1,"%s",content);
279              }
280              xmlFree(content);
281            }
282            xmlXPathFreeObject(idptr);
283            addToMap(tmpMap,"Identifier",identifiers);
284            free(identifiers);
285          }
286        }
287      }
288      xmlFreeDoc(doc);
289      xmlCleanupParser();
290    }else{
291      freeMap(&tmpMap);
292      free(tmpMap);
293      tmpMap=createMap("not_valid","true");
294    }
295
296    char *token,*saveptr;
297    token=strtok_r(cgiQueryString,"&",&saveptr);
298    while(token!=NULL){
299      char *token1,*saveptr1;
300      char *name=NULL;
301      char *value=NULL;
302      token1=strtok_r(token,"=",&saveptr1);
303      while(token1!=NULL){
304        if(name==NULL)
305          name=zStrdup(token1);
306        else
307          value=zStrdup(token1);
308        token1=strtok_r(NULL,"=",&saveptr1);
309      }
310      addToMap(tmpMap,name,value);
311      free(name);
312      free(value);
313      name=NULL;
314      value=NULL;
315      token=strtok_r(NULL,"&",&saveptr);
316    }
317   
318  }
319
320  if(strncasecmp(cgiContentType,"multipart/form-data",19)==0){
321    map* tmp=getMap(tmpMap,"dataInputs");
322    if(tmp!=NULL){
323      addToMap(tmpMap,"dataInputs",strstr(strQuery,"dataInputs=")+11);
324    }
325  }
326
327  if(strQuery!=NULL)
328    free(strQuery);
329  runRequest(tmpMap);
330
331  /**
332   * Required but can't be made after executing a process using POST requests.
333   */
334  if(strncasecmp(cgiRequestMethod,"post",4)!=0 && count(tmpMap)!=1 && tmpMap!=NULL){
335    freeMap(&tmpMap);
336    free(tmpMap);
337  }
338  return 0;
339
340}
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