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

Last change on this file since 728 was 725, checked in by djay, 10 years ago

Fix issue with rst files displayed from Trac. Fix strings to be translated. Always use the same string in all messages.

  • Property svn:keywords set to Id
File size: 49.6 KB
RevLine 
[621]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"
[640]27#include "server_internal.h"
28#include "response_print.h"
29#include "caching.h"
[621]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/**
[640]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/**
[621]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);
[625]201    if(strstr(r_inputs->value,"=")==NULL)
202      cursor_input = url_decode (r_inputs->value);
203    else
204      cursor_input = zStrdup (r_inputs->value);
[621]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      {
[626]213        free(cursor_input);
[725]214        return errorException (*main_conf, _("Unable to allocate memory"),
[621]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          {
[626]224            free(cursor_input);
[725]225            return errorException (*main_conf, _("Unable to allocate memory"),
[621]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                  {
[626]260                    free(cursor_input);
[621]261                    return errorException (*main_conf,
[725]262                                           _("Unable to allocate memory"),
[621]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);
[626]317                        free(cursor_input);
[621]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                        {
[626]325                          free(cursor_input);
[621]326                          return errorException (*main_conf, "Unable to fetch any ressource", "InternalError", NULL);
[626]327                        }
[621]328                      }
329                    free (tmpx2);
[627]330                    addIntToMap (tmpmaps->content, "Order", hInternet->nb);
[621]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                          {
[626]351                            free(cursor_input);
[621]352                            return errorException (*main_conf, "Unable to append maps", "InternalError", NULL);
353                          }
354                      }
355                  }
356                else
[623]357                  addMapsToMaps (request_output, tmpmaps);
[621]358              }
359            freeMaps (&tmpmaps);
360            free (tmpmaps);
361            tmpmaps = NULL;
362            free (tmp);
363          }
364      }
365    free (inputs_as_text);
[626]366    free(cursor_input);
[621]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        {
[626]402          free(cursor_output);
[621]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            {
[626]413              free(cursor_output);
[621]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                        {
[626]438                          free(cursor_output);
[621]439                          return errorException (*main_conf,
440                                                 _
[725]441                                                 ("Unable to allocate memory"),
[621]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
[623]472            addMapsToMaps (request_output, tmp_output);
[621]473          freeMaps (&tmp_output);
474          free (tmp_output);
475          tmp_output = NULL;
476          free (tmp);
477        }
478      free (outputs_as_text);
[626]479      free(cursor_output);
[621]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){
[622]496  int k = 0;
497  int l = 0;
[654]498  map* version=getMapFromMaps(*main_conf,"main","rversion");
499  int vid=getVersionId(version->value);
[622]500  for (k=0; k < nodes->nodeNr; k++)
[621]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.
[654]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
[621]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                                                 _
[725]537                                                 ("Unable to allocate memory"),
[621]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                                                 _
[725]562                                                 ("Unable to allocate memory"),
[621]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                    };
[622]591                  for (l = 0; l < 5; l++)
[621]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
[623]609                                      (main_conf, &tmpmaps->content, hInternet,
[621]610                                       (char *) val) != 0)
611                                    {
612                                      return errorException (*main_conf,
613                                                             _("Unable to add a request in the queue."),
614                                                             "InternalError",
615                                                             NULL);
616                                    }
[628]617                                  addIntToMap (tmpmaps->content, "Order", hInternet->nb);
[621]618                                }
[627]619                              addToMap (tmpmaps->content, "Reference", (char*) val);
[621]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;
[695]640                          char *has=NULL;
[621]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                                                             _
[725]665                                                             ("Unable to allocate memory"),
[621]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                            }
[695]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);
[621]683                            free (has);
[695]684                          }
[621]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                                        {
[623]730                                          addRequestToQueue(main_conf,hInternet,(char *) btmp->value,false);
[621]731                                          InternetOpenUrl (hInternet,
732                                                           btmp->value,
733                                                           tmp,
734                                                           xmlStrlen(btmps),
735                                                           INTERNET_FLAG_NO_CACHE_WRITE,
736                                                           0);
[627]737                                          addIntToMap (tmpmaps->content, "Order", hInternet->nb);
[621]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                                                           _
[725]782                                                           ("Unable to allocate memory"),
[621]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                                  {
[623]798                                    addRequestToQueue(main_conf,hInternet,(char *) btmp->value,false);
[621]799
800                                    res =
801                                      InternetOpenUrl (hInternet,
802                                                       btmp->value,
803                                                       tmp,
804                                                       strlen(tmp),
805                                                       INTERNET_FLAG_NO_CACHE_WRITE,
806                                                       0);
[627]807                                    addIntToMap (tmpmaps->content, "Order", hInternet->nb);
[621]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;
[654]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
[621]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");
[622]869                          for (l = 0; l < 2; l++)
[621]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" };
[622]895                            for (l = 0; l < 3; l++)
[621]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
[654]946                                     && cur5->type != XML_CDATA_SECTION_NODE)
[621]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,
[703]954                                                             "utf-8", 0);
955                                  addIntToMap (tmpmaps->content, "size",
956                                               buffersize);
[621]957                                  xmlFreeDoc (doc1);
958                                }
959                              else
960                                {
961                                  if (cur5 != NULL
962                                      && cur5->type == XML_CDATA_SECTION_NODE){
963                                    xmlDocPtr doc2 = xmlParseMemory((const char*)cur5->content,xmlStrlen(cur5->content));
964                                    xmlDocSetRootElement (doc1,xmlDocGetRootElement(doc2));
965                                    xmlDocDumpFormatMemoryEnc (doc1, &mv,
966                                                               &buffersize,
[703]967                                                               "utf-8", 0);
968                                    addIntToMap(tmpmaps->content, "size",buffersize);
[621]969                                    xmlFreeDoc (doc2);
970                                    xmlFreeDoc (doc1);
971                                  }
972                                }
973                            }else{
974                            xmlNodePtr cur5 = cur4->children;
975                            while (cur5 != NULL
976                                   && cur5->type != XML_CDATA_SECTION_NODE)
977                              cur5 = cur5->next;
978                            if (cur5 != NULL
979                                && cur5->type == XML_CDATA_SECTION_NODE){
980                              xmlFree(mv);
981                              mv=xmlStrdup(cur5->content);
982                            }
983                          }
984                          if (mv != NULL)
985                            {
986                              addToMap (tmpmaps->content, "value",
[703]987                                        (char*) mv);
[621]988                              xmlFree (mv);
989                            }
990                        }
991                      else
992                        {
993                          xmlChar *tmp = xmlNodeListGetRawString (doc,
994                                                                  cur4->xmlChildrenNode,
995                                                                  0);
996                          addToMap (tmpmaps->content, "value",
997                                    (char *) tmp);
998                          xmlFree (tmp);
999                        }
[703]1000
[621]1001                      cur4 = cur4->next;
1002                    }
1003                }
1004              cur2 = cur2->next;
[631]1005              while (cur2 != NULL && cur2->type != XML_ELEMENT_NODE){
1006                cur2 = cur2->next;
1007              }
[621]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);
1024                      }
1025                  }
1026              }
1027            else
[623]1028              addMapsToMaps (request_output, tmpmaps);
[621]1029          }
1030          freeMaps (&tmpmaps);
1031          free (tmpmaps);
1032          tmpmaps = NULL;
1033        }
1034    }
1035  return 1;
1036}
1037
1038/**
[654]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  }
[680]1087  return 0;
[654]1088}
1089
1090/**
[621]1091 * Parse outputs from XML nodes and store them in a maps.
1092 *
1093 * @param main_conf the conf maps containing the main.cfg settings
1094 * @param request_inputs the map storing KVP raw value
1095 * @param request_output the maps to store the KVP pairs
1096 * @param doc the xmlDocPtr containing the original request
1097 * @param cur the xmlNodePtr corresponding to the ResponseDocument or RawDataOutput XML node
1098 * @param raw true if the node is RawDataOutput, false in case of ResponseDocument
1099 * @return 0 on success, -1 on failure
1100 */
1101int xmlParseOutputs(maps** main_conf,map** request_inputs,maps** request_output,xmlDocPtr doc,xmlNodePtr cur,bool raw){
[622]1102  int l=0;
[621]1103  if( raw == true)
1104    {
1105      addToMap (*request_inputs, "RawDataOutput", "");
1106      if (cur->type == XML_ELEMENT_NODE)
1107        {
1108
1109          maps *tmpmaps = (maps *) malloc (MAPS_SIZE);
1110          if (tmpmaps == NULL)
1111            {
[725]1112              return errorException (*main_conf, _("Unable to allocate memory"),
[621]1113                                     "InternalError", NULL);
1114            }
1115          tmpmaps->name = zStrdup ("unknownIdentifier");
1116          tmpmaps->content = NULL;
1117          tmpmaps->next = NULL;
1118
1119          // Get every attribute from a RawDataOutput node
1120          // mimeType, encoding, schema, uom
1121          const char *outs[4] =
1122            { "mimeType", "encoding", "schema", "uom" };
[622]1123          for (l = 0; l < 4; l++)
[621]1124            {
1125              xmlChar *val = xmlGetProp (cur, BAD_CAST outs[l]);
1126              if (val != NULL)
1127                {
1128                  if (strlen ((char *) val) > 0)
1129                    {
1130                      if (tmpmaps->content != NULL)
1131                        addToMap (tmpmaps->content, outs[l],
1132                                  (char *) val);
1133                      else
1134                        tmpmaps->content =
1135                          createMap (outs[l], (char *) val);
1136                    }
1137                  xmlFree (val);
1138                }
1139            }
1140          xmlNodePtr cur2 = cur->children;
1141          while (cur2 != NULL && cur2->type != XML_ELEMENT_NODE)
1142            cur2 = cur2->next;
1143          while (cur2 != NULL)
1144            {
1145              if (xmlStrncasecmp
1146                  (cur2->name, BAD_CAST "Identifier",
1147                   xmlStrlen (cur2->name)) == 0)
1148                {
1149                  xmlChar *val =
1150                    xmlNodeListGetString (NULL, cur2->xmlChildrenNode, 1);
1151                  free (tmpmaps->name);
1152                  tmpmaps->name = zStrdup ((char *) val);
1153                  xmlFree (val);
1154                }
1155              cur2 = cur2->next;
1156              while (cur2 != NULL && cur2->type != XML_ELEMENT_NODE)
1157                cur2 = cur2->next;
1158            }
1159          if (*request_output == NULL)
1160            *request_output = dupMaps (&tmpmaps);
1161          else
[623]1162            addMapsToMaps (request_output, tmpmaps);
[621]1163          if (tmpmaps != NULL)
1164            {
1165              freeMaps (&tmpmaps);
1166              free (tmpmaps);
1167              tmpmaps = NULL;
1168            }
1169        }
1170    }
1171  else
1172    {
1173      addToMap (*request_inputs, "ResponseDocument", "");
1174
1175      if (cur->type == XML_ELEMENT_NODE) {
1176        // Get every attribute: storeExecuteResponse, lineage, status
1177        const char *ress[3] =
1178          { "storeExecuteResponse", "lineage", "status" };
1179        xmlChar *val;
[622]1180        for (l = 0; l < 3; l++)
[621]1181          {
1182            val = xmlGetProp (cur, BAD_CAST ress[l]);
1183            if (val != NULL && strlen ((char *) val) > 0)
1184              {
1185                addToMap (*request_inputs, ress[l], (char *) val);
1186              }
1187            xmlFree (val);
1188          }
1189                       
1190        xmlNodePtr cur1 = cur->children;               
1191        while (cur1 != NULL) // iterate over Output nodes
1192          {
1193            if (cur1->type != XML_ELEMENT_NODE || 
1194                xmlStrncasecmp(cur1->name, BAD_CAST "Output", 
1195                               xmlStrlen (cur1->name)) != 0) {
1196              cur1 = cur1->next;
1197              continue;
1198            }
1199                               
1200            maps *tmpmaps = (maps *) malloc (MAPS_SIZE); // one per Output node
1201            if (tmpmaps == NULL) {
1202              return errorException (*main_conf,
1203                                     _
[725]1204                                     ("Unable to allocate memory"),
[621]1205                                     "InternalError", NULL);
1206            }
1207            tmpmaps->name = zStrdup ("unknownIdentifier");
1208            tmpmaps->content = NULL;
1209            tmpmaps->next = NULL;
1210                               
1211            xmlNodePtr elems = cur1->children;
1212                               
1213            while (elems != NULL) {
1214
1215              // Identifier
1216              if (xmlStrncasecmp
1217                  (elems->name, BAD_CAST "Identifier",
1218                   xmlStrlen (elems->name)) == 0)
1219                {
1220                  xmlChar *val =
1221                    xmlNodeListGetString (doc, elems->xmlChildrenNode, 1);
1222               
1223                  free(tmpmaps->name);
1224                  tmpmaps->name = zStrdup ((char *) val);
1225                  if (tmpmaps->content == NULL) {
1226                    tmpmaps->content = createMap("Identifier", zStrdup ((char *) val));
1227                  }
1228                  else {
1229                    addToMap(tmpmaps->content, "Identifier", zStrdup ((char *) val));
1230                  }
1231
1232                  map* tt = getMap (*request_inputs, "ResponseDocument");
1233                  if (strlen(tt->value) == 0) {
1234                    addToMap (*request_inputs, "ResponseDocument",
1235                              (char *) val);
1236                  }
1237                  else {
1238                    char* tmp = (char*) malloc((strlen(tt->value) + 1 
1239                                                + strlen((char*) val) + 1) * sizeof(char));
1240                    sprintf (tmp, "%s;%s", tt->value, (char *) val);
1241                    free(tt->value);
1242                    tt->value = tmp;
1243                  }
1244                  xmlFree (val);
1245                }
1246             
1247              // Title, Abstract
1248              else if (xmlStrncasecmp(elems->name, BAD_CAST "Title",
1249                                      xmlStrlen (elems->name)) == 0
1250                       || xmlStrncasecmp(elems->name, BAD_CAST "Abstract",
1251                                         xmlStrlen (elems->name)) == 0)
1252                {
1253                  xmlChar *val =
1254                    xmlNodeListGetString (doc, elems->xmlChildrenNode, 1);
1255                                                       
1256                  if (tmpmaps->content == NULL) {
1257                    tmpmaps->content = createMap((char*) elems->name, zStrdup ((char *) val));
1258                  }
1259                  else {
1260                    addToMap(tmpmaps->content, (char*) elems->name, zStrdup ((char *) val));
1261                  }
1262                  xmlFree (val);
1263                }
1264              elems = elems->next;
1265            }
1266                               
1267            // Get every attribute from an Output node:
1268            // mimeType, encoding, schema, uom, asReference
1269            const char *outs[5] =
1270              { "mimeType", "encoding", "schema", "uom", "asReference" };
1271                                         
[622]1272            for (l = 0; l < 5; l++) {
[621]1273              xmlChar *val = xmlGetProp (cur1, BAD_CAST outs[l]);                               
1274              if (val != NULL && xmlStrlen(val) > 0) {
1275                if (tmpmaps->content != NULL) {
1276                  addToMap (tmpmaps->content, outs[l], (char *) val);
1277                }                         
1278                else {
1279                  tmpmaps->content = createMap (outs[l], (char *) val);
1280                }       
1281              }
1282              xmlFree (val);
1283            }
1284                               
1285            if (*request_output == NULL) {
1286              *request_output = tmpmaps;
1287            }   
1288            else if (getMaps(*request_output, tmpmaps->name) != NULL) {
1289              return errorException (*main_conf,
1290                                     _
1291                                     ("Duplicate <Output> elements in WPS Execute request"),
1292                                     "InternalError", NULL);
1293            }
1294            else {
1295              maps* mptr = *request_output;
1296              while (mptr->next != NULL) {
1297                mptr = mptr->next;
1298              }
1299              mptr->next = tmpmaps;     
1300            }                                   
1301            cur1 = cur1->next;
1302          }                     
1303      }
1304    }
1305  return 1;
1306}
1307
1308/**
1309 * Parse XML request and store informations in maps.
1310 *
1311 * @param main_conf the conf maps containing the main.cfg settings
1312 * @param post the string containing the XML request
1313 * @param request_inputs the map storing KVP raw value
1314 * @param s the service
1315 * @param inputs the maps to store the KVP pairs
1316 * @param outputs the maps to store the KVP pairs
1317 * @param hInternet the HINTERNET queue to add potential requests
1318 * @return 0 on success, -1 on failure
1319 */
1320int xmlParseRequest(maps** main_conf,const char* post,map** request_inputs,service* s,maps** inputs,maps** outputs,HINTERNET* hInternet){
[654]1321
1322  map* version=getMapFromMaps(*main_conf,"main","rversion");
1323  int vid=getVersionId(version->value);
1324
[621]1325  xmlInitParser ();
1326  xmlDocPtr doc = xmlParseMemory (post, cgiContentLength);
1327
1328  /**
1329   * Extract Input nodes from the XML Request.
1330   */
1331  xmlXPathObjectPtr tmpsptr =
[654]1332    extractFromDoc (doc, (vid==0?"/*/*/*[local-name()='Input']":"/*/*[local-name()='Input']"));
[621]1333  xmlNodeSet *tmps = tmpsptr->nodesetval;
[654]1334  if(tmps==NULL || xmlParseInputs(main_conf,s,inputs,doc,tmps,hInternet)<0){
[621]1335    xmlXPathFreeObject (tmpsptr);
1336    xmlFreeDoc (doc);
1337    xmlCleanupParser ();
1338    return -1;
1339  }
1340  xmlXPathFreeObject (tmpsptr);
1341
[654]1342  if(vid==1){
1343    tmpsptr =
1344      extractFromDoc (doc, "/*[local-name()='Execute']");
1345    bool asRaw = false;
1346    tmps = tmpsptr->nodesetval;
1347    if(tmps->nodeNr > 0){
1348      int k = 0;
1349      for (k=0; k < tmps->nodeNr; k++){
1350        maps *tmpmaps = NULL;
1351        xmlNodePtr cur = tmps->nodeTab[k];
1352        if (cur->type == XML_ELEMENT_NODE){
1353          xmlChar *val = xmlGetProp (cur, BAD_CAST "mode");
1354          if(val!=NULL)
1355            addToMap(*request_inputs,"mode",(char*)val);
1356          else
1357            addToMap(*request_inputs,"mode","auto");
1358          val = xmlGetProp (cur, BAD_CAST "response");
1359          if(val!=NULL){
1360            addToMap(*request_inputs,"response",(char*)val);
1361            if(strncasecmp((char*)val,"raw",xmlStrlen(val))==0)
1362              addToMap(*request_inputs,"RawDataOutput","");
1363            else
1364              addToMap(*request_inputs,"ResponseDocument","");
1365          }
1366          else{
1367            addToMap(*request_inputs,"response","document");
1368            addToMap(*request_inputs,"ResponseDocument","");
1369          }
1370        }
1371      }
[621]1372    }
[654]1373    xmlXPathFreeObject (tmpsptr);
1374    tmpsptr =
1375      extractFromDoc (doc, "/*/*[local-name()='Output']");
1376    tmps = tmpsptr->nodesetval;
1377    if(tmps->nodeNr > 0){
1378      if(xmlParseOutputs2(main_conf,request_inputs,outputs,doc,tmps)<0){
1379        xmlXPathFreeObject (tmpsptr);
1380        xmlFreeDoc (doc);
1381        xmlCleanupParser ();
1382        return -1;
1383      }
[621]1384    }
1385  }
[654]1386  else{
1387    // Extract ResponseDocument / RawDataOutput from the XML Request
1388    tmpsptr =
1389      extractFromDoc (doc, "/*/*/*[local-name()='ResponseDocument']");
1390    bool asRaw = false;
1391    tmps = tmpsptr->nodesetval;
1392    if (tmps->nodeNr == 0)
1393      {
1394        xmlXPathFreeObject (tmpsptr);
1395        tmpsptr =
1396          extractFromDoc (doc, "/*/*/*[local-name()='RawDataOutput']");
1397        tmps = tmpsptr->nodesetval;
1398        asRaw = true;
1399      }
1400    if(tmps->nodeNr != 0){
1401      if(xmlParseOutputs(main_conf,request_inputs,outputs,doc,tmps->nodeTab[0],asRaw)<0){
1402        xmlXPathFreeObject (tmpsptr);
1403        xmlFreeDoc (doc);
1404        xmlCleanupParser ();
1405        return -1;
1406      }
1407    }
1408  }
[621]1409  xmlXPathFreeObject (tmpsptr);
1410  xmlFreeDoc (doc);
1411  xmlCleanupParser ();
1412  return 1;
1413}
1414
1415/**
1416 * Parse request and store informations in maps.
1417 *
1418 * @param main_conf the conf maps containing the main.cfg settings
1419 * @param post the string containing the XML request
1420 * @param request_inputs the map storing KVP raw value
1421 * @param s the service
1422 * @param inputs the maps to store the KVP pairs
1423 * @param outputs the maps to store the KVP pairs
1424 * @param hInternet the HINTERNET queue to add potential requests
1425 * @return 0 on success, -1 on failure
1426 * @see kvpParseOutputs,kvpParseInputs,xmlParseRequest
1427 */
1428int parseRequest(maps** main_conf,map** request_inputs,service* s,maps** inputs,maps** outputs,HINTERNET* hInternet){
1429  map *postRequest = NULL;
1430  postRequest = getMap (*request_inputs, "xrequest");
1431  if (postRequest == NULLMAP)
1432    {
1433      if(kvpParseOutputs(main_conf,*request_inputs,outputs)<0){
1434        return -1;
1435      }
1436      if(kvpParseInputs(main_conf,s,*request_inputs,inputs,hInternet)<0){
1437        return -1;
1438      }
1439    }
1440  else
1441    {
1442      //Parse XML request
1443      if(xmlParseRequest(main_conf,postRequest->value,request_inputs,s,inputs,outputs,hInternet)<0){
1444        return -1;
1445      }
1446    }
1447  return 1;
1448}
1449
1450/**
1451 * Ensure that each requested arguments are present in the request
1452 * DataInputs and ResponseDocument / RawDataOutput. Potentially run
1453 * http requests from the queue in parallel.
1454 * For optional inputs add default values defined in the ZCFG file.
1455 *
1456 * @param main_conf
1457 * @param s
1458 * @param original_request
1459 * @param request_inputs
1460 * @param request_outputs
1461 * @param hInternet
1462 *
1463 * @see runHttpRequests
1464 */
1465int validateRequest(maps** main_conf,service* s,map* original_request, maps** request_inputs,maps** request_outputs,HINTERNET* hInternet){
1466
1467  runHttpRequests (main_conf, request_inputs, hInternet);
1468  InternetCloseHandle (hInternet);
1469
1470  map* errI=NULL;
1471  char *dfv = addDefaultValues (request_inputs, s->inputs, *main_conf, 0,&errI);
1472
1473  maps *ptr = *request_inputs;
1474  while (ptr != NULL)
1475    {
1476      map *tmp0 = getMap (ptr->content, "size");
1477      map *tmp1 = getMap (ptr->content, "maximumMegabytes");
1478      if (tmp1 != NULL && tmp0 != NULL)
1479        {
1480          float i = atof (tmp0->value) / 1048576.0;
1481          if (i >= atoi (tmp1->value))
1482            {
1483              char tmps[1024];
1484              map *tmpe = createMap ("code", "FileSizeExceeded");
1485              snprintf (tmps, 1024,
1486                        _
1487                        ("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)."),
1488                        ptr->name, tmp1->value, i);
1489              addToMap (tmpe, "locator", ptr->name);
1490              addToMap (tmpe, "text", tmps);
1491              printExceptionReportResponse (*main_conf, tmpe);
1492              freeMap (&tmpe);
1493              free (tmpe);
1494              return -1;
1495            }
1496        }
1497      ptr = ptr->next;
1498    }
1499
1500  map* errO=NULL;
1501  char *dfv1 =
1502    addDefaultValues (request_outputs, s->outputs, *main_conf, 1,&errO);
1503  if (strcmp (dfv1, "") != 0 || strcmp (dfv, "") != 0)
1504    {
1505      char tmps[1024];
1506      map *tmpe = NULL;
1507      if (strcmp (dfv, "") != 0)
1508        {
1509          tmpe = createMap ("code", "MissingParameterValue");
1510          int nb=0;
1511          int length=1;
1512          map* len=getMap(errI,"length");
1513          if(len!=NULL)
1514            length=atoi(len->value);
1515          for(nb=0;nb<length;nb++){
1516            map* errp=getMapArray(errI,"value",nb);
1517            snprintf (tmps, 1024,
1518                      _
1519                      ("The <%s> argument was not specified in DataInputs but is required according to the ZOO ServicesProvider configuration file."),
1520                      errp->value);
1521            setMapArray (tmpe, "locator", nb , errp->value);
1522            setMapArray (tmpe, "text", nb , tmps);
1523            setMapArray (tmpe, "code", nb , "MissingParameterValue");
1524          }
1525        }
1526      if (strcmp (dfv1, "") != 0)
1527        {
1528          int ilength=0;
1529          if(tmpe==NULL)
1530            tmpe = createMap ("code", "InvalidParameterValue");
1531          else{
1532            map* len=getMap(tmpe,"length");
1533            if(len!=NULL)
1534              ilength=atoi(len->value);
1535          }
1536          int nb=0;
1537          int length=1;
1538          map* len=getMap(errO,"length");
1539          if(len!=NULL)
1540            length=atoi(len->value);
1541          for(nb=0;nb<length;nb++){
1542            map* errp=getMapArray(errO,"value",nb);
1543            snprintf (tmps, 1024,
1544                      _
1545                      ("The <%s> argument specified as %s identifier was not recognized (not defined in the ZOO Configuration File)."),
1546                      errp->value,
1547                      ((getMap(original_request,"RawDataOutput")!=NULL)?"RawDataOutput":"ResponseDocument"));
1548            setMapArray (tmpe, "locator", nb+ilength , errp->value);
1549            setMapArray (tmpe, "text", nb+ilength , tmps);
1550            setMapArray (tmpe, "code", nb+ilength , "InvalidParameterValue");
1551          }
1552        }
1553      printExceptionReportResponse (*main_conf, tmpe);
1554      if(errI!=NULL){
1555        freeMap(&errI);
1556        free(errI);
1557      }
1558      if(errO!=NULL){
1559        freeMap(&errO);
1560        free(errO);
1561      }
1562      freeMap (&tmpe);
1563      free (tmpe);
1564      return -1;
1565    }
1566  maps *tmpReqI = *request_inputs;
1567  while (tmpReqI != NULL)
1568    {
1569      char name[1024];
1570      if (getMap (tmpReqI->content, "isFile") != NULL)
1571        {
1572          if (cgiFormFileName (tmpReqI->name, name, sizeof (name)) ==
1573              cgiFormSuccess)
1574            {
1575              int BufferLen = 1024;
1576              cgiFilePtr file;
1577              int targetFile;
1578              char storageNameOnServer[2048];
1579              char fileNameOnServer[64];
1580              char contentType[1024];
1581              char buffer[1024];
1582              char *tmpStr = NULL;
1583              int size;
1584              int got, t;
1585              map *path = getMapFromMaps (*main_conf, "main", "tmpPath");
1586              cgiFormFileSize (tmpReqI->name, &size);
1587              cgiFormFileContentType (tmpReqI->name, contentType,
1588                                      sizeof (contentType));
1589              if (cgiFormFileOpen (tmpReqI->name, &file) == cgiFormSuccess)
1590                {
1591                  t = -1;
1592                  while (1)
1593                    {
1594                      tmpStr = strstr (name + t + 1, "\\");
1595                      if (NULL == tmpStr)
1596                        tmpStr = strstr (name + t + 1, "/");
1597                      if (NULL != tmpStr)
1598                        t = (int) (tmpStr - name);
1599                      else
1600                        break;
1601                    }
1602                  strcpy (fileNameOnServer, name + t + 1);
1603
1604                  sprintf (storageNameOnServer, "%s/%s", path->value,
1605                           fileNameOnServer);
1606#ifdef DEBUG
1607                  fprintf (stderr, "Name on server %s\n",
1608                           storageNameOnServer);
1609                  fprintf (stderr, "fileNameOnServer: %s\n",
1610                           fileNameOnServer);
1611#endif
1612                  targetFile =
1613                    open (storageNameOnServer, O_RDWR | O_CREAT | O_TRUNC,
1614                          S_IRWXU | S_IRGRP | S_IROTH);
1615                  if (targetFile < 0)
1616                    {
1617#ifdef DEBUG
1618                      fprintf (stderr, "could not create the new file,%s\n",
1619                               fileNameOnServer);
1620#endif
1621                    }
1622                  else
1623                    {
1624                      while (cgiFormFileRead (file, buffer, BufferLen, &got)
1625                             == cgiFormSuccess)
1626                        {
1627                          if (got > 0)
1628                            write (targetFile, buffer, got);
1629                        }
1630                    }
1631                  addToMap (tmpReqI->content, "lref", storageNameOnServer);
1632                  cgiFormFileClose (file);
1633                  close (targetFile);
1634#ifdef DEBUG
1635                  fprintf (stderr, "File \"%s\" has been uploaded",
1636                           fileNameOnServer);
1637#endif
1638                }
1639            }
1640        }
1641      tmpReqI = tmpReqI->next;
1642    }
1643
1644  ensureDecodedBase64 (request_inputs);
1645  return 1;
1646}
[640]1647
1648
1649/**
1650 * Verify if a parameter value is valid.
1651 *
1652 * @param request the request map
1653 * @param res the error map potentially generated
1654 * @param toCheck the parameter to use
1655 * @param avalues the acceptable values (or null if testing only for presence)
1656 * @param mandatory verify the presence of the parameter if mandatory > 0
1657 */
1658void checkValidValue(map* request,map** res,const char* toCheck,const char** avalues,int mandatory){
1659  map* lres=*res;
1660  map* r_inputs = getMap (request,toCheck);
1661  if (r_inputs == NULL){
1662    if(mandatory>0){
1663      char *replace=_("Mandatory parameter <%s> was not specified");
1664      char *message=(char*)malloc((strlen(replace)+strlen(toCheck)+1)*sizeof(char));
1665      sprintf(message,replace,toCheck);
1666      if(lres==NULL){
1667        lres=createMap("code","MissingParameterValue");
1668        addToMap(lres,"text",message);
1669        addToMap(lres,"locator",toCheck);       
1670      }else{
1671        int length=1;
1672        map* len=getMap(lres,"length");
1673        if(len!=NULL){
1674          length=atoi(len->value);
1675        }
1676        setMapArray(lres,"text",length,message);
1677        setMapArray(lres,"locator",length,toCheck);
1678        setMapArray(lres,"code",length,"MissingParameter");
1679      }
1680      free(message);
1681    }
1682  }else{
1683    if(avalues==NULL)
1684      return;
1685    int nb=0;
1686    int hasValidValue=-1;
1687    if(strncasecmp(toCheck,"Accept",6)==0){
1688      char *tmp=zStrdup(r_inputs->value);
1689      char *pToken,*saveptr;
1690      pToken=strtok_r(tmp,",",&saveptr);
1691      while(pToken!=NULL){
1692        while(avalues[nb]!=NULL){
1693          if(strcasecmp(avalues[nb],pToken)==0){
1694            hasValidValue=1;
1695            break;
1696          }
1697          nb++;
1698        }
1699        pToken=strtok_r(NULL,",",&saveptr);
1700      }
1701      free(tmp);
1702    }else{
1703      while(avalues[nb]!=NULL){
1704        if(strcasecmp(avalues[nb],r_inputs->value)==0){
1705          hasValidValue=1;
1706          break;
1707        }
1708        nb++;
1709      }
1710    }
1711    if(hasValidValue<0){
1712      char *replace=_("The value <%s> was not recognized, %s %s the only acceptable value.");
1713      nb=0;
1714      char *vvalues=NULL;
1715      char* num=_("is");
1716      while(avalues[nb]!=NULL){
1717        char *tvalues;
1718        if(vvalues==NULL){
1719          vvalues=(char*)malloc((strlen(avalues[nb])+3)*sizeof(char));
1720          sprintf(vvalues,"%s",avalues[nb]);
1721        }
1722        else{
1723          tvalues=zStrdup(vvalues);
1724          vvalues=(char*)realloc(vvalues,(strlen(tvalues)+strlen(avalues[nb])+3)*sizeof(char));
1725          sprintf(vvalues,"%s, %s",tvalues,avalues[nb]);
1726          free(tvalues);
1727          num=_("are");
1728        }
1729        nb++;
1730      }
1731      char *message=(char*)malloc((strlen(replace)+strlen(num)+strlen(vvalues)+strlen(toCheck)+1)*sizeof(char));
1732      sprintf(message,replace,toCheck,vvalues,num);
1733      const char *code="VersionNegotiationFailed";
1734      code="InvalidParameterValue";
1735      const char *locator=toCheck;
1736      if( strncasecmp(toCheck,"version",7)==0 ||
1737          strncasecmp(toCheck,"AcceptVersions",14)==0 )
1738        code="VersionNegotiationFailed";
1739      if( strncasecmp(toCheck,"request",7)==0){
1740        code="OperationNotSupported";
1741        locator=r_inputs->value;
1742      }
1743      if(lres==NULL){
1744        lres=createMap("code","InvalidParameterValue");
1745        addToMap(lres,"text",message);
1746        addToMap(lres,"locator",locator);       
1747      }else{
1748        int length=1;
1749        map* len=getMap(lres,"length");
1750        if(len!=NULL){
1751          length=atoi(len->value);
1752        }
1753        setMapArray(lres,"text",length,message);
1754        setMapArray(lres,"locator",length,locator);
1755        setMapArray(lres,"code",length,"InvalidParameterValue");
1756      }
1757    }
1758  }
1759  if(lres!=NULL){
1760    *res=lres;
1761  }
1762}
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