source: branches/prototype-v0/zoo-project/zoo-kernel/request_parser.c @ 877

Last change on this file since 877 was 877, checked in by djay, 6 years ago

Fixes for supporting properly the memory=protect which force the ZOO-Kernel to not store any downloaded files in memory. Add footer to the HPC support. Fix the autotools to build service_json and sshapi only when required so, when HPC support is activated, this also avoid adding too much dependencies at compilation time. Store md5 of the downloaded files to avoid uploading on HPC server the same file more than once, in case the md5 correspond.

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