source: branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/request_parser.c @ 741

Last change on this file since 741 was 741, checked in by david, 9 years ago
  • Property svn:keywords set to Id
File size: 50.5 KB
Line 
1/*
2 * Author : Gérald FENOY
3 *
4 * Copyright (c) 2015 GeoLabs SARL
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#include "request_parser.h"
26#include "service_internal.h"
27#include "server_internal.h"
28#include "response_print.h"
29#include "caching.h"
30
31/**
32 * Apply XPath Expression on XML document.
33 *
34 * @param doc the XML Document
35 * @param search the XPath expression
36 * @return xmlXPathObjectPtr containing the resulting nodes set
37 */
38xmlXPathObjectPtr
39extractFromDoc (xmlDocPtr doc, const char *search)
40{
41  xmlXPathContextPtr xpathCtx;
42  xmlXPathObjectPtr xpathObj;
43  xpathCtx = xmlXPathNewContext (doc);
44  xpathObj = xmlXPathEvalExpression (BAD_CAST search, xpathCtx);
45  xmlXPathFreeContext (xpathCtx);
46  return xpathObj;
47}
48
49/**
50 * Create (or append to) an array valued maps value = "["",""]"
51 *
52 * @param m the conf maps containing the main.cfg settings
53 * @param mo the map to update
54 * @param mi the map to append
55 * @param elem the elements containing default definitions
56 * @return 0 on success, -1 on failure
57 */
58int appendMapsToMaps (maps * m, maps * mo, maps * mi, elements * elem){
59  maps *tmpMaps = getMaps (mo, mi->name);
60  map *tmap = getMapType (tmpMaps->content);
61  elements *el = getElements (elem, mi->name);
62  int hasEl = 1;
63  if (el == NULL)
64    hasEl = -1;
65  if (tmap == NULL)
66    {
67      if (hasEl > 0)
68        tmap = getMapType (el->defaults->content);
69    }
70 
71  map *testMap = NULL;
72  if (hasEl > 0)
73    {
74      testMap = getMap (el->content, "maxOccurs");
75    }
76  else
77    {
78      testMap = createMap ("maxOccurs", "unbounded");
79    }
80   
81  if (testMap != NULL)
82    {
83      if (strncasecmp (testMap->value, "unbounded", 9) != 0
84          && atoi (testMap->value) > 1)
85        {
86          addMapsArrayToMaps (&mo, mi, tmap->name);
87          map* nb=getMapFromMaps(mo,mi->name,"length");
88          if (nb!=NULL && atoi(nb->value)>atoi(testMap->value))
89            {
90              char emsg[1024];
91              sprintf (emsg,
92                       _("The maximum allowed occurrences for <%s> (%i) was exceeded."),
93                       mi->name, atoi (testMap->value));
94              errorException (m, emsg, "InternalError", NULL,NULL);
95              return -1;
96            }
97        }
98      else
99        {
100          if (strncasecmp (testMap->value, "unbounded", 9) == 0)
101            {
102              if (hasEl < 0)
103                {
104                  freeMap (&testMap);
105                  free (testMap);
106                }
107              if (addMapsArrayToMaps (&mo, mi, tmap->name) < 0)
108                {
109                  char emsg[1024];
110                  map *tmpMap = getMap (mi->content, "length");
111                  sprintf (emsg,
112                           _
113                           ("ZOO-Kernel was unable to load your data for %s position %s."),
114                           mi->name, tmpMap->value);
115                  errorException (m, emsg, "InternalError", NULL,NULL);
116                  return -1;
117                }
118            }
119          else
120            {
121              char emsg[1024];
122              sprintf (emsg,
123                       _
124                       ("The maximum allowed occurrences for <%s> is one."),
125                       mi->name);
126              errorException (m, emsg, "InternalError", NULL,NULL);
127              return -1;
128            }
129        }
130    }
131  return 0;
132}
133
134/**
135 * Make sure that each value encoded in base64 in a maps is decoded.
136 *
137 * @param in the maps containing the values
138 * @see readBase64
139 */
140void ensureDecodedBase64(maps **in){
141  maps* cursor=*in;
142  while(cursor!=NULL){
143    map *tmp=getMap(cursor->content,"encoding");
144    if(tmp!=NULL && strncasecmp(tmp->value,"base64",6)==0){
145      tmp=getMap(cursor->content,"value");
146      readBase64(&tmp);
147      addToMap(cursor->content,"base64_value",tmp->value);
148      int size=0;
149      char *s=strdup(tmp->value);
150      free(tmp->value);
151      tmp->value=base64d(s,strlen(s),&size);
152      free(s);
153      char sizes[1024];
154      sprintf(sizes,"%d",size);
155      addToMap(cursor->content,"size",sizes);
156    }
157    map* length=getMap(cursor->content,"length");
158    if(length!=NULL){
159      int len=atoi(length->value);
160      for(int i=1;i<len;i++){
161        tmp=getMapArray(cursor->content,"encoding",i);
162        if(tmp!=NULL && strncasecmp(tmp->value,"base64",6)==0){
163          char key[17];
164          sprintf(key,"base64_value_%d",i);
165          tmp=getMapArray(cursor->content,"value",i);
166          readBase64(&tmp);
167          addToMap(cursor->content,key,tmp->value);
168          int size=0;
169          char *s=strdup(tmp->value);
170          free(tmp->value);
171          tmp->value=base64d(s,strlen(s),&size);
172          free(s);
173          char sizes[1024];
174          sprintf(sizes,"%d",size);
175          sprintf(key,"size_%d",i);
176          addToMap(cursor->content,key,sizes);
177        }
178      }
179    }
180    cursor=cursor->next;
181  }
182}
183
184/**
185 * Parse inputs provided as KVP and store them in a maps.
186 *
187 * @param main_conf the conf maps containing the main.cfg settings
188 * @param s the service
189 * @param request_inputs the map storing KVP raw value
190 * @param request_output the maps to store the KVP pairs
191 * @param hInternet the HINTERNET queue to add potential requests
192 * @return 0 on success, -1 on failure
193 */
194int kvpParseInputs(maps** main_conf,service* s,map *request_inputs,maps** request_output,HINTERNET* hInternet){
195  // Parsing inputs provided as KVP
196  maps *tmpmaps = *request_output;
197  map* r_inputs = getMap (request_inputs, "DataInputs");
198  char* cursor_input;
199  if (r_inputs != NULL){
200    //snprintf (cursor_input, 40960, "%s", r_inputs->value);
201    if(strstr(r_inputs->value,"=")==NULL)
202      cursor_input = url_decode (r_inputs->value);
203    else
204      cursor_input = zStrdup (r_inputs->value);
205    int j = 0;
206
207    // Put each DataInputs into the inputs_as_text array
208    char *pToken;
209    pToken = strtok (cursor_input, ";");
210    char **inputs_as_text = (char **) malloc (100 * sizeof (char *));
211    if (inputs_as_text == NULL)
212      {
213        free(cursor_input);
214        return errorException (*main_conf, _("Unable to allocate memory."),
215                               "InternalError", NULL,NULL);
216      }
217    int i = 0;
218    while (pToken != NULL)
219      {
220        inputs_as_text[i] =
221          (char *) malloc ((strlen (pToken) + 1) * sizeof (char));
222        if (inputs_as_text[i] == NULL)
223          {
224            free(cursor_input);
225            return errorException (*main_conf, _("Unable to allocate memory."),
226                                   "InternalError", NULL,NULL);
227          }
228        snprintf (inputs_as_text[i], strlen (pToken) + 1, "%s", pToken);
229        pToken = strtok (NULL, ";");
230        i++;
231      }
232       
233    for (j = 0; j < i; j++)
234      {
235        char *tmp = zStrdup (inputs_as_text[j]);
236        free (inputs_as_text[j]);
237        char *tmpc;
238        tmpc = strtok (tmp, "@");
239        while (tmpc != NULL)
240          {
241            char *tmpv = strstr (tmpc, "=");
242            char tmpn[256];
243            memset (tmpn, 0, 256);
244            if (tmpv != NULL)
245              {
246                strncpy (tmpn, tmpc,
247                         (strlen (tmpc) - strlen (tmpv)) * sizeof (char));
248                tmpn[strlen (tmpc) - strlen (tmpv)] = 0;
249              }
250            else
251              {
252                strncpy (tmpn, tmpc, strlen (tmpc) * sizeof (char));
253                tmpn[strlen (tmpc)] = 0;
254              }
255            if (tmpmaps == NULL)
256              {
257                tmpmaps = (maps *) malloc (MAPS_SIZE);
258                if (tmpmaps == NULL)
259                  {
260                    free(cursor_input);
261                    return errorException (*main_conf,
262                                           _("Unable to allocate memory."),
263                                           "InternalError", NULL,NULL);
264                  }
265                tmpmaps->name = zStrdup (tmpn);
266                if (tmpv != NULL)
267                  {
268                    char *tmpvf = url_decode (tmpv + 1);
269                    tmpmaps->content = createMap ("value", tmpvf);
270                    free (tmpvf);
271                  }
272                else
273                  tmpmaps->content = createMap ("value", "Reference");
274                tmpmaps->next = NULL;
275              }
276            tmpc = strtok (NULL, "@");
277            while (tmpc != NULL)
278              {
279                char *tmpv1 = strstr (tmpc, "=");
280                char tmpn1[1024];
281                memset (tmpn1, 0, 1024);
282                if (tmpv1 != NULL)
283                  {
284                    strncpy (tmpn1, tmpc, strlen (tmpc) - strlen (tmpv1));
285                    tmpn1[strlen (tmpc) - strlen (tmpv1)] = 0;
286                    addToMap (tmpmaps->content, tmpn1, tmpv1 + 1);
287                  }
288                else
289                  {
290                    strncpy (tmpn1, tmpc, strlen (tmpc));
291                    tmpn1[strlen (tmpc)] = 0;
292                    map *lmap = getLastMap (tmpmaps->content);
293                    char *tmpValue =
294                      (char *) malloc ((strlen (tmpv) + strlen (tmpc) + 1) *
295                                       sizeof (char));
296                    sprintf (tmpValue, "%s@%s", tmpv + 1, tmpc);
297                    free (lmap->value);
298                    lmap->value = zStrdup (tmpValue);
299                    free (tmpValue);
300                    tmpc = strtok (NULL, "@");
301                    continue;
302                  }
303                if (strcmp (tmpn1, "xlink:href") != 0)
304                  addToMap (tmpmaps->content, tmpn1, tmpv1 + 1);
305                else if (tmpv1 != NULL)
306                  {
307                    char *tmpx2 = url_decode (tmpv1 + 1);
308                    if (strncasecmp (tmpx2, "http://", 7) != 0 &&
309                        strncasecmp (tmpx2, "ftp://", 6) != 0 &&
310                        strncasecmp (tmpx2, "https://", 8) != 0)
311                      {
312                        char emsg[1024];
313                        sprintf (emsg,
314                                 _
315                                 ("Unable to find a valid protocol to download the remote file %s"),
316                                 tmpv1 + 1);
317                        free(cursor_input);
318                        return errorException (*main_conf, emsg, "InternalError", NULL,NULL);
319                      }
320                    addToMap (tmpmaps->content, tmpn1, tmpx2);
321                      if (loadRemoteFile
322                          (&*main_conf, &tmpmaps->content, hInternet, tmpx2) < 0)
323                        {
324                          free(cursor_input);
325                          return errorException (*main_conf, "Unable to fetch any ressource", "InternalError", NULL,NULL);
326                        }
327                     
328                    free (tmpx2);
329                    addIntToMap (tmpmaps->content, "Order", hInternet->nb);
330                    addToMap (tmpmaps->content, "Reference", tmpv1 + 1);
331                  }
332                tmpc = strtok (NULL, "@");
333              }
334            if (*request_output == NULL)
335              *request_output = dupMaps (&tmpmaps);
336            else
337              {
338                maps *testPresence =
339                  getMaps (*request_output, tmpmaps->name);
340                if (testPresence != NULL)
341                  {
342                    elements *elem =
343                      getElements (s->inputs, tmpmaps->name);
344                    if (elem != NULL)
345                      {
346                        if (appendMapsToMaps
347                            (*main_conf, *request_output, tmpmaps,
348                             elem) < 0)
349                          {
350                            free(cursor_input);
351                            return errorException (*main_conf, "Unable to append maps", "InternalError", NULL,NULL);
352                          }
353                      }
354                  }
355                else
356                  addMapsToMaps (request_output, tmpmaps);
357              }
358            freeMaps (&tmpmaps);
359            free (tmpmaps);
360            tmpmaps = NULL;
361            free (tmp);
362          }
363      }
364    free (inputs_as_text);
365    free(cursor_input);
366  }
367  return 1;
368}
369
370/**
371 * Parse outputs provided as KVP and store them in a maps.
372 *
373 * @param main_conf the conf maps containing the main.cfg settings
374 * @param request_inputs the map storing KVP raw value
375 * @param request_output the maps to store the KVP pairs
376 * @return 0 on success, -1 on failure
377 */
378int kvpParseOutputs(maps** main_conf,map *request_inputs,maps** request_output){
379  /**
380   * Parsing outputs provided as KVP
381   */
382  map *r_inputs = NULL;
383  r_inputs = getMap (request_inputs, "ResponseDocument");
384  if (r_inputs == NULL)
385    r_inputs = getMap (request_inputs, "RawDataOutput");
386
387  if (r_inputs != NULL)
388    {
389      char *cursor_output = zStrdup (r_inputs->value);
390      int j = 0;
391
392      /**
393       * Put each Output into the outputs_as_text array
394       */
395      char *pToken;
396      maps *tmp_output = NULL;
397      pToken = strtok (cursor_output, ";");
398      char **outputs_as_text = (char **) malloc (128 * sizeof (char *));
399      if (outputs_as_text == NULL)
400        {
401          free(cursor_output);
402          return errorException (*main_conf, _("Unable to allocate memory"),
403                                 "InternalError", NULL,NULL);
404        }
405      int i = 0;
406      while (pToken != NULL)
407        {
408          outputs_as_text[i] =
409            (char *) malloc ((strlen (pToken) + 1) * sizeof (char));
410          if (outputs_as_text[i] == NULL)
411            {
412              free(cursor_output);
413              return errorException (*main_conf, _("Unable to allocate memory"),
414                                     "InternalError", NULL,NULL);
415            }
416          snprintf (outputs_as_text[i], strlen (pToken) + 1, "%s",
417                    pToken);
418          pToken = strtok (NULL, ";");
419          i++;
420        }
421      for (j = 0; j < i; j++)
422        {
423          char *tmp = zStrdup (outputs_as_text[j]);
424          free (outputs_as_text[j]);
425          char *tmpc;
426          tmpc = strtok (tmp, "@");
427          int k = 0;
428          while (tmpc != NULL)
429            {
430              if (k == 0)
431                {
432                  if (tmp_output == NULL)
433                    {
434                      tmp_output = (maps *) malloc (MAPS_SIZE);
435                      if (tmp_output == NULL)
436                        {
437                          free(cursor_output);
438                          return errorException (*main_conf,
439                                                 _
440                                                 ("Unable to allocate memory."),
441                                                 "InternalError", NULL,NULL);
442                        }
443                      tmp_output->name = zStrdup (tmpc);
444                      tmp_output->content = NULL;
445                      tmp_output->next = NULL;
446                    }
447                }
448              else
449                {
450                  char *tmpv = strstr (tmpc, "=");
451                  char tmpn[256];
452                  memset (tmpn, 0, 256);
453                  strncpy (tmpn, tmpc,
454                           (strlen (tmpc) -
455                            strlen (tmpv)) * sizeof (char));
456                  tmpn[strlen (tmpc) - strlen (tmpv)] = 0;
457                  if (tmp_output->content == NULL)
458                    {
459                      tmp_output->content = createMap (tmpn, tmpv + 1);
460                      tmp_output->content->next = NULL;
461                    }
462                  else
463                    addToMap (tmp_output->content, tmpn, tmpv + 1);
464                }
465              k++;
466              tmpc = strtok (NULL, "@");
467            }
468          if (*request_output == NULL)
469            *request_output = dupMaps (&tmp_output);
470          else
471            addMapsToMaps (request_output, tmp_output);
472          freeMaps (&tmp_output);
473          free (tmp_output);
474          tmp_output = NULL;
475          free (tmp);
476        }
477      free (outputs_as_text);
478      free(cursor_output);
479    }
480  return 1;
481}
482
483/**
484 * Parse inputs from XML nodes and store them in a maps.
485 *
486 * @param main_conf the conf maps containing the main.cfg settings
487 * @param s the service
488 * @param request_output the maps to store the KVP pairs
489 * @param doc the xmlDocPtr containing the original request
490 * @param nodes the input nodes array
491 * @param hInternet the HINTERNET queue to add potential requests
492 * @return 0 on success, -1 on failure
493 */
494int xmlParseInputs(maps** main_conf,service* s,maps** request_output,xmlDocPtr doc,xmlNodeSet* nodes,HINTERNET* hInternet){
495  int k = 0;
496  int l = 0;
497  map* version=getMapFromMaps(*main_conf,"main","rversion");
498  int vid=getVersionId(version->value);
499  for (k=0; k < nodes->nodeNr; k++)
500    {
501      maps *tmpmaps = NULL;
502      xmlNodePtr cur = nodes->nodeTab[k];
503
504      if (nodes->nodeTab[k]->type == XML_ELEMENT_NODE)
505        {
506          // A specific Input node.
507          if(vid==1){
508            tmpmaps = (maps *) malloc (MAPS_SIZE);
509            xmlChar *val = xmlGetProp (cur, BAD_CAST "id");
510            tmpmaps->name = zStrdup ((char *) val);
511            tmpmaps->content = NULL;
512            tmpmaps->next = NULL;
513          }
514
515          xmlNodePtr cur2 = cur->children;
516          while (cur2 != NULL)
517            {
518              while (cur2 != NULL && cur2->type != XML_ELEMENT_NODE)
519                cur2 = cur2->next;
520              if (cur2 == NULL)
521                break;
522              // Indentifier
523              if (xmlStrncasecmp
524                  (cur2->name, BAD_CAST "Identifier",
525                   xmlStrlen (cur2->name)) == 0)
526                {
527                  xmlChar *val =
528                    xmlNodeListGetString (doc, cur2->xmlChildrenNode, 1);
529                  if (tmpmaps == NULL)
530                    {
531                      tmpmaps = (maps *) malloc (MAPS_SIZE);
532                      if (tmpmaps == NULL)
533                        {
534                          return errorException (*main_conf,
535                                                 _
536                                                 ("Unable to allocate memory."),
537                                                 "InternalError", NULL,NULL);
538                        }
539                      tmpmaps->name = zStrdup ((char *) val);
540                      tmpmaps->content = NULL;
541                      tmpmaps->next = NULL;
542                    }
543                  xmlFree (val);
544                }
545              // Title, Asbtract
546              if (xmlStrncasecmp
547                  (cur2->name, BAD_CAST "Title",
548                   xmlStrlen (cur2->name)) == 0
549                  || xmlStrncasecmp (cur2->name, BAD_CAST "Abstract",
550                                     xmlStrlen (cur2->name)) == 0)
551                {
552                  xmlChar *val =
553                    xmlNodeListGetString (doc, cur2->xmlChildrenNode, 1);
554                  if (tmpmaps == NULL)
555                    {
556                      tmpmaps = (maps *) malloc (MAPS_SIZE);
557                      if (tmpmaps == NULL)
558                        {
559                          return errorException (*main_conf,
560                                                 _
561                                                 ("Unable to allocate memory."),
562                                                 "InternalError", NULL,NULL);
563                        }
564                      tmpmaps->name = zStrdup ("missingIndetifier");
565                      tmpmaps->content =
566                        createMap ((char *) cur2->name, (char *) val);
567                      tmpmaps->next = NULL;
568                    }
569                  else
570                    {
571                      if (tmpmaps->content != NULL)
572                        addToMap (tmpmaps->content,
573                                  (char *) cur2->name, (char *) val);
574                      else
575                        tmpmaps->content =
576                          createMap ((char *) cur2->name, (char *) val);
577                    }
578                  xmlFree (val);
579                }
580              // InputDataFormChoice (Reference or Data ?)
581              if (xmlStrcasecmp (cur2->name, BAD_CAST "Reference") == 0)
582                {
583                  // Get every attribute from a Reference node
584                  // mimeType, encoding, schema, href, method
585                  // Header and Body gesture should be added here
586                  const char *refs[5] =
587                    { "mimeType", "encoding", "schema", "method",
588                      "href"
589                    };
590                  for (l = 0; l < 5; l++)
591                    {
592                      xmlChar *val = xmlGetProp (cur2, BAD_CAST refs[l]);
593                      if (val != NULL && xmlStrlen (val) > 0)
594                        {
595                          if (tmpmaps->content != NULL)
596                            addToMap (tmpmaps->content, refs[l],
597                                      (char *) val);
598                          else
599                            tmpmaps->content =
600                              createMap (refs[l], (char *) val);
601
602                          map *ltmp = getMap (tmpmaps->content, "method");
603                          if (l == 4 )
604                            {
605                              if ((ltmp==NULL || strncmp (ltmp->value, "POST",4) != 0))
606                                {
607                                  if (loadRemoteFile
608                                      (main_conf, &tmpmaps->content, hInternet,
609                                       (char *) val) != 0)
610                                    {
611                                      return errorException (*main_conf,
612                                                             _("Unable to add a request in the queue."),
613                                                             "InternalError",
614                                                             NULL,NULL);
615                                    }
616                                  addIntToMap (tmpmaps->content, "Order", hInternet->nb);
617                                }
618                              addToMap (tmpmaps->content, "Reference", (char*) val);
619                            }
620                        }
621                      xmlFree (val);
622                    }
623                  // Parse Header and Body from Reference
624                  xmlNodePtr cur3 = cur2->children;
625                  while (cur3 != NULL)
626                    {
627                      while (cur3 != NULL
628                             && cur3->type != XML_ELEMENT_NODE)
629                        cur3 = cur3->next;
630                      if (cur3 == NULL)
631                        break;
632                      if (xmlStrcasecmp (cur3->name, BAD_CAST "Header") ==
633                          0)
634                        {
635                          const char *ha[2];
636                          ha[0] = "key";
637                          ha[1] = "value";
638                          int hai;
639                          char *has;
640                          char *key;
641                          for (hai = 0; hai < 2; hai++)
642                            {
643                              xmlChar *val =
644                                xmlGetProp (cur3, BAD_CAST ha[hai]);
645#ifdef POST_DEBUG
646                              fprintf (stderr, "%s = %s\n", ha[hai],
647                                       (char *) val);
648#endif
649                              if (hai == 0)
650                                {
651                                  key = zStrdup ((char *) val);
652                                }
653                              else
654                                {
655                                  has =
656                                    (char *)
657                                    malloc ((4 + xmlStrlen (val) +
658                                             strlen (key)) *
659                                            sizeof (char));
660                                  if (has == NULL)
661                                    {
662                                      return errorException (*main_conf,
663                                                             _
664                                                             ("Unable to allocate memory."),
665                                                             "InternalError",
666                                                             NULL,NULL);
667                                    }
668                                  snprintf (has,
669                                            (3 + xmlStrlen (val) +
670                                             strlen (key)), "%s: %s", key,
671                                            (char *) val);
672                                  free (key);
673                                }
674                              xmlFree (val);
675                            }
676                if (has != NULL){
677                            hInternet->ihandle[hInternet->nb].header = NULL;
678                            hInternet->ihandle[hInternet->nb].header =
679                              curl_slist_append (hInternet->ihandle
680                                                 [hInternet->nb].header,
681                                                 has);
682                            free (has);
683                }
684                        }
685                      else
686                        {
687#ifdef POST_DEBUG
688                          fprintf (stderr,
689                                   "Try to fetch the body part of the request ...\n");
690#endif
691                          if (xmlStrcasecmp (cur3->name, BAD_CAST "Body")
692                              == 0)
693                            {
694#ifdef POST_DEBUG
695                              fprintf (stderr, "Body part found (%s) !!!\n",
696                                       (char *) cur3->content);
697#endif
698                              char *tmp = NULL;
699                              xmlNodePtr cur4 = cur3->children;
700                              while (cur4 != NULL)
701                                {
702                                  while (cur4 && cur4 != NULL && cur4->type && cur4->type != XML_ELEMENT_NODE){
703                                    if(cur4->next)
704                                      cur4 = cur4->next;
705                                    else
706                                      cur4 = NULL;
707                                  }
708                                  if(cur4 != NULL) {
709                                    xmlDocPtr bdoc =
710                                      xmlNewDoc (BAD_CAST "1.0");
711                                    bdoc->encoding =
712                                      xmlCharStrdup ("UTF-8");
713                                    xmlDocSetRootElement (bdoc, cur4);
714                                    xmlChar *btmps;
715                                    int bsize;
716                                    // TODO : check for encoding defined in the input
717                                    xmlDocDumpFormatMemoryEnc(bdoc, &btmps, &bsize, "UTF-8", 0);
718                                    if (btmps != NULL){
719                                      tmp = (char *) malloc ((bsize + 1) * sizeof (char));
720
721                                      sprintf (tmp, "%s", (char*) btmps);
722                                         
723                                      xmlFreeDoc (bdoc);
724                                         
725                                      map *btmp =
726                                        getMap (tmpmaps->content, "Reference");
727                                      if (btmp != NULL)
728                                        {
729                                          addRequestToQueue(main_conf,hInternet,(char *) btmp->value,false);
730                                          InternetOpenUrl (hInternet,
731                                                           btmp->value,
732                                                           tmp,
733                                                           xmlStrlen(btmps),
734                                                           INTERNET_FLAG_NO_CACHE_WRITE,
735                                                           0);
736                                          addIntToMap (tmpmaps->content, "Order", hInternet->nb);
737                                        }
738                                      xmlFree (btmps);
739                                      free (tmp);
740                                      break;
741                                    }
742                                  }
743                                  cur4 = cur4->next;
744                                }
745                            }
746                          else
747                            if (xmlStrcasecmp
748                                (cur3->name,
749                                 BAD_CAST "BodyReference") == 0)
750                              {
751                                xmlChar *val =
752                                  xmlGetProp (cur3, BAD_CAST "href");
753                                HINTERNET bInternet, res1, res;
754                                bInternet = InternetOpen (
755#ifndef WIN32
756                                                          (LPCTSTR)
757#endif
758                                                          "ZooWPSClient\0",
759                                                          INTERNET_OPEN_TYPE_PRECONFIG,
760                                                          NULL, NULL, 0);
761                                if (!CHECK_INET_HANDLE (bInternet))
762                                  fprintf (stderr,
763                                           "WARNING : bInternet handle failed to initialize");
764                                bInternet.waitingRequests[0] =
765                                  strdup ((char *) val);
766                                res1 =
767                                  InternetOpenUrl (&bInternet,
768                                                   bInternet.waitingRequests
769                                                   [0], NULL, 0,
770                                                   INTERNET_FLAG_NO_CACHE_WRITE,
771                                                   0);
772                                processDownloads (&bInternet);
773                                char *tmp =
774                                  (char *)
775                                  malloc ((bInternet.ihandle[0].nDataLen +
776                                           1) * sizeof (char));
777                                if (tmp == NULL)
778                                  {
779                                    return errorException (*main_conf,
780                                                           _
781                                                           ("Unable to allocate memory."),
782                                                           "InternalError",
783                                                           NULL,NULL);
784                                  }
785                                size_t bRead;
786                                InternetReadFile (bInternet.ihandle[0],
787                                                  (LPVOID) tmp,
788                                                  bInternet.
789                                                  ihandle[0].nDataLen,
790                                                  &bRead);
791                                tmp[bInternet.ihandle[0].nDataLen] = 0;
792                                InternetCloseHandle (&bInternet);
793                                map *btmp =
794                                  getMap (tmpmaps->content, "href");
795                                if (btmp != NULL)
796                                  {
797                                    addRequestToQueue(main_conf,hInternet,(char *) btmp->value,false);
798
799                                    res =
800                                      InternetOpenUrl (hInternet,
801                                                       btmp->value,
802                                                       tmp,
803                                                       strlen(tmp),
804                                                       INTERNET_FLAG_NO_CACHE_WRITE,
805                                                       0);
806                                    addIntToMap (tmpmaps->content, "Order", hInternet->nb);
807                                  }
808                                free (tmp);
809                              }
810                        }
811                      cur3 = cur3->next;
812                    }
813                }
814              else if (xmlStrcasecmp (cur2->name, BAD_CAST "Data") == 0)
815                {
816                  xmlNodePtr cur4 = cur2->children;
817                  if(vid==1){
818                    // Get every dataEncodingAttributes from a Data node:
819                    // mimeType, encoding, schema
820                    const char *coms[3] =
821                      { "mimeType", "encoding", "schema" };
822                    for (l = 0; l < 3; l++){
823                      xmlChar *val =
824                          xmlGetProp (cur4, BAD_CAST coms[l]);
825                        if (val != NULL && strlen ((char *) val) > 0){
826                          if (tmpmaps->content != NULL)
827                            addToMap (tmpmaps->content,coms[l],(char *) val);
828                          else
829                            tmpmaps->content =
830                              createMap (coms[l],(char *) val);
831                        }
832                        xmlFree (val);
833                    }
834                    while (cur4 != NULL){
835                      while(cur4 != NULL && 
836                            cur4->type != XML_CDATA_SECTION_NODE &&
837                            cur4->type != XML_TEXT_NODE)
838                        cur4=cur4->next;
839                      if(cur4!=NULL){
840                        if(cur4->content!=NULL)
841                          if (tmpmaps->content != NULL)
842                            addToMap (tmpmaps->content, "value",
843                                      (char *) cur4->content);
844                          else
845                            tmpmaps->content =
846                              createMap ("value", (char *) cur4->content);
847                        cur4=cur4->next;
848                      }
849                    }
850                  }
851
852
853                  while (cur4 != NULL)
854                    {
855                      while (cur4 != NULL
856                             && cur4->type != XML_ELEMENT_NODE)
857                        cur4 = cur4->next;
858                      if (cur4 == NULL)
859                        break;
860                      if (xmlStrcasecmp
861                          (cur4->name, BAD_CAST "LiteralData") == 0)
862                        {
863                          // Get every attribute from a LiteralData node
864                          // dataType , uom
865                          char *list[2];
866                          list[0] = zStrdup ("dataType");
867                          list[1] = zStrdup ("uom");
868                          for (l = 0; l < 2; l++)
869                            {
870                              xmlChar *val =
871                                xmlGetProp (cur4, BAD_CAST list[l]);
872                              if (val != NULL
873                                  && strlen ((char *) val) > 0)
874                                {
875                                  if (tmpmaps->content != NULL)
876                                    addToMap (tmpmaps->content, list[l],
877                                              (char *) val);
878                                  else
879                                    tmpmaps->content =
880                                      createMap (list[l], (char *) val);
881                                }
882                              xmlFree (val);
883                              free (list[l]);
884                            }
885                        }
886                      else
887                        if (xmlStrcasecmp
888                            (cur4->name, BAD_CAST "ComplexData") == 0)
889                          {
890                            // Get every attribute from a Reference node
891                            // mimeType, encoding, schema
892                            const char *coms[3] =
893                              { "mimeType", "encoding", "schema" };
894                            for (l = 0; l < 3; l++)
895                              {
896                                xmlChar *val =
897                                  xmlGetProp (cur4, BAD_CAST coms[l]);
898                                if (val != NULL
899                                    && strlen ((char *) val) > 0)
900                                  {
901                                    if (tmpmaps->content != NULL)
902                                      addToMap (tmpmaps->content, coms[l],
903                                                (char *) val);
904                                    else
905                                      tmpmaps->content =
906                                        createMap (coms[l], (char *) val);
907                                  }
908                                xmlFree (val);
909                              }
910                          }
911
912                      map *test = getMap (tmpmaps->content, "encoding");
913
914                      if (test == NULL)
915                        { 
916                          if (tmpmaps->content != NULL)
917                            addToMap (tmpmaps->content, "encoding",
918                                      "utf-8");
919                          else
920                            tmpmaps->content =
921                              createMap ("encoding", "utf-8");
922                          test = getMap (tmpmaps->content, "encoding");
923                        }
924
925                      if (strcasecmp (test->value, "base64") != 0)
926                        { 
927                          xmlChar *mv = xmlNodeListGetString (doc,
928                                                              cur4->xmlChildrenNode,
929                                                              1);
930                          map *ltmp =
931                            getMap (tmpmaps->content, "mimeType");
932                          if (mv == NULL
933                              ||
934                              (xmlStrcasecmp
935                               (cur4->name, BAD_CAST "ComplexData") == 0
936                               && (ltmp == NULL
937                                   || strncasecmp (ltmp->value,
938                                                   "text/xml", 8) == 0)))
939                            {
940                              xmlDocPtr doc1 = xmlNewDoc (BAD_CAST "1.0");
941                              int buffersize;
942                              xmlNodePtr cur5 = cur4->children;
943                              while (cur5 != NULL
944                                     && cur5->type != XML_ELEMENT_NODE
945                                     && cur5->type != XML_CDATA_SECTION_NODE)
946                                cur5 = cur5->next;
947                              if (cur5 != NULL
948                                  && cur5->type != XML_CDATA_SECTION_NODE)
949                                {
950                                  xmlDocSetRootElement (doc1, cur5);
951                                  xmlDocDumpFormatMemoryEnc (doc1, &mv,
952                                                             &buffersize,
953                                                             "utf-8", 0);
954                                  char size[1024];
955                                  sprintf (size, "%d", buffersize);
956                                  addToMap (tmpmaps->content, "size",
957                                            size);
958                                  xmlFreeDoc (doc1);
959                                }
960                              else
961                                {
962                                  if (cur5 != NULL
963                                      && cur5->type == XML_CDATA_SECTION_NODE){
964                                    xmlDocPtr doc2 = xmlParseMemory((const char*)cur5->content,xmlStrlen(cur5->content));
965                                    xmlDocSetRootElement (doc1,xmlDocGetRootElement(doc2));
966                                    xmlDocDumpFormatMemoryEnc (doc1, &mv,
967                                                               &buffersize,
968                                                               "utf-8", 0);
969                                    addIntToMap(tmpmaps->content, "size",buffersize);
970                    xmlFreeDoc (doc2);
971                                    xmlFreeDoc (doc1);
972                                  }
973                                }
974                            }else{
975                            xmlNodePtr cur5 = cur4->children;
976                            while (cur5 != NULL
977                                   && cur5->type != XML_CDATA_SECTION_NODE)
978                              cur5 = cur5->next;
979                            if (cur5 != NULL
980                                && cur5->type == XML_CDATA_SECTION_NODE){
981                              xmlFree(mv);
982                              mv=xmlStrdup(cur5->content);
983                            }
984                          }
985                          if (mv != NULL)
986                            {
987                              addToMap (tmpmaps->content, "value",
988                                        (char *) mv);
989                              xmlFree (mv);
990                            }
991                        }
992                      else
993                        {
994                          xmlChar *tmp = xmlNodeListGetRawString (doc,
995                                                                  cur4->xmlChildrenNode,
996                                                                  0);
997                          addToMap (tmpmaps->content, "value",
998                                    (char *) tmp);
999                          xmlFree (tmp);
1000                        }
1001                      cur4 = cur4->next;
1002                    }
1003                }
1004              cur2 = cur2->next;
1005              while (cur2 != NULL && cur2->type != XML_ELEMENT_NODE){
1006                cur2 = cur2->next;
1007              }
1008            }
1009          {
1010            maps *testPresence =
1011              getMaps (*request_output, tmpmaps->name);
1012            if (testPresence != NULL)
1013              {
1014                elements *elem = getElements (s->inputs, tmpmaps->name);
1015                if (elem != NULL)
1016                  {
1017                    if (appendMapsToMaps
1018                        (*main_conf, *request_output, tmpmaps, elem) < 0)
1019                      {
1020                        return errorException (*main_conf,
1021                                               _("Unable to append maps to maps."),
1022                                               "InternalError",
1023                                               NULL,NULL);
1024                      }
1025                  }
1026              }
1027            else
1028              addMapsToMaps (request_output, tmpmaps);
1029          }
1030          freeMaps (&tmpmaps);
1031          free (tmpmaps);
1032          tmpmaps = NULL;
1033        }
1034    }
1035  return 1;
1036}
1037
1038/**
1039 * Parse outputs from XML nodes and store them in a maps (WPS version 2.0.0).
1040 *
1041 * @param main_conf the conf maps containing the main.cfg settings
1042 * @param request_inputs the map storing KVP raw value
1043 * @param request_output the maps to store the KVP pairs
1044 * @param doc the xmlDocPtr containing the original request
1045 * @param cur the xmlNodePtr corresponding to the ResponseDocument or RawDataOutput XML node
1046 * @param raw true if the node is RawDataOutput, false in case of ResponseDocument
1047 * @return 0 on success, -1 on failure
1048 */
1049int xmlParseOutputs2(maps** main_conf,map** request_inputs,maps** request_output,xmlDocPtr doc,xmlNodeSet* nodes){
1050  int k = 0;
1051  int l = 0;
1052  for (k=0; k < nodes->nodeNr; k++){
1053    maps *tmpmaps = NULL;
1054    xmlNodePtr cur = nodes->nodeTab[k];
1055    if (cur->type == XML_ELEMENT_NODE){
1056      maps *tmpmaps = (maps *) malloc (MAPS_SIZE);
1057      xmlChar *val = xmlGetProp (cur, BAD_CAST "id");
1058      if(val!=NULL)
1059        tmpmaps->name = zStrdup ((char*)val);
1060      else
1061        tmpmaps->name = zStrdup ("unknownIdentifier");
1062      tmpmaps->content = NULL;
1063      tmpmaps->next = NULL;
1064      const char ress[4][13] =
1065        { "mimeType", "encoding", "schema", "transmission" };
1066      for (l = 0; l < 4; l++){
1067        val = xmlGetProp (cur, BAD_CAST ress[l]);
1068        if (val != NULL && strlen ((char *) val) > 0)
1069          {
1070            if (tmpmaps->content != NULL)
1071              addToMap (tmpmaps->content, ress[l],
1072                        (char *) val);
1073            else
1074              tmpmaps->content =
1075                createMap (ress[l], (char *) val);
1076            if(l==3 && strncasecmp((char*)val,"reference",xmlStrlen(val))==0)
1077              addToMap (tmpmaps->content,"asReference","true");
1078          }
1079        xmlFree (val);
1080      }
1081      if (*request_output == NULL)
1082        *request_output = dupMaps(&tmpmaps);
1083      else
1084        addMapsToMaps(request_output,tmpmaps);
1085    }
1086  }
1087}
1088
1089/**
1090 * Parse outputs from XML nodes and store them in a maps.
1091 *
1092 * @param main_conf the conf maps containing the main.cfg settings
1093 * @param request_inputs the map storing KVP raw value
1094 * @param request_output the maps to store the KVP pairs
1095 * @param doc the xmlDocPtr containing the original request
1096 * @param cur the xmlNodePtr corresponding to the ResponseDocument or RawDataOutput XML node
1097 * @param raw true if the node is RawDataOutput, false in case of ResponseDocument
1098 * @return 0 on success, -1 on failure
1099 */
1100int xmlParseOutputs(maps** main_conf,map** request_inputs,maps** request_output,xmlDocPtr doc,xmlNodePtr cur,bool raw){
1101  int l=0;
1102  if( raw == true)
1103    {
1104      addToMap (*request_inputs, "RawDataOutput", "");
1105      if (cur->type == XML_ELEMENT_NODE)
1106        {
1107
1108          maps *tmpmaps = (maps *) malloc (MAPS_SIZE);
1109          if (tmpmaps == NULL)
1110            {
1111              return errorException (*main_conf, _("Unable to allocate memory."),
1112                                     "InternalError", NULL,NULL);
1113            }
1114          tmpmaps->name = zStrdup ("unknownIdentifier");
1115          tmpmaps->content = NULL;
1116          tmpmaps->next = NULL;
1117
1118          // Get every attribute from a RawDataOutput node
1119          // mimeType, encoding, schema, uom
1120          const char *outs[4] =
1121            { "mimeType", "encoding", "schema", "uom" };
1122          for (l = 0; l < 4; l++)
1123            {
1124              xmlChar *val = xmlGetProp (cur, BAD_CAST outs[l]);
1125              if (val != NULL)
1126                {
1127                  if (strlen ((char *) val) > 0)
1128                    {
1129                      if (tmpmaps->content != NULL)
1130                        addToMap (tmpmaps->content, outs[l],
1131                                  (char *) val);
1132                      else
1133                        tmpmaps->content =
1134                          createMap (outs[l], (char *) val);
1135                    }
1136                  xmlFree (val);
1137                }
1138            }
1139          xmlNodePtr cur2 = cur->children;
1140          while (cur2 != NULL && cur2->type != XML_ELEMENT_NODE)
1141            cur2 = cur2->next;
1142          while (cur2 != NULL)
1143            {
1144              if (xmlStrncasecmp
1145                  (cur2->name, BAD_CAST "Identifier",
1146                   xmlStrlen (cur2->name)) == 0)
1147                {
1148                  xmlChar *val =
1149                    xmlNodeListGetString (NULL, cur2->xmlChildrenNode, 1);
1150                  free (tmpmaps->name);
1151                  tmpmaps->name = zStrdup ((char *) val);
1152                  xmlFree (val);
1153                }
1154              cur2 = cur2->next;
1155              while (cur2 != NULL && cur2->type != XML_ELEMENT_NODE)
1156                cur2 = cur2->next;
1157            }
1158          if (*request_output == NULL)
1159            *request_output = dupMaps (&tmpmaps);
1160          else
1161            addMapsToMaps (request_output, tmpmaps);
1162          if (tmpmaps != NULL)
1163            {
1164              freeMaps (&tmpmaps);
1165              free (tmpmaps);
1166              tmpmaps = NULL;
1167            }
1168        }
1169    }
1170  else
1171    {
1172      addToMap (*request_inputs, "ResponseDocument", "");
1173
1174      if (cur->type == XML_ELEMENT_NODE) {
1175        // Get every attribute: storeExecuteResponse, lineage, status
1176        const char *ress[3] =
1177          { "storeExecuteResponse", "lineage", "status" };
1178        xmlChar *val;
1179        for (l = 0; l < 3; l++)
1180          {
1181            val = xmlGetProp (cur, BAD_CAST ress[l]);
1182            if (val != NULL && strlen ((char *) val) > 0)
1183              {
1184                addToMap (*request_inputs, ress[l], (char *) val);
1185              }
1186            xmlFree (val);
1187          }
1188                       
1189        xmlNodePtr cur1 = cur->children;               
1190        while (cur1 != NULL) // iterate over Output nodes
1191          {
1192            if (cur1->type != XML_ELEMENT_NODE || 
1193                xmlStrncasecmp(cur1->name, BAD_CAST "Output", 
1194                               xmlStrlen (cur1->name)) != 0) {
1195              cur1 = cur1->next;
1196              continue;
1197            }
1198                               
1199            maps *tmpmaps = (maps *) malloc (MAPS_SIZE); // one per Output node
1200            if (tmpmaps == NULL) {
1201              return errorException (*main_conf,
1202                                     _
1203                                     ("Unable to allocate memory."),
1204                                     "InternalError", NULL,NULL);
1205            }
1206            tmpmaps->name = zStrdup ("unknownIdentifier");
1207            tmpmaps->content = NULL;
1208            tmpmaps->next = NULL;
1209                               
1210            xmlNodePtr elems = cur1->children;
1211                               
1212            while (elems != NULL) {
1213
1214              // Identifier
1215              if (xmlStrncasecmp
1216                  (elems->name, BAD_CAST "Identifier",
1217                   xmlStrlen (elems->name)) == 0)
1218                {
1219                  xmlChar *val =
1220                    xmlNodeListGetString (doc, elems->xmlChildrenNode, 1);
1221               
1222                  free(tmpmaps->name);
1223                  tmpmaps->name = zStrdup ((char *) val);
1224                  if (tmpmaps->content == NULL) {
1225                    tmpmaps->content = createMap("Identifier", zStrdup ((char *) val));
1226                  }
1227                  else {
1228                    addToMap(tmpmaps->content, "Identifier", zStrdup ((char *) val));
1229                  }
1230
1231                  map* tt = getMap (*request_inputs, "ResponseDocument");
1232                  if (strlen(tt->value) == 0) {
1233                    addToMap (*request_inputs, "ResponseDocument",
1234                              (char *) val);
1235                  }
1236                  else {
1237                    char* tmp = (char*) malloc((strlen(tt->value) + 1 
1238                                                + strlen((char*) val) + 1) * sizeof(char));
1239                    sprintf (tmp, "%s;%s", tt->value, (char *) val);
1240                    free(tt->value);
1241                    tt->value = tmp;
1242                  }
1243                  xmlFree (val);
1244                }
1245             
1246              // Title, Abstract
1247              else if (xmlStrncasecmp(elems->name, BAD_CAST "Title",
1248                                      xmlStrlen (elems->name)) == 0
1249                       || xmlStrncasecmp(elems->name, BAD_CAST "Abstract",
1250                                         xmlStrlen (elems->name)) == 0)
1251                {
1252                  xmlChar *val =
1253                    xmlNodeListGetString (doc, elems->xmlChildrenNode, 1);
1254                                                       
1255                  if (tmpmaps->content == NULL) {
1256                    tmpmaps->content = createMap((char*) elems->name, zStrdup ((char *) val));
1257                  }
1258                  else {
1259                    addToMap(tmpmaps->content, (char*) elems->name, zStrdup ((char *) val));
1260                  }
1261                  xmlFree (val);
1262                }
1263              elems = elems->next;
1264            }
1265                               
1266            // Get every attribute from an Output node:
1267            // mimeType, encoding, schema, uom, asReference
1268            const char *outs[5] =
1269              { "mimeType", "encoding", "schema", "uom", "asReference" };
1270                                         
1271            for (l = 0; l < 5; l++) {
1272              xmlChar *val = xmlGetProp (cur1, BAD_CAST outs[l]);                               
1273              if (val != NULL && xmlStrlen(val) > 0) {
1274                if (tmpmaps->content != NULL) {
1275                  addToMap (tmpmaps->content, outs[l], (char *) val);
1276                }                         
1277                else {
1278                  tmpmaps->content = createMap (outs[l], (char *) val);
1279                }       
1280              }
1281              xmlFree (val);
1282            }
1283                               
1284            if (*request_output == NULL) {
1285              *request_output = tmpmaps;
1286            }   
1287            else if (getMaps(*request_output, tmpmaps->name) != NULL) {
1288              return errorException (*main_conf,
1289                                     _
1290                                     ("Duplicate <Output> elements in WPS Execute request"),
1291                                     "InternalError", NULL,NULL);
1292            }
1293            else {
1294              maps* mptr = *request_output;
1295              while (mptr->next != NULL) {
1296                mptr = mptr->next;
1297              }
1298              mptr->next = tmpmaps;     
1299            }                                   
1300            cur1 = cur1->next;
1301          }                     
1302      }
1303    }
1304  return 1;
1305}
1306
1307/**
1308 * Parse XML request and store informations in maps.
1309 *
1310 * @param main_conf the conf maps containing the main.cfg settings
1311 * @param post the string containing the XML request
1312 * @param request_inputs the map storing KVP raw value
1313 * @param s the service
1314 * @param inputs the maps to store the KVP pairs
1315 * @param outputs the maps to store the KVP pairs
1316 * @param hInternet the HINTERNET queue to add potential requests
1317 * @return 0 on success, -1 on failure
1318 */
1319int xmlParseRequest(maps** main_conf,const char* post,map** request_inputs,service* s,maps** inputs,maps** outputs,HINTERNET* hInternet,struct cgi_env *cgi){
1320
1321  map* version=getMapFromMaps(*main_conf,"main","rversion");
1322  int vid=getVersionId(version->value);
1323
1324  xmlInitParser ();
1325  xmlDocPtr doc = xmlParseMemory (post, cgi->cgiContentLength);
1326
1327  /**
1328   * Extract Input nodes from the XML Request.
1329   */
1330  xmlXPathObjectPtr tmpsptr =
1331    extractFromDoc (doc, (vid==0?"/*/*/*[local-name()='Input']":"/*/*[local-name()='Input']"));
1332  xmlNodeSet *tmps = tmpsptr->nodesetval;
1333  if(tmps==NULL || xmlParseInputs(main_conf,s,inputs,doc,tmps,hInternet)<0){
1334    xmlXPathFreeObject (tmpsptr);
1335    xmlFreeDoc (doc);
1336    xmlCleanupParser ();
1337    return -1;
1338  }
1339  xmlXPathFreeObject (tmpsptr);
1340
1341  if(vid==1){
1342    tmpsptr =
1343      extractFromDoc (doc, "/*[local-name()='Execute']");
1344    bool asRaw = false;
1345    tmps = tmpsptr->nodesetval;
1346    if(tmps->nodeNr > 0){
1347      int k = 0;
1348      for (k=0; k < tmps->nodeNr; k++){
1349        maps *tmpmaps = NULL;
1350        xmlNodePtr cur = tmps->nodeTab[k];
1351        if (cur->type == XML_ELEMENT_NODE){
1352          xmlChar *val = xmlGetProp (cur, BAD_CAST "mode");
1353          if(val!=NULL)
1354            addToMap(*request_inputs,"mode",(char*)val);
1355          else
1356            addToMap(*request_inputs,"mode","auto");
1357          val = xmlGetProp (cur, BAD_CAST "response");
1358          if(val!=NULL){
1359            addToMap(*request_inputs,"response",(char*)val);
1360            if(strncasecmp((char*)val,"raw",xmlStrlen(val))==0)
1361              addToMap(*request_inputs,"RawDataOutput","");
1362            else
1363              addToMap(*request_inputs,"ResponseDocument","");
1364          }
1365          else{
1366            addToMap(*request_inputs,"response","document");
1367            addToMap(*request_inputs,"ResponseDocument","");
1368          }
1369        }
1370      }
1371    }
1372    xmlXPathFreeObject (tmpsptr);
1373    tmpsptr =
1374      extractFromDoc (doc, "/*/*[local-name()='Output']");
1375    tmps = tmpsptr->nodesetval;
1376    if(tmps->nodeNr > 0){
1377      if(xmlParseOutputs2(main_conf,request_inputs,outputs,doc,tmps)<0){
1378        xmlXPathFreeObject (tmpsptr);
1379        xmlFreeDoc (doc);
1380        xmlCleanupParser ();
1381        return -1;
1382      }
1383    }
1384  }
1385  else{
1386    // Extract ResponseDocument / RawDataOutput from the XML Request
1387    tmpsptr =
1388      extractFromDoc (doc, "/*/*/*[local-name()='ResponseDocument']");
1389    bool asRaw = false;
1390    tmps = tmpsptr->nodesetval;
1391    if (tmps->nodeNr == 0)
1392      {
1393        xmlXPathFreeObject (tmpsptr);
1394        tmpsptr =
1395          extractFromDoc (doc, "/*/*/*[local-name()='RawDataOutput']");
1396        tmps = tmpsptr->nodesetval;
1397        asRaw = true;
1398      }
1399    if(tmps->nodeNr != 0){
1400      if(xmlParseOutputs(main_conf,request_inputs,outputs,doc,tmps->nodeTab[0],asRaw)<0){
1401        xmlXPathFreeObject (tmpsptr);
1402        xmlFreeDoc (doc);
1403        xmlCleanupParser ();
1404        return -1;
1405      }
1406    }
1407  }
1408  xmlXPathFreeObject (tmpsptr);
1409  xmlFreeDoc (doc);
1410  xmlCleanupParser ();
1411  return 1;
1412}
1413
1414/**
1415 * Parse request and store informations in maps.
1416 *
1417 * @param main_conf the conf maps containing the main.cfg settings
1418 * @param post the string containing the XML request
1419 * @param request_inputs the map storing KVP raw value
1420 * @param s the service
1421 * @param inputs the maps to store the KVP pairs
1422 * @param outputs the maps to store the KVP pairs
1423 * @param hInternet the HINTERNET queue to add potential requests
1424 * @return 0 on success, -1 on failure
1425 * @see kvpParseOutputs,kvpParseInputs,xmlParseRequest
1426 */
1427int parseRequest(maps** main_conf,map** request_inputs,service* s,maps** inputs,maps** outputs,HINTERNET* hInternet,struct cgi_env *cgi){
1428  map *postRequest = NULL;
1429  postRequest = getMap (*request_inputs, "xrequest");
1430  if (postRequest == NULLMAP)
1431    {
1432      if(kvpParseOutputs(main_conf,*request_inputs,outputs)<0){
1433        return -1;
1434      }
1435      if(kvpParseInputs(main_conf,s,*request_inputs,inputs,hInternet)<0){
1436        return -1;
1437      }
1438    }
1439  else
1440    {
1441      //Parse XML request
1442      if(xmlParseRequest(main_conf,postRequest->value,request_inputs,s,inputs,outputs,hInternet,cgi)<0){
1443        return -1;
1444      }
1445    }
1446  return 1;
1447}
1448
1449/**
1450 * Ensure that each requested arguments are present in the request
1451 * DataInputs and ResponseDocument / RawDataOutput. Potentially run
1452 * http requests from the queue in parallel.
1453 * For optional inputs add default values defined in the ZCFG file.
1454 *
1455 * @param main_conf
1456 * @param s
1457 * @param original_request
1458 * @param request_inputs
1459 * @param request_outputs
1460 * @param hInternet
1461 *
1462 * @see runHttpRequests
1463 */
1464int validateRequest(maps** main_conf,service* s,map* original_request, maps** request_inputs,maps** request_outputs,HINTERNET* hInternet,struct cgi_env * cgi){
1465  fprintf(stderr,"STEP 1 VALIDATE \n");
1466 
1467  runHttpRequests (main_conf, request_inputs, hInternet);
1468fprintf(stderr,"STEP 2 VALIDATE \n");
1469 
1470  InternetCloseHandle (hInternet);
1471  fprintf(stderr,"STEP 3 VALIDATE \n");
1472               
1473  map* errI=NULL;
1474  char *dfv = addDefaultValues (request_inputs, s->inputs, *main_conf, 0,&errI);
1475
1476  maps *ptr = *request_inputs;
1477  while (ptr != NULL)
1478    {
1479      map *tmp0 = getMap (ptr->content, "size");
1480      map *tmp1 = getMap (ptr->content, "maximumMegabytes");
1481      if (tmp1 != NULL && tmp0 != NULL)
1482        {
1483          float i = atof (tmp0->value) / 1048576.0;
1484          if (i >= atoi (tmp1->value))
1485            {
1486              char tmps[1024];
1487              map *tmpe = createMap ("code", "FileSizeExceeded");
1488              snprintf (tmps, 1024,
1489                        _
1490                        ("The <%s> parameter has a size limit (%s MB) defined in the ZOO ServicesProvider configuration file, but the reference you provided exceeds this limit (%f MB)."),
1491                        ptr->name, tmp1->value, i);
1492              addToMap (tmpe, "locator", ptr->name);
1493              addToMap (tmpe, "text", tmps);
1494              printExceptionReportResponse (*main_conf, tmpe,NULL);
1495              freeMap (&tmpe);
1496              free (tmpe);
1497              return -1;
1498            }
1499        }
1500      ptr = ptr->next;
1501    }
1502fprintf(stderr,"STEP 4 VALIDATE \n");
1503  dumpMaps(*request_outputs);
1504  map* errO=NULL;
1505  char *dfv1 =
1506    addDefaultValues (request_outputs, s->outputs, *main_conf, 1,&errO);
1507    fprintf(stderr,"STEP 4 - 1 VALIDATE \n");
1508 
1509  if (strcmp (dfv1, "") != 0 || strcmp (dfv, "") != 0)
1510    {
1511      char tmps[1024];
1512      map *tmpe = NULL;
1513      if (strcmp (dfv, "") != 0)
1514        {
1515          tmpe = createMap ("code", "MissingParameterValue");
1516          int nb=0;
1517          int length=1;
1518          map* len=getMap(errI,"length");
1519          if(len!=NULL)
1520            length=atoi(len->value);
1521          for(nb=0;nb<length;nb++){
1522            map* errp=getMapArray(errI,"value",nb);
1523            snprintf (tmps, 1024,
1524                      _
1525                      ("The <%s> argument was not specified in DataInputs but is required according to the ZOO ServicesProvider configuration file."),
1526                      errp->value);
1527            setMapArray (tmpe, "locator", nb , errp->value);
1528            setMapArray (tmpe, "text", nb , tmps);
1529            setMapArray (tmpe, "code", nb , "MissingParameterValue");
1530          }
1531        }
1532    fprintf(stderr,"STEP 4 - 2 VALIDATE \n");
1533 
1534      if (strcmp (dfv1, "") != 0)
1535        {
1536          int ilength=0;
1537          if(tmpe==NULL)
1538            tmpe = createMap ("code", "InvalidParameterValue");
1539          else{
1540            map* len=getMap(tmpe,"length");
1541            if(len!=NULL)
1542              ilength=atoi(len->value);
1543          }
1544          int nb=0;
1545          int length=1;
1546          map* len=getMap(errO,"length");
1547          if(len!=NULL)
1548            length=atoi(len->value);
1549          for(nb=0;nb<length;nb++){
1550            map* errp=getMapArray(errO,"value",nb);
1551            snprintf (tmps, 1024,
1552                      _
1553                      ("The <%s> argument specified as %s identifier was not recognized (not defined in the ZOO Configuration File)."),
1554                      errp->value,
1555                      ((getMap(original_request,"RawDataOutput")!=NULL)?"RawDataOutput":"ResponseDocument"));
1556            setMapArray (tmpe, "locator", nb+ilength , errp->value);
1557            setMapArray (tmpe, "text", nb+ilength , tmps);
1558            setMapArray (tmpe, "code", nb+ilength , "InvalidParameterValue");
1559          }
1560        }
1561    fprintf(stderr,"STEP 4 - 3 VALIDATE \n");
1562 
1563      printExceptionReportResponse (*main_conf, tmpe,NULL);
1564      if(errI!=NULL){
1565        freeMap(&errI);
1566        free(errI);
1567      }
1568      if(errO!=NULL){
1569        freeMap(&errO);
1570        free(errO);
1571      }
1572      freeMap (&tmpe);
1573      free (tmpe);
1574      return -1;
1575    }
1576  maps *tmpReqI = *request_inputs;
1577  fprintf(stderr,"STEP 5 VALIDATE \n");
1578 
1579  while (tmpReqI != NULL)
1580    {
1581      char name[1024];
1582      if (getMap (tmpReqI->content, "isFile") != NULL)
1583        {
1584          if (cgiFormFileName (tmpReqI->name, name, sizeof (name),&cgi) ==
1585              cgiFormSuccess)
1586            {
1587              int BufferLen = 1024;
1588              cgiFilePtr file;
1589              int targetFile;
1590              char storageNameOnServer[2048];
1591              char fileNameOnServer[64];
1592              char contentType[1024];
1593              char buffer[1024];
1594              char *tmpStr = NULL;
1595              int size;
1596              int got, t;
1597              map *path = getMapFromMaps (*main_conf, "main", "tmpPath");
1598              cgiFormFileSize (tmpReqI->name, &size,&cgi);
1599              cgiFormFileContentType (tmpReqI->name, contentType,
1600                                      sizeof (contentType),&cgi);
1601              if (cgiFormFileOpen (tmpReqI->name, &file,&cgi) == cgiFormSuccess)
1602                {
1603                  t = -1;
1604                  while (1)
1605                    {
1606                      tmpStr = strstr (name + t + 1, "\\");
1607                      if (NULL == tmpStr)
1608                        tmpStr = strstr (name + t + 1, "/");
1609                      if (NULL != tmpStr)
1610                        t = (int) (tmpStr - name);
1611                      else
1612                        break;
1613                    }
1614                  strcpy (fileNameOnServer, name + t + 1);
1615
1616                  sprintf (storageNameOnServer, "%s/%s", path->value,
1617                           fileNameOnServer);
1618#ifdef DEBUG
1619                  fprintf (stderr, "Name on server %s\n",
1620                           storageNameOnServer);
1621                  fprintf (stderr, "fileNameOnServer: %s\n",
1622                           fileNameOnServer);
1623#endif
1624                  targetFile =
1625                    open (storageNameOnServer, O_RDWR | O_CREAT | O_TRUNC,
1626                          S_IRWXU | S_IRGRP | S_IROTH);
1627                  if (targetFile < 0)
1628                    {
1629#ifdef DEBUG
1630                      fprintf (stderr, "could not create the new file,%s\n",
1631                               fileNameOnServer);
1632#endif
1633                    }
1634                  else
1635                    {
1636                      while (cgiFormFileRead (file, buffer, BufferLen, &got)
1637                             == cgiFormSuccess)
1638                        {
1639                          if (got > 0)
1640                            write (targetFile, buffer, got);
1641                        }
1642                    }
1643                  addToMap (tmpReqI->content, "lref", storageNameOnServer);
1644                  cgiFormFileClose (file);
1645                  close (targetFile);
1646#ifdef DEBUG
1647                  fprintf (stderr, "File \"%s\" has been uploaded",
1648                           fileNameOnServer);
1649#endif
1650                }
1651            }
1652        }
1653      tmpReqI = tmpReqI->next;
1654    }
1655fprintf(stderr,"STEP FINAL VALIDATE \n");
1656 
1657  ensureDecodedBase64 (request_inputs);
1658  return 1;
1659}
1660
1661
1662/**
1663 * Verify if a parameter value is valid.
1664 *
1665 * @param request the request map
1666 * @param res the error map potentially generated
1667 * @param toCheck the parameter to use
1668 * @param avalues the acceptable values (or null if testing only for presence)
1669 * @param mandatory verify the presence of the parameter if mandatory > 0
1670 */
1671void checkValidValue(map* request,map** res,const char* toCheck,const char** avalues,int mandatory){
1672  map* lres=*res;
1673  map* r_inputs = getMap (request,toCheck);
1674  if (r_inputs == NULL){
1675    if(mandatory>0){
1676      char *replace=_("Mandatory parameter <%s> was not specified");
1677      char *message=(char*)malloc((strlen(replace)+strlen(toCheck)+1)*sizeof(char));
1678      sprintf(message,replace,toCheck);
1679      if(lres==NULL){
1680        lres=createMap("code","MissingParameterValue");
1681        addToMap(lres,"text",message);
1682        addToMap(lres,"locator",toCheck);       
1683      }else{
1684        int length=1;
1685        map* len=getMap(lres,"length");
1686        if(len!=NULL){
1687          length=atoi(len->value);
1688        }
1689        setMapArray(lres,"text",length,message);
1690        setMapArray(lres,"locator",length,toCheck);
1691        setMapArray(lres,"code",length,"MissingParameter");
1692      }
1693      free(message);
1694    }
1695  }else{
1696    if(avalues==NULL)
1697      return;
1698    int nb=0;
1699    int hasValidValue=-1;
1700    if(strncasecmp(toCheck,"Accept",6)==0){
1701      char *tmp=zStrdup(r_inputs->value);
1702      char *pToken,*saveptr;
1703      pToken=strtok_r(tmp,",",&saveptr);
1704      while(pToken!=NULL){
1705        while(avalues[nb]!=NULL){
1706          if(strcasecmp(avalues[nb],pToken)==0){
1707            hasValidValue=1;
1708            break;
1709          }
1710          nb++;
1711        }
1712        pToken=strtok_r(NULL,",",&saveptr);
1713      }
1714      free(tmp);
1715    }else{
1716      while(avalues[nb]!=NULL){
1717        if(strcasecmp(avalues[nb],r_inputs->value)==0){
1718          hasValidValue=1;
1719          break;
1720        }
1721        nb++;
1722      }
1723    }
1724    if(hasValidValue<0){
1725      char *replace=_("The value <%s> was not recognized, %s %s the only acceptable value.");
1726      nb=0;
1727      char *vvalues=NULL;
1728      char* num=_("is");
1729      while(avalues[nb]!=NULL){
1730        char *tvalues;
1731        if(vvalues==NULL){
1732          vvalues=(char*)malloc((strlen(avalues[nb])+3)*sizeof(char));
1733          sprintf(vvalues,"%s",avalues[nb]);
1734        }
1735        else{
1736          tvalues=zStrdup(vvalues);
1737          vvalues=(char*)realloc(vvalues,(strlen(tvalues)+strlen(avalues[nb])+3)*sizeof(char));
1738          sprintf(vvalues,"%s, %s",tvalues,avalues[nb]);
1739          free(tvalues);
1740          num=_("are");
1741        }
1742        nb++;
1743      }
1744      char *message=(char*)malloc((strlen(replace)+strlen(num)+strlen(vvalues)+strlen(toCheck)+1)*sizeof(char));
1745      sprintf(message,replace,toCheck,vvalues,num);
1746      const char *code="VersionNegotiationFailed";
1747      code="InvalidParameterValue";
1748      const char *locator=toCheck;
1749      if( strncasecmp(toCheck,"version",7)==0 ||
1750          strncasecmp(toCheck,"AcceptVersions",14)==0 )
1751        code="VersionNegotiationFailed";
1752      if( strncasecmp(toCheck,"request",7)==0){
1753        code="OperationNotSupported";
1754        locator=r_inputs->value;
1755      }
1756      if(lres==NULL){
1757        lres=createMap("code","InvalidParameterValue");
1758        addToMap(lres,"text",message);
1759        addToMap(lres,"locator",locator);       
1760      }else{
1761        int length=1;
1762        map* len=getMap(lres,"length");
1763        if(len!=NULL){
1764          length=atoi(len->value);
1765        }
1766        setMapArray(lres,"text",length,message);
1767        setMapArray(lres,"locator",length,locator);
1768        setMapArray(lres,"code",length,"InvalidParameterValue");
1769      }
1770    }
1771  }
1772  if(lres!=NULL){
1773    *res=lres;
1774  }
1775}
Note: See TracBrowser for help on using the repository browser.

Search

Context Navigation

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