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

Last change on this file since 959 was 949, checked in by djay, 5 years ago

Prototype implementation of the OGC API - Processing and other simplifications

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