source: branches/PublicaMundi_David-devel/zoo-project/zoo-kernel/zoo_loader.c @ 549

Last change on this file since 549 was 549, checked in by david, 7 years ago
  • Adding Process Management
  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc
File size: 18.0 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/*
33#include "fcgio.h"
34#include "fcgi_config.h"
35#include "fcgi_stdio.h"
36*/
37#include <unistd.h>
38#include <fcgiapp.h>
39#endif
40#include <sys/wait.h>
41#include <pthread.h>
42#include <sys/types.h>
43#include <unistd.h>
44#include "service_internal.h"
45#ifdef WIN32
46#include "windows.h"
47#define strtok_r strtok_s
48#endif
49
50extern "C"
51{
52#include "cgic.h"
53#include <libxml/tree.h>
54#include <libxml/xmlmemory.h>
55#include <libxml/parser.h>
56#include <libxml/xpath.h>
57#include <libxml/xpathInternals.h>
58
59#include <string.h>
60#include <stdio.h>
61#include <stdlib.h>
62#include <glib.h>
63#include <sys/stat.h>
64}
65
66#include "service_zcfg.h"
67//#include "service_internal.h"
68
69xmlXPathObjectPtr extractFromDoc (xmlDocPtr, const char *);
70int runRequest (map **,struct cgi_env **,FCGX_Request *);
71
72using namespace std;
73
74#ifndef TRUE
75#define TRUE 1
76#endif
77#ifndef FALSE
78#define FALSE -1
79#endif
80
81
82static void PrintEnv(FCGX_Stream *out, char *label, char **envp)
83{
84    FCGX_FPrintF(out, "%s:<br>\n<pre>\n", label);
85    for( ; *envp != NULL; envp++) {
86        FCGX_FPrintF(out, "%s\n", *envp);
87    }
88    FCGX_FPrintF(out, "</pre><p>\n");
89}
90
91#define PATH_SOCKET "/tmp/zoo.sock"
92#define THREAD_COUNT 50
93static int counts[THREAD_COUNT];
94
95
96int process(FCGX_Request *request){
97
98      int pid = getpid();
99      struct cgi_env *cgi;
100      //PrintEnv(request.err, "Request environment", request.envp);
101      cgi = (struct cgi_env*)malloc(sizeof(struct cgi_env));
102      cgiMain_init (NULL, NULL,&cgi,request);
103      char *strQuery = NULL;
104      if (cgi->cgiQueryString != NULL)
105        strQuery = zStrdup (cgi->cgiQueryString);
106      map *tmpMap = NULL;
107
108      if (strncmp (cgi->cgiContentType, "text/xml", 8) == 0 ||
109          strncasecmp (cgi->cgiRequestMethod, "post", 4) == 0)
110        {
111          if (cgi->cgiContentLength == 0)
112            {
113              char *post_data = NULL;
114              int i = 0;
115              int ch = FCGX_GetChar(request->in);
116              while (ch != -1){
117                {
118                  i++;
119                  if (post_data == NULL)
120                    {
121                    post_data=(char*)malloc(sizeof(char));
122                    post_data[i-1] = (char) ch;
123                    }
124                  else
125                    {
126                    post_data=(char*)realloc(post_data,i*sizeof(char));
127                    post_data[i-1] = (char) ch;
128                    }
129                  ch = FCGX_GetChar(request->in);
130                  if (ch == -1 ){
131                    post_data=(char*)realloc(post_data,(i + 1)*sizeof(char));
132                    post_data[i] = '\0';
133                    }
134                }
135                cgi->cgiContentLength = i;
136              if (post_data == NULL && (strQuery == NULL || strlen (strQuery) == 0))
137                {
138                  return errorException (NULL,
139                                         "ZOO-Kernel failed to process your request cause the request was emtpty.",
140                                         "InternalError", NULL,request->out);
141                }
142              else
143                {
144                  if (strQuery == NULL || strlen (strQuery) == 0)
145                    tmpMap = createMap ("request", post_data);
146                }
147              if (post_data != NULL)
148                free (post_data);
149                }
150            }
151          else
152            {
153              char *post_data = new char[cgi->cgiContentLength + 1];
154              int r = FCGX_GetStr(post_data,cgi->cgiContentLength,request->in);
155              if ( r > 0)
156                {
157                  post_data[r] = '\0';
158                  cgi->cgiContentLength = r;
159                  tmpMap = createMap ("request", post_data);
160                }
161              else
162                {
163                  post_data[0] = '\0';
164                  char **array, **arrayStep;
165                  if (cgiFormEntries (&array,&cgi) != cgiFormSuccess)
166                    {
167                      return 1;
168                    }
169                  arrayStep = array;
170                  while (*arrayStep)
171                    {
172                      char *ivalue = new char[cgi->cgiContentLength];
173                      cgiFormStringNoNewlines (*arrayStep, ivalue,
174                                               cgi->cgiContentLength,&cgi);
175                      char *tmpValueFinal =
176                        (char *)
177                        malloc ((strlen (*arrayStep) + strlen (ivalue) +
178                                 1) * sizeof (char));
179                      sprintf (tmpValueFinal, "%s=%s", *arrayStep, ivalue);
180                      if (strlen (post_data) == 0)
181                        {
182                          sprintf (post_data, "%s", tmpValueFinal);
183                        }
184                      else
185                        {
186                          char *tmp = zStrdup (post_data);
187                          sprintf (post_data, "%s&%s", tmp, tmpValueFinal);
188                          free (tmp);
189                        }
190                      free (tmpValueFinal);
191#ifdef DEBUG
192                      fprintf (stderr, "(( \n %s \n %s \n ))", *arrayStep,
193                               ivalue);
194#endif
195                      delete[]ivalue;
196                      arrayStep++;
197                    }
198                  if (tmpMap != NULL)
199                    addToMap (tmpMap, "request", post_data);
200                  else
201                    tmpMap = createMap ("request", post_data);
202                }
203              delete[]post_data;
204            }
205        }
206      else
207        {
208#ifdef DEBUG
209          dumpMap (tmpMap);
210#endif
211       
212       char **array, **arrayStep;
213          if (cgiFormEntries (&array,&cgi) != cgiFormSuccess)
214            {
215              return 1;
216            }
217          arrayStep = array;
218          while (*arrayStep)
219            {
220              char *value = new char[cgi->cgiContentLength];
221              cgiFormStringNoNewlines (*arrayStep, value, cgi->cgiContentLength,&cgi);
222#ifdef DEBUG
223              fprintf (stderr, "(( \n %s \n %s \n ))", *arrayStep, value);
224#endif
225              if (tmpMap != NULL)
226                addToMap (tmpMap, *arrayStep, value);
227              else
228                tmpMap = createMap (*arrayStep, value);
229              arrayStep++;
230              delete[]value;
231            }
232          cgiStringArrayFree (array);
233        }
234
235#ifdef WIN32
236      map *tmpReq = getMap (tmpMap, "rfile");
237      if (tmpReq != NULL)
238        {
239          FILE *lf = fopen (tmpReq->value, "r");
240          fseek (lf, 0, SEEK_END);
241          long flen = ftell (lf);
242          fseek (lf, 0, SEEK_SET);
243          char *buffer = (char *) malloc ((flen + 1) * sizeof (char));
244          fread (buffer, flen, 1, lf);
245          fclose (lf);
246          addToMap (tmpMap, "request", buffer);
247          free (buffer);
248          cgiContentLength = flen + 9;
249        }
250#endif
251  /**
252   * In case that the POST method was used, then check if params came in XML
253   * format else try to use the attribute "request" which should be the only
254   * one.
255   */
256      if (strncasecmp (cgi->cgiRequestMethod, "post", 4) == 0 ||
257          (count (tmpMap) == 1 && strncmp (tmpMap->value, "<", 1) == 0)
258#ifdef WIN32
259          || tmpReq != NULL
260#endif
261        )
262        {
263    /**
264     * Store the original XML request in xrequest map
265     */
266          map *t1 = getMap (tmpMap, "request");
267          if (t1 != NULL && strncasecmp (t1->value, "<", 1) == 0)
268            {
269              addToMap (tmpMap, "xrequest", t1->value);
270              xmlInitParser ();
271              xmlDocPtr doc = xmlParseMemory (t1->value, cgi->cgiContentLength);
272              {
273                xmlXPathObjectPtr reqptr = extractFromDoc (doc,
274                                                           "/*[local-name()='Envelope']/*[local-name()='Body']/*");
275                if (reqptr != NULL)
276                  {
277                    xmlNodeSet *req = reqptr->nodesetval;
278                    if (req != NULL && req->nodeNr == 1)
279                      {
280                        addToMap (tmpMap, "soap", "true");
281                        for (int k = 0; k < req->nodeNr; k++)
282                          {
283                            //xmlNsPtr ns=xmlNewNs(req->nodeTab[k],BAD_CAST "http://www.w3.org/2001/XMLSchema-instance",BAD_CAST "xsi");
284                            xmlDocSetRootElement (doc, req->nodeTab[k]);
285                            xmlChar *xmlbuff;
286                            int buffersize;
287                            xmlDocDumpFormatMemoryEnc (doc, &xmlbuff,
288                                                       &buffersize, "utf-8",
289                                                       1);
290                            addToMap (tmpMap, "xrequest", (char *) xmlbuff);
291                            xmlFree (xmlbuff);
292                          }
293                      }
294                    xmlXPathFreeObject (reqptr);
295                  }
296              }
297
298              xmlNodePtr cur = xmlDocGetRootElement (doc);
299              char *tval;
300              tval = NULL;
301              tval = (char *) xmlGetProp (cur, BAD_CAST "service");
302              if (tval != NULL)
303                {
304                  addToMap (tmpMap, "service", tval);
305                  xmlFree (tval);
306                }
307              tval = NULL;
308              tval = (char *) xmlGetProp (cur, BAD_CAST "language");
309              if (tval != NULL)
310                {
311                  addToMap (tmpMap, "language", tval);
312                  xmlFree (tval);
313                }
314              const char *requests[3] =
315                { "GetCapabilities", "DescribeProcess", "Execute" };
316              for (int j = 0; j < 3; j++)
317                {
318                  char tt[128];
319                  sprintf (tt, "/*[local-name()='%s']", requests[j]);
320                  xmlXPathObjectPtr reqptr = extractFromDoc (doc, tt);
321                  if (reqptr != NULL)
322                    {
323                      xmlNodeSet *req = reqptr->nodesetval;
324#ifdef DEBUG
325                      fprintf (stderr, "%i", req->nodeNr);
326#endif
327                      if (req != NULL && req->nodeNr == 1)
328                        {
329                          if (t1->value != NULL)
330                            free (t1->value);
331                          t1->value = zStrdup (requests[j]);
332                          j = 2;
333                        }
334                      xmlXPathFreeObject (reqptr);
335                    }
336                }
337              if (strncasecmp (t1->value, "GetCapabilities", 15) == 0)
338                {
339                  xmlXPathObjectPtr versptr =
340                    extractFromDoc (doc, "/*/*/*[local-name()='Version']");
341                  xmlNodeSet *vers = versptr->nodesetval;
342                  xmlChar *content = xmlNodeListGetString (doc,
343                                                           vers->
344                                                           nodeTab
345                                                           [0]->xmlChildrenNode,
346                                                           1);
347                  addToMap (tmpMap, "version", (char *) content);
348                  xmlXPathFreeObject (versptr);
349                  xmlFree (content);
350                }
351              else
352                {
353                  tval = NULL;
354                  tval = (char *) xmlGetProp (cur, BAD_CAST "version");
355                  if (tval != NULL)
356                    {
357                      addToMap (tmpMap, "version", tval);
358                      xmlFree (tval);
359                    }
360                  tval = (char *) xmlGetProp (cur, BAD_CAST "language");
361                  if (tval != NULL)
362                    {
363                      addToMap (tmpMap, "language", tval);
364                      xmlFree (tval);
365                    }
366                  xmlXPathObjectPtr idptr =
367                    extractFromDoc (doc, "/*/*[local-name()='Identifier']");
368                  if (idptr != NULL)
369                    {
370                      xmlNodeSet *id = idptr->nodesetval;
371                      if (id != NULL)
372                        {
373                          char *identifiers = NULL;
374                          identifiers =
375                            (char *) calloc (cgi->cgiContentLength, sizeof (char));
376                          identifiers[0] = 0;
377                          for (int k = 0; k < id->nodeNr; k++)
378                            {
379                              xmlChar *content = xmlNodeListGetString (doc,
380                                                                       id->nodeTab
381                                                                       [k]->
382                                                                       xmlChildrenNode,
383                                                                       1);
384                              if (strlen (identifiers) > 0)
385                                {
386                                  char *tmp = zStrdup (identifiers);
387                                  snprintf (identifiers,
388                                            strlen (tmp) +
389                                            xmlStrlen (content) + 2, "%s,%s",
390                                            tmp, content);
391                                  free (tmp);
392                                }
393                              else
394                                {
395                                  snprintf (identifiers,
396                                            xmlStrlen (content) + 1, "%s",
397                                            content);
398                                }
399                              xmlFree (content);
400                            }
401                          xmlXPathFreeObject (idptr);
402                          addToMap (tmpMap, "Identifier", identifiers);
403                          free (identifiers);
404                        }
405                    }
406                }
407              xmlFreeDoc (doc);
408              xmlCleanupParser ();
409            }
410          else
411            {
412              freeMap (&tmpMap);
413              free (tmpMap);
414              tmpMap = createMap ("not_valid", "true");
415            }
416
417          char *token, *saveptr;
418          token = strtok_r (cgi->cgiQueryString, "&", &saveptr);
419          while (token != NULL)
420            {
421              char *token1, *saveptr1;
422              char *name = NULL;
423              char *value = NULL;
424              token1 = strtok_r (token, "=", &saveptr1);
425              while (token1 != NULL)
426                {
427                  if (name == NULL)
428                    name = zStrdup (token1);
429                  else
430                    value = zStrdup (token1);
431                  token1 = strtok_r (NULL, "=", &saveptr1);
432                }
433              addToMap (tmpMap, name, value);
434              free (name);
435              free (value);
436              name = NULL;
437              value = NULL;
438              token = strtok_r (NULL, "&", &saveptr);
439            }
440
441        }
442
443      if (strncasecmp (cgi->cgiContentType, "multipart/form-data", 19) == 0)
444        {
445          map *tmp = getMap (tmpMap, "dataInputs");
446          if (tmp != NULL)
447            {
448              addToMap (tmpMap, "dataInputs",
449                        strstr (strQuery, "dataInputs=") + 11);
450            }
451        }
452
453      if (strQuery != NULL)
454        free (strQuery);
455
456      runRequest (&tmpMap,&cgi,request);
457
458  /**
459   * Required but can't be made after executing a process using POST requests.
460   */
461      if ( /*strncasecmp(cgiRequestMethod,"post",4)!=0 && count(tmpMap)!=1 && */ tmpMap != NULL)
462        {
463          freeMap (&tmpMap);
464          free (tmpMap);
465        }
466        // a verifier fait planter
467      cgiFreeResources (&cgi);
468
469      FCGX_Finish_r(request);
470      return 0;
471}
472
473
474
475int
476main (int argc, char *argv[])
477{
478  maps *main_config;
479  int max_requests, start_servers;
480  start_servers = 10;
481  max_requests= 100;
482  main_config = (maps *) malloc (MAP_SIZE);
483  conf_read ("main.cfg", main_config);
484  char ntmp[1024];
485#ifndef WIN32
486  getcwd (ntmp, 1024);
487#else
488  _getcwd (ntmp, 1024);
489#endif
490  char *rootDir = "/var/www/zoo-wps/cgi-bin";
491  int fork_status = fork();
492  if (fork_status == 0){
493    //child
494    int forker_pid = getpid();
495    init_services_conf (rootDir);
496    int sock = FCGX_OpenSocket(PATH_SOCKET, 1000);
497    FCGX_Init();
498    FCGX_Request request;
499    FCGX_InitRequest(&request, sock, 0);
500    int i;
501    int count_request = 0;
502    for (i = 0; i< start_servers; i++){
503        fork_status = fork();
504        if (fork_status == 0){
505            fprintf(stderr,"child %d \n",i);
506            fflush(stderr);
507            break;
508        }
509    }
510    while(1){
511        if (forker_pid != getpid()){
512            while(FCGX_Accept_r(&request) == 0){
513                process(&request);
514                count_request ++;
515                if (count_request >= max_requests){
516                    fprintf(stderr,"Max request stop process\n");
517                    fflush(stderr);
518                    exit(0);
519                }
520            }
521        }
522        else {
523            wait(0);
524            fprintf(stderr,"new child\n");
525            fflush(stderr);
526            fork();
527        }
528    }
529  }
530  else {
531 
532  while(1);
533
534
535
536  }
537 
538  return 0;
539}
540 
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