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

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

Initial introduction of Value and Range in AllowedValues?, update zcfg documentation. Return valid Status code when returning ExceptionRepport?.

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc
File size: 10.3 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",NULL);
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#ifdef WIN32
180  map *tmpReq=getMap(tmpMap,"rfile");
181  if(tmpReq!=NULL){
182    FILE *lf=fopen(tmpReq->value,"r");
183    fseek(lf,0,SEEK_END);
184    long flen=ftell(lf);
185    fseek(lf,0,SEEK_SET);
186    char *buffer=(char*)malloc((flen+1)*sizeof(char));
187    fread(buffer,flen,1,lf);
188    fclose(lf);
189    addToMap(tmpMap,"request",buffer);
190    free(buffer);
191    cgiContentLength=flen+9;
192  }
193#endif
194  /**
195   * In case that the POST method was used, then check if params came in XML
196   * format else try to use the attribute "request" which should be the only
197   * one.
198   */
199  if(strncasecmp(cgiRequestMethod,"post",4)==0 || 
200     (count(tmpMap)==1 && strncmp(tmpMap->value,"<",1)==0) 
201#ifdef WIN32
202     ||tmpReq!=NULL
203#endif
204     ){
205    /**
206     * First include the MetaPath and the ServiceProvider default parameters
207     * (which should be always available in GET params so in cgiQueryString)
208     */
209    char *str1;
210    str1=cgiQueryString;
211    /**
212     * Store the original XML request in xrequest map
213     */
214    map* t1=getMap(tmpMap,"request");
215    if(t1!=NULL && strncasecmp(t1->value,"<",1)==0){
216      addToMap(tmpMap,"xrequest",t1->value);
217      xmlInitParser();
218      xmlDocPtr doc = xmlParseMemory(t1->value,cgiContentLength);
219      {
220        xmlXPathObjectPtr reqptr=extractFromDoc(doc,"/*[local-name()='Envelope']/*[local-name()='Body']/*");
221        if(reqptr!=NULL){
222          xmlNodeSet* req=reqptr->nodesetval;
223          if(req!=NULL && req->nodeNr==1){
224            addToMap(tmpMap,"soap","true");
225            int k=0;
226            for(k;k < req->nodeNr;k++){
227              xmlNsPtr ns=xmlNewNs(req->nodeTab[k],BAD_CAST "http://www.w3.org/2001/XMLSchema-instance",BAD_CAST "xsi");
228              xmlDocSetRootElement(doc, req->nodeTab[k]);
229              xmlChar *xmlbuff;
230              int buffersize;
231              xmlDocDumpFormatMemoryEnc(doc, &xmlbuff, &buffersize, "utf-8", 1);
232              addToMap(tmpMap,"xrequest",(char*)xmlbuff);
233              char *tmp=(char*)xmlbuff;
234              xmlFree(xmlbuff);
235            }
236          }
237        }
238      }
239
240      xmlNodePtr cur = xmlDocGetRootElement(doc);
241      char *tval;
242      tval=NULL;
243      tval = (char*) xmlGetProp(cur,BAD_CAST "service");
244      if(tval!=NULL)
245        addToMap(tmpMap,"service",tval);
246      tval=NULL;
247      tval = (char*) xmlGetProp(cur,BAD_CAST "language");
248      if(tval!=NULL)
249        addToMap(tmpMap,"language",tval);
250      const char* requests[3]={"GetCapabilities","DescribeProcess","Execute"};
251      for(int j=0;j<3;j++){
252        char tt[128];
253        sprintf(tt,"/*[local-name()='%s']",requests[j]);
254        xmlXPathObjectPtr reqptr=extractFromDoc(doc,tt);
255        if(reqptr!=NULL){
256          xmlNodeSet* req=reqptr->nodesetval;
257#ifdef DEBUG
258          fprintf(stderr,"%i",req->nodeNr);
259#endif
260          if(req!=NULL && req->nodeNr==1){
261            t1->value=zStrdup(requests[j]);
262            j=2;
263          }
264          xmlXPathFreeObject(reqptr);
265        }
266      }
267      if(strncasecmp(t1->value,"GetCapabilities",15)==0){
268        xmlXPathObjectPtr versptr=extractFromDoc(doc,"/*/*/*[local-name()='Version']");
269        xmlNodeSet* vers=versptr->nodesetval;
270        xmlChar* content=xmlNodeListGetString(doc, vers->nodeTab[0]->xmlChildrenNode,1);
271        addToMap(tmpMap,"version",(char*)content);
272        xmlXPathFreeObject(versptr);
273        xmlFree(content);
274      }else{
275        tval=NULL;
276        tval = (char*) xmlGetProp(cur,BAD_CAST "version");
277        if(tval!=NULL)
278          addToMap(tmpMap,"version",tval);
279        tval = (char*) xmlGetProp(cur,BAD_CAST "language");
280        if(tval!=NULL)
281          addToMap(tmpMap,"language",tval);
282        xmlXPathObjectPtr idptr=extractFromDoc(doc,"/*/*[local-name()='Identifier']");
283        if(idptr!=NULL){
284          xmlNodeSet* id=idptr->nodesetval;
285          if(id!=NULL){
286            char* identifiers=NULL;
287            identifiers=(char*)calloc(cgiContentLength,sizeof(char));
288            identifiers[0]=0;
289            for(int k=0;k<id->nodeNr;k++){
290              xmlChar* content=xmlNodeListGetString(doc, id->nodeTab[k]->xmlChildrenNode,1);
291              if(strlen(identifiers)>0){
292                char *tmp=zStrdup(identifiers);
293                snprintf(identifiers,strlen(tmp)+xmlStrlen(content)+2,"%s,%s",tmp,content);
294                free(tmp);
295              }
296              else{
297                snprintf(identifiers,xmlStrlen(content)+1,"%s",content);
298              }
299              xmlFree(content);
300            }
301            xmlXPathFreeObject(idptr);
302            addToMap(tmpMap,"Identifier",identifiers);
303            free(identifiers);
304          }
305        }
306      }
307      xmlFreeDoc(doc);
308      xmlCleanupParser();
309    }else{
310      freeMap(&tmpMap);
311      free(tmpMap);
312      tmpMap=createMap("not_valid","true");
313    }
314
315    char *token,*saveptr;
316    token=strtok_r(cgiQueryString,"&",&saveptr);
317    while(token!=NULL){
318      char *token1,*saveptr1;
319      char *name=NULL;
320      char *value=NULL;
321      token1=strtok_r(token,"=",&saveptr1);
322      while(token1!=NULL){
323        if(name==NULL)
324          name=zStrdup(token1);
325        else
326          value=zStrdup(token1);
327        token1=strtok_r(NULL,"=",&saveptr1);
328      }
329      addToMap(tmpMap,name,value);
330      free(name);
331      free(value);
332      name=NULL;
333      value=NULL;
334      token=strtok_r(NULL,"&",&saveptr);
335    }
336   
337  }
338
339  if(strncasecmp(cgiContentType,"multipart/form-data",19)==0){
340    map* tmp=getMap(tmpMap,"dataInputs");
341    if(tmp!=NULL){
342      addToMap(tmpMap,"dataInputs",strstr(strQuery,"dataInputs=")+11);
343    }
344  }
345
346  if(strQuery!=NULL)
347    free(strQuery);
348  runRequest(tmpMap);
349
350  /**
351   * Required but can't be made after executing a process using POST requests.
352   */
353  if(strncasecmp(cgiRequestMethod,"post",4)!=0 && count(tmpMap)!=1 && tmpMap!=NULL){
354    freeMap(&tmpMap);
355    free(tmpMap);
356  }
357  return 0;
358
359}
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