source: trunk/zoo-project/zoo-kernel/request_parser.c @ 695

Last change on this file since 695 was 695, checked in by djay, 9 years ago

Do not set header to NULL in addRequestToQueue, it should already contain a curl_slist. This fix issue for both Body and BodyReference?.

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