source: trunk/zoo-kernel/zoo_loader.c @ 69

Last change on this file since 69 was 69, checked in by djay, 13 years ago

Fix XML request parser for embedded XML complex data. Handle Execute requests coming from the QGIS WPS Client plugin. Fix for Python support.

File size: 7.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
38extern "C" {
39#include "cgic.h"
40#include <libxml/tree.h>
41#include <libxml/xmlmemory.h>
42#include <libxml/parser.h>
43#include <libxml/xpath.h>
44#include <libxml/xpathInternals.h>
45}
46
47xmlXPathObjectPtr extractFromDoc(xmlDocPtr,char*);
48int runRequest(map*);
49
50using namespace std;
51
52/* ************************************************************************* */
53
54int errorException(maps *m, const char *message, const char *errorcode) 
55{
56  map* errormap = createMap("text", message);
57  addToMap(errormap,"code", errorcode);
58  printExceptionReportResponse(m,errormap);
59  freeMap(&errormap);
60  free(errormap);
61  return -1;
62}
63
64/* ************************************************************************* */
65
66#ifndef STRTOK_R
67char *
68strtok_r (char *s1, const char *s2, char **lasts)
69{
70  char *ret;
71
72  if (s1 == NULL)
73    s1 = *lasts;
74  while (*s1 && strchr(s2, *s1))
75    ++s1;
76  if (*s1 == '\0')
77    return NULL;
78  ret = s1;
79  while (*s1 && !strchr(s2, *s1))
80    ++s1;
81  if (*s1)
82    *s1++ = '\0';
83  *lasts = s1;
84  return ret;
85}
86
87#endif
88
89#define TRUE 1
90#define FALSE -1
91
92int cgiMain(){
93  /**
94   * We'll use cgiOut as the default output (stdout) to produce plain text
95   * response.
96   */
97  dup2(fileno(cgiOut),fileno(stdout));
98#ifdef DEBUG
99  fprintf(cgiOut,"Content-Type: text/plain; charset=utf-8\r\nStatus: 200 OK\r\n\r\n");
100  fprintf(cgiOut,"Welcome on ZOO verbose debuging mode \r\n\r\n");
101  fflush(cgiOut);
102#endif
103 
104#ifdef DEBUG
105  fprintf (stderr, "Addr:%s\n", cgiRemoteAddr); 
106  fprintf (stderr, "RequestMethod:%s\n", cgiRequestMethod); 
107  fprintf (stderr, "Request: %s\n", cgiQueryString);
108#endif
109
110  map* tmpMap=NULL;
111
112  if(strncmp(cgiContentType,"text/xml",8)==0){
113    char *buffer=new char[cgiContentLength+1];
114    if(fread(buffer,1,cgiContentLength,cgiIn)){
115      buffer[cgiContentLength]=0;
116      tmpMap=createMap("request",buffer);
117    }else{
118      /* Here we have to return an error message ... */
119      fprintf(stderr, "Unable to read cgi content in zoo_loader.c line %i\n", __LINE__);
120      return 1; 
121    }
122    delete[]buffer;
123  }
124  else{
125    char **array, **arrayStep;
126    if (cgiFormEntries(&array) != cgiFormSuccess) {
127      return 1;
128    }
129    arrayStep = array;
130    while (*arrayStep) {
131      char *value=new char[cgiContentLength];
132      cgiFormStringNoNewlines(*arrayStep, value, cgiContentLength);
133#ifdef DEBUG
134      fprintf(stderr,"(( \n %s \n %s \n ))",*arrayStep,value);
135#endif
136      if(tmpMap!=NULL)
137        addToMap(tmpMap,*arrayStep,value);
138      else
139        tmpMap=createMap(*arrayStep,value);
140      arrayStep++;
141      delete[]value;
142    }
143    cgiStringArrayFree(array);
144  }
145
146  if(strncasecmp(cgiRequestMethod,"post",4)==0 && getMap(tmpMap,"request")==NULL){
147    char *tmpKey=strdup(tmpMap->name);
148    char *tmpValue=strdup(tmpMap->value);
149    freeMap(&tmpMap);
150    free(tmpMap);
151    char* tmpValueFinal=(char*) malloc((strlen(tmpKey)+strlen(tmpValue)+2)*sizeof(char));
152    sprintf(tmpValueFinal,"%s=%s",tmpKey,tmpValue);
153    tmpMap=createMap("request",tmpValueFinal);
154    free(tmpValueFinal);
155  }
156  /**
157   * In case that the POST method was used, then check if params came in XML
158   * format else try to use the attribute "request" which should be the only
159   * one.
160   */
161  if(strncasecmp(cgiRequestMethod,"post",4)==0 || 
162     (count(tmpMap)==1 && strncmp(tmpMap->value,"<",1)==0)){
163    /**
164     * First include the MetaPath and the ServiceProvider default parameters
165     * (which should be always available in GET params so in cgiQueryString)
166     */
167    char *str1;
168    str1=cgiQueryString;
169    /**
170     * Store the original XML request in xrequest map
171     */
172    map* t1=getMap(tmpMap,"request");
173    if(t1!=NULL){
174      addToMap(tmpMap,"xrequest",t1->value);
175      xmlInitParser();
176      xmlDocPtr doc = xmlParseMemory(t1->value,cgiContentLength);
177      xmlNodePtr cur = xmlDocGetRootElement(doc);
178      char *tval;
179      tval=NULL;
180      tval = (char*) xmlGetProp(cur,BAD_CAST "service");
181      if(tval!=NULL)
182        addToMap(tmpMap,"service",tval);
183      tval=NULL;
184      tval = (char*) xmlGetProp(cur,BAD_CAST "language");
185      if(tval!=NULL)
186        addToMap(tmpMap,"language",tval);
187     
188      char* requests[3];
189      requests[0]="GetCapabilities";
190      requests[1]="DescribeProcess";
191      requests[2]="Execute";
192      for(int j=0;j<3;j++){
193        char tt[35];
194        sprintf(tt,"/*[local-name()='%s']",requests[j]);
195        xmlXPathObjectPtr reqptr=extractFromDoc(doc,tt);
196        if(reqptr!=NULL){
197          xmlNodeSet* req=reqptr->nodesetval;
198#ifdef DEBUG
199          fprintf(stderr,"%i",req->nodeNr);
200#endif
201          if(req!=NULL && req->nodeNr==1){
202            t1->value=requests[j];
203            j=2;
204          }
205          xmlXPathFreeObject(reqptr);
206        }
207        //xmlFree(req);
208      }
209      if(strncasecmp(t1->value,"GetCapabilities",15)==0){
210        xmlXPathObjectPtr versptr=extractFromDoc(doc,"/*/*/*[local-name()='Version']");
211        xmlNodeSet* vers=versptr->nodesetval;
212        xmlChar* content=xmlNodeListGetString(doc, vers->nodeTab[0]->xmlChildrenNode,1);
213        addToMap(tmpMap,"version",(char*)content);
214        xmlXPathFreeObject(versptr);
215        //xmlFree(vers);
216        xmlFree(content);
217      }else{
218        tval=NULL;
219        tval = (char*) xmlGetProp(cur,BAD_CAST "version");
220        if(tval!=NULL)
221          addToMap(tmpMap,"version",tval);
222        xmlFree(tval);
223        tval = (char*) xmlGetProp(cur,BAD_CAST "language");
224        if(tval!=NULL)
225          addToMap(tmpMap,"language",tval);
226        xmlXPathObjectPtr idptr=extractFromDoc(doc,"/*/*[local-name()='Identifier']");
227        if(idptr!=NULL){
228          xmlNodeSet* id=idptr->nodesetval;
229          if(id!=NULL){
230            char* identifiers=NULL;
231            identifiers=(char*)calloc(cgiContentLength,sizeof(char));
232            identifiers[0]=0;
233            for(int k=0;k<id->nodeNr;k++){
234              xmlChar* content=xmlNodeListGetString(doc, id->nodeTab[k]->xmlChildrenNode,1);
235              if(strlen(identifiers)>0){
236                char *tmp=strdup(identifiers);
237                snprintf(identifiers,strlen(tmp)+xmlStrlen(content)+2,"%s,%s",tmp,content);
238                free(tmp);
239              }
240              else{
241                snprintf(identifiers,xmlStrlen(content)+1,"%s",content);
242              }
243              xmlFree(content);
244            }
245            xmlXPathFreeObject(idptr);
246            addToMap(tmpMap,"Identifier",identifiers);
247            free(identifiers);
248          }
249        }
250        //xmlFree(id);
251      }
252      xmlFree(tval);
253      xmlFreeDoc(doc);
254      xmlCleanupParser();
255    }
256  }
257
258  runRequest(tmpMap);
259
260  /**
261   * Required but can't be made after executing a process using POST requests.
262   */
263  if(strncasecmp(cgiRequestMethod,"post",4)!=0 && count(tmpMap)!=1 && tmpMap!=NULL){
264    freeMap(&tmpMap);
265    free(tmpMap);
266  }
267  return 0;
268
269}
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