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

Last change on this file since 836 was 835, checked in by jmckenna, 7 years ago

handle strcasestr on Windows (ticket#158)

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