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

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

Small fixes.

  • 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#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#include "response_print.h"
40
41
42#ifdef WIN32
43#include "windows.h"
44#define strtok_r strtok_s
45#endif
46
47extern "C" {
48#include "cgic.h"
49#include <libxml/tree.h>
50#include <libxml/xmlmemory.h>
51#include <libxml/parser.h>
52#include <libxml/xpath.h>
53#include <libxml/xpathInternals.h>
54}
55
56#include "service_internal.h"
57#include "request_parser.h"
58
59int runRequest(map**);
60
61using namespace std;
62
63#ifndef TRUE
64#define TRUE 1
65#endif
66#ifndef FALSE
67#define FALSE -1
68#endif
69
70/**
71 * Main entry point for cgic.
72 * @return 0 on sucess.
73 */
74int cgiMain(){
75  /**
76   * We'll use cgiOut as the default output (stdout) to produce plain text
77   * response.
78   */
79  dup2(fileno(cgiOut),fileno(stdout));
80#ifdef DEBUG
81  fprintf(cgiOut,"Content-Type: text/plain; charset=utf-8\r\nStatus: 200 OK\r\n\r\n");
82  fprintf(cgiOut,"Welcome on ZOO verbose debuging mode \r\n\r\n");
83  fflush(cgiOut);
84  fprintf (stderr, "Addr:%s\n", cgiRemoteAddr); 
85  fprintf (stderr, "RequestMethod: (%s) %d %d\n", cgiRequestMethod,strncasecmp(cgiRequestMethod,"post",4),strncmp(cgiContentType,"text/xml",8)==0 || strncasecmp(cgiRequestMethod,"post",4)==0); 
86  fprintf (stderr, "Request: %s\n", cgiQueryString);
87  fprintf (stderr, "ContentType: %s\n", cgiContentType);
88  fprintf (stderr, "ContentLength: %d\n", cgiContentLength);
89  fflush(stderr);
90#endif
91 
92  char *strQuery=NULL;
93  if(cgiQueryString!=NULL)
94    strQuery=zStrdup(cgiQueryString);
95  map* tmpMap=NULL;
96
97  if(strncmp(cgiContentType,"text/xml",8)==0 || 
98     strncasecmp(cgiRequestMethod,"post",4)==0){
99    if(cgiContentLength==0){
100       char *buffer=new char[2];
101       char *res=NULL;
102       int r=0;
103       while((r=fread(buffer,sizeof(char),1,cgiIn))){
104         buffer[1]=0;
105         if(res==NULL){
106           res=(char*)malloc(2*sizeof(char));
107           sprintf(res,"%s",buffer);
108         }
109         else{
110           res=(char*)realloc(res,(cgiContentLength+2)*sizeof(char));
111           memcpy(res + cgiContentLength, buffer, sizeof(char));
112           res[cgiContentLength+1]=0;
113         }
114         cgiContentLength+=r;
115       }
116       delete[] buffer;
117       if(res==NULL && (strQuery==NULL || strlen(strQuery)==0)){
118         return errorException(NULL,"ZOO-Kernel failed to process your request because the request was empty.","InternalError",NULL);
119       }else{
120         if(strQuery==NULL || strlen(strQuery)==0)
121           tmpMap=createMap("request",res);
122       }
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#ifdef WIN32
181      char* tmp = url_decode(value); 
182      if(tmpMap!=NULL)         
183        addToMap(tmpMap,*arrayStep,tmp);
184      else             
185        tmpMap=createMap(*arrayStep,tmp);
186      free(tmp);
187#else
188      if(tmpMap!=NULL)
189        addToMap(tmpMap,*arrayStep,value);
190      else
191        tmpMap=createMap(*arrayStep,value);
192#endif 
193      arrayStep++;
194      delete[]value;
195    }
196    cgiStringArrayFree(array);
197  }
198
199#ifdef WIN32
200  map *tmpReq=getMap(tmpMap,"rfile");
201  if(tmpReq!=NULL){
202    FILE *lf=fopen(tmpReq->value,"r");
203    fseek(lf,0,SEEK_END);
204    long flen=ftell(lf);
205    fseek(lf,0,SEEK_SET);
206    char *buffer=(char*)malloc((flen+1)*sizeof(char));
207    fread(buffer,flen,1,lf);
208    fclose(lf);
209    addToMap(tmpMap,"request",buffer);
210    free(buffer);
211    cgiContentLength=flen+9;
212  }
213#endif
214  /**
215   * In case that the POST method was used, then check if params came in XML
216   * format else try to use the attribute "request" which should be the only
217   * one.
218   */
219  if(strncasecmp(cgiRequestMethod,"post",4)==0 || 
220     (count(tmpMap)==1 && strncmp(tmpMap->value,"<",1)==0) 
221#ifdef WIN32
222     ||tmpReq!=NULL
223#endif
224     ){
225    /**
226     * Store the original XML request in xrequest map
227     */
228    map* t1=getMap(tmpMap,"request");
229    if(t1!=NULL && strncasecmp(t1->value,"<",1)==0) {
230      addToMap(tmpMap,"xrequest",t1->value);
231      xmlInitParser();
232      xmlDocPtr doc = xmlParseMemory(t1->value,cgiContentLength);
233      {
234        xmlXPathObjectPtr reqptr=extractFromDoc(doc,"/*[local-name()='Envelope']/*[local-name()='Body']/*");
235        if(reqptr!=NULL){
236          xmlNodeSet* req=reqptr->nodesetval;
237          if(req!=NULL && req->nodeNr==1){
238            addToMap(tmpMap,"soap","true");
239            for(int k=0;k < req->nodeNr;k++){
240              //xmlNsPtr ns=xmlNewNs(req->nodeTab[k],BAD_CAST "http://www.w3.org/2001/XMLSchema-instance",BAD_CAST "xsi");
241              xmlDocSetRootElement(doc, req->nodeTab[k]);
242              xmlChar *xmlbuff;
243              int buffersize;
244              xmlDocDumpFormatMemoryEnc(doc, &xmlbuff, &buffersize, "utf-8", 1);
245              addToMap(tmpMap,"xrequest",(char*)xmlbuff);
246              xmlFree(xmlbuff);
247            }
248          }
249          xmlXPathFreeObject(reqptr);
250        }
251      }
252
253      xmlNodePtr cur = xmlDocGetRootElement(doc);
254      char *tval;
255      tval=NULL;
256      tval = (char*) xmlGetProp(cur,BAD_CAST "service");
257      if(tval!=NULL){
258        addToMap(tmpMap,"service",tval);
259        xmlFree(tval);
260      }
261      tval=NULL;
262      tval = (char*) xmlGetProp(cur,BAD_CAST "language");
263      if(tval!=NULL){
264        addToMap(tmpMap,"language",tval);
265        xmlFree(tval);
266      }
267      const char* requests[3]={"GetCapabilities","DescribeProcess","Execute"};
268      for(int j=0;j<3;j++){
269        char tt[128];
270        sprintf(tt,"/*[local-name()='%s']",requests[j]);
271        xmlXPathObjectPtr reqptr=extractFromDoc(doc,tt);
272        if(reqptr!=NULL){
273          xmlNodeSet* req=reqptr->nodesetval;
274#ifdef DEBUG
275          fprintf(stderr,"%i",req->nodeNr);
276#endif
277          if(req!=NULL && req->nodeNr==1){
278            if(t1->value!=NULL)
279              free(t1->value);
280            t1->value=zStrdup(requests[j]);
281            j=2;
282          }
283          xmlXPathFreeObject(reqptr);
284        }
285      }
286      if(strncasecmp(t1->value,"GetCapabilities",15)==0){
287        xmlXPathObjectPtr versptr=extractFromDoc(doc,"/*/*/*[local-name()='Version']");
288        xmlNodeSet* vers=versptr->nodesetval;
289        if(vers!=NULL && vers->nodeTab!=NULL && vers->nodeTab[0]!=NULL){
290          xmlChar* content=xmlNodeListGetString(doc, vers->nodeTab[0]->xmlChildrenNode,1);
291          addToMap(tmpMap,"version",(char*)content);
292          xmlFree(content);
293        }
294        if(cur->ns){
295          addToMap(tmpMap,"wps_schemas",(char*)cur->ns->href);
296          int j=0;
297          for(j=0;j<2;j++)
298            if(strncasecmp(schemas[j][2],(char*)cur->ns->href,strlen(schemas[j][2]))==0){
299              char vers[6];
300              sprintf(vers,"%d.0.0",j+1);
301              addToMap(tmpMap,"version",(char*)vers);
302            }
303        }
304        xmlXPathFreeObject(versptr);
305      }else{
306        tval=NULL;
307        tval = (char*) xmlGetProp(cur,BAD_CAST "version");
308        if(tval!=NULL){
309          addToMap(tmpMap,"version",tval);
310          xmlFree(tval);
311        }
312        tval = (char*) xmlGetProp(cur,BAD_CAST "language");
313        if(tval!=NULL){
314          addToMap(tmpMap,"language",tval);
315          xmlFree(tval);
316        }
317        xmlXPathObjectPtr idptr=extractFromDoc(doc,"/*/*[local-name()='Identifier']");
318        if(idptr!=NULL){
319          xmlNodeSet* id=idptr->nodesetval;
320          if(id!=NULL){
321            char* identifiers=NULL;
322            identifiers=(char*)calloc(cgiContentLength,sizeof(char));
323            identifiers[0]=0;
324            for(int k=0;k<id->nodeNr;k++){
325              xmlChar* content=xmlNodeListGetString(doc, id->nodeTab[k]->xmlChildrenNode,1);
326              if(strlen(identifiers)>0){
327                char *tmp=zStrdup(identifiers);
328                snprintf(identifiers,strlen(tmp)+xmlStrlen(content)+2,"%s,%s",tmp,content);
329                free(tmp);
330              }
331              else{
332                snprintf(identifiers,xmlStrlen(content)+1,"%s",content);
333              }
334              xmlFree(content);
335            }
336            xmlXPathFreeObject(idptr);
337            addToMap(tmpMap,"Identifier",identifiers);
338            free(identifiers);
339          }
340        }else{
341          idptr=extractFromDoc(doc,"/*/*[local-name()='JobID']");
342          if(idptr!=NULL){
343            xmlNodeSet* id=idptr->nodesetval;
344            if(id!=NULL){
345              char* identifiers=NULL;
346              identifiers=(char*)calloc(cgiContentLength,sizeof(char));
347              identifiers[0]=0;
348              for(int k=0;k<id->nodeNr;k++){
349                xmlChar* content=xmlNodeListGetString(doc, id->nodeTab[k]->xmlChildrenNode,1);
350                if(strlen(identifiers)>0){
351                  char *tmp=zStrdup(identifiers);
352                  snprintf(identifiers,strlen(tmp)+xmlStrlen(content)+2,"%s,%s",tmp,content);
353                  free(tmp);
354                }
355                else{
356                  snprintf(identifiers,xmlStrlen(content)+1,"%s",content);
357                }
358                xmlFree(content);
359              }
360              xmlXPathFreeObject(idptr);
361              addToMap(tmpMap,"JobID",identifiers);
362              free(identifiers);
363            }
364        }
365        }
366      }
367      xmlFreeDoc(doc);
368      xmlCleanupParser();
369    }else{
370      freeMap(&tmpMap);
371      free(tmpMap);
372      tmpMap=createMap("not_valid","true");
373    }
374
375    char *token,*saveptr;
376    token=strtok_r(cgiQueryString,"&",&saveptr);
377    while(token!=NULL){
378      char *token1,*saveptr1;
379      char *name=NULL;
380      char *value=NULL;
381      token1=strtok_r(token,"=",&saveptr1);
382      while(token1!=NULL){
383        if(name==NULL)
384          name=zStrdup(token1);
385        else
386          value=zStrdup(token1);
387        token1=strtok_r(NULL,"=",&saveptr1);
388      }   
389      //addToMap(tmpMap,name,value);
390          /* knut: strtok(_r) ignores delimiter bytes at start and end of string;
391           * it will return non-empty string or NULL, e.g. "metapath=" yields value=NULL.
392           * This modification sets value="" instead of NULL.
393           */
394          addToMap(tmpMap,name, value != NULL ? value : "");
395
396      free(name);
397      free(value);
398      name=NULL;
399      value=NULL;
400      token=strtok_r(NULL,"&",&saveptr);
401    }
402   
403  }
404
405  if(strncasecmp(cgiContentType,"multipart/form-data",19)==0){
406    map* tmp=getMap(tmpMap,"dataInputs");
407    if(tmp!=NULL){
408      addToMap(tmpMap,"dataInputs",strstr(strQuery,"dataInputs=")+11);
409    }
410  }
411
412  if(strQuery!=NULL)
413    free(strQuery);
414
415 
416  runRequest(&tmpMap);
417
418  if(tmpMap!=NULL){
419    freeMap(&tmpMap);
420    free(tmpMap);
421  }
422  return 0;
423
424}
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