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

Last change on this file since 779 was 756, checked in by djay, 11 years ago

Remove prefix for storeSupported and statusSupported for 1.0.0. Fix isValidLang function. Fix error code to MissingParameterValue? or any other relevant code.

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