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

Last change on this file since 375 was 375, checked in by djay, 11 years ago

Print specific headers when a [headers] section was added to the main.cfg file (can add headers such as X-Powered-By for instance). Handle reading file in cache as binary (solving file size not corresponding for text files).

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc
File size: 9.8 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#endif
81
82  char *strQuery=strdup(cgiQueryString);
83  map* tmpMap=NULL;
84
85  if(strncmp(cgiContentType,"text/xml",8)==0 || 
86     strncasecmp(cgiRequestMethod,"post",4)==0){
87    //fprintf(stderr,"length %d\n",cgiContentLength);
88    if(cgiContentLength==NULL){
89       cgiContentLength=0;
90       char *buffer=new char[2];
91       char *res=NULL;
92       int r=0;
93       while(r=fread(buffer,sizeof(char),1,cgiIn)){
94         cgiContentLength+=r;
95         if(res==NULL){
96           res=(char*)malloc(1*sizeof(char));
97           sprintf(res,"%s",buffer);
98         }
99         else{
100           res=(char*)realloc(res,(cgiContentLength+1)*sizeof(char));
101           char *tmp=strdup(res);
102           sprintf(res,"%s%s",tmp,buffer);
103           free(tmp);
104         }
105       }
106       if(res==NULL){
107         return errorException(NULL,"ZOO-Kernel failed to process your request cause the request was emtpty.","InternalError");
108       }else
109         tmpMap=createMap("request",res);
110    }else{
111      char *buffer=new char[cgiContentLength+1];
112      if(fread(buffer,sizeof(char),cgiContentLength,cgiIn)){
113        buffer[cgiContentLength]=0;
114        tmpMap=createMap("request",buffer);
115        //fprintf(stderr,"%s\n",tmpMap->value);
116      }else{
117        buffer[0]=0;
118        char **array, **arrayStep;
119        if (cgiFormEntries(&array) != cgiFormSuccess) {
120          return 1;
121        }
122        arrayStep = array;
123        while (*arrayStep) {
124          char *ivalue=new char[cgiContentLength];
125          cgiFormStringNoNewlines(*arrayStep, ivalue, cgiContentLength);
126          char* tmpValueFinal=(char*) malloc((strlen(*arrayStep)+strlen(ivalue)+1)*sizeof(char));
127          sprintf(tmpValueFinal,"%s=%s",*arrayStep,ivalue);
128          if(strlen(buffer)==0){
129            sprintf(buffer,"%s",tmpValueFinal);
130          }else{
131            char *tmp=strdup(buffer);
132            sprintf(buffer,"%s&%s",tmp,tmpValueFinal);
133            free(tmp);
134          }
135         
136          sprintf(tmpValueFinal,"%s=%s",*arrayStep,ivalue);
137          free(tmpValueFinal);
138#ifdef DEBUG
139          fprintf(stderr,"(( \n %s \n %s \n ))",*arrayStep,ivalue);
140#endif
141          delete[]ivalue;
142          arrayStep++;
143        }
144        tmpMap=createMap("request",buffer);
145      }
146      delete[]buffer;
147    }
148  }
149  else{
150#ifdef DEBUG
151    dumpMap(tmpMap);
152#endif
153    char **array, **arrayStep;
154    if (cgiFormEntries(&array) != cgiFormSuccess) {
155      return 1;
156    }
157    arrayStep = array;
158    while (*arrayStep) {
159      char *value=new char[cgiContentLength];
160      cgiFormStringNoNewlines(*arrayStep, value, cgiContentLength);
161#ifdef DEBUG
162      fprintf(stderr,"(( \n %s \n %s \n ))",*arrayStep,value);
163#endif
164      if(tmpMap!=NULL)
165        addToMap(tmpMap,*arrayStep,value);
166      else
167        tmpMap=createMap(*arrayStep,value);
168      arrayStep++;
169      delete[]value;
170    }
171    cgiStringArrayFree(array);
172  }
173
174  /**
175   * In case that the POST method was used, then check if params came in XML
176   * format else try to use the attribute "request" which should be the only
177   * one.
178   */
179  if(strncasecmp(cgiRequestMethod,"post",4)==0 || 
180     (count(tmpMap)==1 && strncmp(tmpMap->value,"<",1)==0)){
181    /**
182     * First include the MetaPath and the ServiceProvider default parameters
183     * (which should be always available in GET params so in cgiQueryString)
184     */
185    char *str1;
186    str1=cgiQueryString;
187    /**
188     * Store the original XML request in xrequest map
189     */
190    map* t1=getMap(tmpMap,"request");
191    if(t1!=NULL && strncasecmp(t1->value,"<",1)==0){
192      addToMap(tmpMap,"xrequest",t1->value);
193      xmlInitParser();
194      xmlDocPtr doc = xmlParseMemory(t1->value,cgiContentLength);
195
196
197      {
198        xmlXPathObjectPtr reqptr=extractFromDoc(doc,"/*[local-name()='Envelope']/*[local-name()='Body']/*");
199        if(reqptr!=NULL){
200          xmlNodeSet* req=reqptr->nodesetval;
201          if(req!=NULL && req->nodeNr==1){
202            addToMap(tmpMap,"soap","true");
203            int k=0;
204            for(k;k < req->nodeNr;k++){
205              xmlNsPtr ns=xmlNewNs(req->nodeTab[k],BAD_CAST "http://www.w3.org/2001/XMLSchema-instance",BAD_CAST "xsi");
206              xmlDocSetRootElement(doc, req->nodeTab[k]);
207              xmlChar *xmlbuff;
208              int buffersize;
209              xmlDocDumpFormatMemoryEnc(doc, &xmlbuff, &buffersize, "utf-8", 1);
210              addToMap(tmpMap,"xrequest",(char*)xmlbuff);
211              char *tmp=(char*)xmlbuff;
212              fprintf(stderr,"%s\n",tmp);
213              xmlFree(xmlbuff);
214            }
215          }
216        }
217      }
218
219      xmlNodePtr cur = xmlDocGetRootElement(doc);
220      char *tval;
221      tval=NULL;
222      tval = (char*) xmlGetProp(cur,BAD_CAST "service");
223      if(tval!=NULL)
224        addToMap(tmpMap,"service",tval);
225      tval=NULL;
226      tval = (char*) xmlGetProp(cur,BAD_CAST "language");
227      if(tval!=NULL)
228        addToMap(tmpMap,"language",tval);
229      const char* requests[3]={"GetCapabilities","DescribeProcess","Execute"};
230      for(int j=0;j<3;j++){
231        char tt[128];
232        sprintf(tt,"/*[local-name()='%s']",requests[j]);
233        xmlXPathObjectPtr reqptr=extractFromDoc(doc,tt);
234        if(reqptr!=NULL){
235          xmlNodeSet* req=reqptr->nodesetval;
236#ifdef DEBUG
237          fprintf(stderr,"%i",req->nodeNr);
238#endif
239          if(req!=NULL && req->nodeNr==1){
240            t1->value=strdup(requests[j]);
241            j=2;
242          }
243          xmlXPathFreeObject(reqptr);
244        }
245        //xmlFree(req);
246      }
247      if(strncasecmp(t1->value,"GetCapabilities",15)==0){
248        xmlXPathObjectPtr versptr=extractFromDoc(doc,"/*/*/*[local-name()='Version']");
249        xmlNodeSet* vers=versptr->nodesetval;
250        xmlChar* content=xmlNodeListGetString(doc, vers->nodeTab[0]->xmlChildrenNode,1);
251        addToMap(tmpMap,"version",(char*)content);
252        xmlXPathFreeObject(versptr);
253        //xmlFree(vers);
254        xmlFree(content);
255      }else{
256        tval=NULL;
257        tval = (char*) xmlGetProp(cur,BAD_CAST "version");
258        if(tval!=NULL)
259          addToMap(tmpMap,"version",tval);
260        xmlFree(tval);
261        tval = (char*) xmlGetProp(cur,BAD_CAST "language");
262        if(tval!=NULL)
263          addToMap(tmpMap,"language",tval);
264        xmlXPathObjectPtr idptr=extractFromDoc(doc,"/*/*[local-name()='Identifier']");
265        if(idptr!=NULL){
266          xmlNodeSet* id=idptr->nodesetval;
267          if(id!=NULL){
268            char* identifiers=NULL;
269            identifiers=(char*)calloc(cgiContentLength,sizeof(char));
270            identifiers[0]=0;
271            for(int k=0;k<id->nodeNr;k++){
272              xmlChar* content=xmlNodeListGetString(doc, id->nodeTab[k]->xmlChildrenNode,1);
273              if(strlen(identifiers)>0){
274                char *tmp=strdup(identifiers);
275                snprintf(identifiers,strlen(tmp)+xmlStrlen(content)+2,"%s,%s",tmp,content);
276                free(tmp);
277              }
278              else{
279                snprintf(identifiers,xmlStrlen(content)+1,"%s",content);
280              }
281              xmlFree(content);
282            }
283            xmlXPathFreeObject(idptr);
284            addToMap(tmpMap,"Identifier",identifiers);
285            free(identifiers);
286          }
287        }
288        //xmlFree(id);
289      }
290      xmlFree(tval);
291      xmlFreeDoc(doc);
292      xmlCleanupParser();
293    }else{
294      freeMap(&tmpMap);
295      free(tmpMap);
296      tmpMap=createMap("not_valid","true");
297    }
298
299    char *token,*saveptr;
300    token=strtok_r(cgiQueryString,"&",&saveptr);
301    while(token!=NULL){
302      char *token1,*saveptr1;
303      char *name=NULL;
304      char *value=NULL;
305      token1=strtok_r(token,"=",&saveptr1);
306      while(token1!=NULL){
307        if(name==NULL)
308          name=strdup(token1);
309        else
310          value=strdup(token1);
311        token1=strtok_r(NULL,"=",&saveptr1);
312      }
313      addToMap(tmpMap,name,value);
314      free(name);
315      free(value);
316      name=NULL;
317      value=NULL;
318      token=strtok_r(NULL,"&",&saveptr);
319    }
320   
321  }
322
323
324  if(strncasecmp(cgiContentType,"multipart/form-data",19)==0){
325      map* tmp=getMap(tmpMap,"dataInputs");
326      if(tmp!=NULL){
327        addToMap(tmpMap,"dataInputs",strstr(strQuery,"dataInputs=")+11);
328      }
329    }
330
331  runRequest(tmpMap);
332
333  /**
334   * Required but can't be made after executing a process using POST requests.
335   */
336  if(strncasecmp(cgiRequestMethod,"post",4)!=0 && count(tmpMap)!=1 && tmpMap!=NULL){
337    freeMap(&tmpMap);
338    free(tmpMap);
339  }
340  return 0;
341
342}
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