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

Last change on this file since 967 was 962, checked in by djay, 4 years ago

Update OGC API - Processes documentation and implementation, providing a browsable User Interface to Processes.

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