source: branches/prototype-v0/zoo-project/zoo-kernel/zoo_loader.c @ 896

Last change on this file since 896 was 896, checked in by knut, 5 years ago

Added some recent changes from trunk (r889), including some new utility functions and exception handling and new (conditional) definition of type bool. Added some new logic concerning Python and Mono environment and search paths. Fixed problem with Mono updateStatus function. Changed response_print.h to #include locale.h unconditionally and xlocale.h conditionally; xlocale.h is non-standard and can probably be dropped.

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

Search

Context Navigation

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