/** * Author : GĂ©rald FENOY * * Copyright 2008-2011 GeoLabs SARL. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ #define MALLOC_CHECK_ 0 #define MALLOC_CHECK 0 /** * Specific includes */ #ifndef WIN32 #include "fcgio.h" #include "fcgi_config.h" #include "fcgi_stdio.h" #endif #include #include #include "service_internal.h" #ifdef WIN32 #include "windows.h" #define strtok_r strtok_s #endif extern "C" { #include "cgic.h" #include #include #include #include #include } #include "service_internal.h" xmlXPathObjectPtr extractFromDoc(xmlDocPtr,const char*); int runRequest(map*); using namespace std; #ifndef TRUE #define TRUE 1 #endif #ifndef FALSE #define FALSE -1 #endif int cgiMain(){ /** * We'll use cgiOut as the default output (stdout) to produce plain text * response. */ dup2(fileno(cgiOut),fileno(stdout)); #ifdef DEBUG fprintf(cgiOut,"Content-Type: text/plain; charset=utf-8\r\nStatus: 200 OK\r\n\r\n"); fprintf(cgiOut,"Welcome on ZOO verbose debuging mode \r\n\r\n"); fflush(cgiOut); fprintf (stderr, "Addr:%s\n", cgiRemoteAddr); fprintf (stderr, "RequestMethod: (%s) %d %d\n", cgiRequestMethod,strncasecmp(cgiRequestMethod,"post",4),strncmp(cgiContentType,"text/xml",8)==0 || strncasecmp(cgiRequestMethod,"post",4)==0); fprintf (stderr, "Request: %s\n", cgiQueryString); fprintf (stderr, "ContentType: %s\n", cgiContentType); fprintf (stderr, "ContentLength: %d\n", cgiContentLength); fflush(stderr); #endif char *strQuery=NULL; if(cgiQueryString!=NULL) strQuery=zStrdup(cgiQueryString); map* tmpMap=NULL; if(strncmp(cgiContentType,"text/xml",8)==0 || strncasecmp(cgiRequestMethod,"post",4)==0){ if(cgiContentLength==NULL){ cgiContentLength=0; char *buffer=new char[2]; char *res=NULL; int r=0; while((r=fread(buffer,sizeof(char),1,cgiIn))){ cgiContentLength+=r; if(res==NULL){ res=(char*)malloc(1*sizeof(char)); sprintf(res,"%s",buffer); } else{ res=(char*)realloc(res,(cgiContentLength+1)*sizeof(char)); char *tmp=zStrdup(res); sprintf(res,"%s%s",tmp,buffer); free(tmp); } } if(res==NULL && (strQuery==NULL || strlen(strQuery)==0)){ return errorException(NULL,"ZOO-Kernel failed to process your request cause the request was emtpty.","InternalError"); }else{ if(strQuery==NULL || strlen(strQuery)==0) tmpMap=createMap("request",res); } }else{ char *buffer=new char[cgiContentLength+1]; int r=0; if(fread(buffer,sizeof(char),cgiContentLength,cgiIn)>=0){ buffer[cgiContentLength]=0; tmpMap=createMap("request",buffer); }else{ buffer[0]=0; char **array, **arrayStep; if (cgiFormEntries(&array) != cgiFormSuccess) { return 1; } arrayStep = array; while (*arrayStep) { char *ivalue=new char[cgiContentLength]; cgiFormStringNoNewlines(*arrayStep, ivalue, cgiContentLength); char* tmpValueFinal=(char*) malloc((strlen(*arrayStep)+strlen(ivalue)+1)*sizeof(char)); sprintf(tmpValueFinal,"%s=%s",*arrayStep,ivalue); if(strlen(buffer)==0){ sprintf(buffer,"%s",tmpValueFinal); }else{ char *tmp=zStrdup(buffer); sprintf(buffer,"%s&%s",tmp,tmpValueFinal); free(tmp); } free(tmpValueFinal); #ifdef DEBUG fprintf(stderr,"(( \n %s \n %s \n ))",*arrayStep,ivalue); #endif delete[]ivalue; arrayStep++; } tmpMap=createMap("request",buffer); } delete[]buffer; } } else{ #ifdef DEBUG dumpMap(tmpMap); #endif char **array, **arrayStep; if (cgiFormEntries(&array) != cgiFormSuccess) { return 1; } arrayStep = array; while (*arrayStep) { char *value=new char[cgiContentLength]; cgiFormStringNoNewlines(*arrayStep, value, cgiContentLength); #ifdef DEBUG fprintf(stderr,"(( \n %s \n %s \n ))",*arrayStep,value); #endif if(tmpMap!=NULL) addToMap(tmpMap,*arrayStep,value); else tmpMap=createMap(*arrayStep,value); arrayStep++; delete[]value; } cgiStringArrayFree(array); } /** * In case that the POST method was used, then check if params came in XML * format else try to use the attribute "request" which should be the only * one. */ if(strncasecmp(cgiRequestMethod,"post",4)==0 || (count(tmpMap)==1 && strncmp(tmpMap->value,"<",1)==0)){ /** * First include the MetaPath and the ServiceProvider default parameters * (which should be always available in GET params so in cgiQueryString) */ char *str1; str1=cgiQueryString; /** * Store the original XML request in xrequest map */ map* t1=getMap(tmpMap,"request"); if(t1!=NULL && strncasecmp(t1->value,"<",1)==0){ addToMap(tmpMap,"xrequest",t1->value); xmlInitParser(); xmlDocPtr doc = xmlParseMemory(t1->value,cgiContentLength); { xmlXPathObjectPtr reqptr=extractFromDoc(doc,"/*[local-name()='Envelope']/*[local-name()='Body']/*"); if(reqptr!=NULL){ xmlNodeSet* req=reqptr->nodesetval; if(req!=NULL && req->nodeNr==1){ addToMap(tmpMap,"soap","true"); int k=0; for(k;k < req->nodeNr;k++){ xmlNsPtr ns=xmlNewNs(req->nodeTab[k],BAD_CAST "http://www.w3.org/2001/XMLSchema-instance",BAD_CAST "xsi"); xmlDocSetRootElement(doc, req->nodeTab[k]); xmlChar *xmlbuff; int buffersize; xmlDocDumpFormatMemoryEnc(doc, &xmlbuff, &buffersize, "utf-8", 1); addToMap(tmpMap,"xrequest",(char*)xmlbuff); char *tmp=(char*)xmlbuff; xmlFree(xmlbuff); } } } } xmlNodePtr cur = xmlDocGetRootElement(doc); char *tval; tval=NULL; tval = (char*) xmlGetProp(cur,BAD_CAST "service"); if(tval!=NULL) addToMap(tmpMap,"service",tval); tval=NULL; tval = (char*) xmlGetProp(cur,BAD_CAST "language"); if(tval!=NULL) addToMap(tmpMap,"language",tval); const char* requests[3]={"GetCapabilities","DescribeProcess","Execute"}; for(int j=0;j<3;j++){ char tt[128]; sprintf(tt,"/*[local-name()='%s']",requests[j]); xmlXPathObjectPtr reqptr=extractFromDoc(doc,tt); if(reqptr!=NULL){ xmlNodeSet* req=reqptr->nodesetval; #ifdef DEBUG fprintf(stderr,"%i",req->nodeNr); #endif if(req!=NULL && req->nodeNr==1){ t1->value=zStrdup(requests[j]); j=2; } xmlXPathFreeObject(reqptr); } } if(strncasecmp(t1->value,"GetCapabilities",15)==0){ xmlXPathObjectPtr versptr=extractFromDoc(doc,"/*/*/*[local-name()='Version']"); xmlNodeSet* vers=versptr->nodesetval; xmlChar* content=xmlNodeListGetString(doc, vers->nodeTab[0]->xmlChildrenNode,1); addToMap(tmpMap,"version",(char*)content); xmlXPathFreeObject(versptr); xmlFree(content); }else{ tval=NULL; tval = (char*) xmlGetProp(cur,BAD_CAST "version"); if(tval!=NULL) addToMap(tmpMap,"version",tval); tval = (char*) xmlGetProp(cur,BAD_CAST "language"); if(tval!=NULL) addToMap(tmpMap,"language",tval); xmlXPathObjectPtr idptr=extractFromDoc(doc,"/*/*[local-name()='Identifier']"); if(idptr!=NULL){ xmlNodeSet* id=idptr->nodesetval; if(id!=NULL){ char* identifiers=NULL; identifiers=(char*)calloc(cgiContentLength,sizeof(char)); identifiers[0]=0; for(int k=0;knodeNr;k++){ xmlChar* content=xmlNodeListGetString(doc, id->nodeTab[k]->xmlChildrenNode,1); if(strlen(identifiers)>0){ char *tmp=zStrdup(identifiers); snprintf(identifiers,strlen(tmp)+xmlStrlen(content)+2,"%s,%s",tmp,content); free(tmp); } else{ snprintf(identifiers,xmlStrlen(content)+1,"%s",content); } xmlFree(content); } xmlXPathFreeObject(idptr); addToMap(tmpMap,"Identifier",identifiers); free(identifiers); } } } xmlFreeDoc(doc); xmlCleanupParser(); }else{ freeMap(&tmpMap); free(tmpMap); tmpMap=createMap("not_valid","true"); } char *token,*saveptr; token=strtok_r(cgiQueryString,"&",&saveptr); while(token!=NULL){ char *token1,*saveptr1; char *name=NULL; char *value=NULL; token1=strtok_r(token,"=",&saveptr1); while(token1!=NULL){ if(name==NULL) name=zStrdup(token1); else value=zStrdup(token1); token1=strtok_r(NULL,"=",&saveptr1); } addToMap(tmpMap,name,value); free(name); free(value); name=NULL; value=NULL; token=strtok_r(NULL,"&",&saveptr); } } if(strncasecmp(cgiContentType,"multipart/form-data",19)==0){ map* tmp=getMap(tmpMap,"dataInputs"); if(tmp!=NULL){ addToMap(tmpMap,"dataInputs",strstr(strQuery,"dataInputs=")+11); } } if(strQuery!=NULL) free(strQuery); runRequest(tmpMap); /** * Required but can't be made after executing a process using POST requests. */ if(strncasecmp(cgiRequestMethod,"post",4)!=0 && count(tmpMap)!=1 && tmpMap!=NULL){ freeMap(&tmpMap); free(tmpMap); } return 0; }