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

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

Modify memory configuration option gesture. Now, in case you don't have setup memory option in the main section your main.cfg file then, the ZOO-Kernel will load everything in memory and will also store the file containing the input. In case you want the old mode, you have to set memory option to 'load' in your main.cfg file. Fix issue with loading R ZOO-Service located in a subdirectory. Support for XML Execute request containing TEXT_NODE when CDATA_NODE should be used.

  • Property svn:keywords set to Id
File size: 56.7 KB
Line 
1/*
2 * Author : Gérald FENOY
3 *
4 * Copyright (c) 2015 GeoLabs SARL
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
24
25#include "request_parser.h"
26#include "service_internal.h"
27#include "server_internal.h"
28#include "response_print.h"
29#include "caching.h"
30
31/**
32 * Apply XPath Expression on XML document.
33 *
34 * @param doc the XML Document
35 * @param search the XPath expression
36 * @return xmlXPathObjectPtr containing the resulting nodes set
37 */
38xmlXPathObjectPtr
39extractFromDoc (xmlDocPtr doc, const char *search)
40{
41  xmlXPathContextPtr xpathCtx;
42  xmlXPathObjectPtr xpathObj;
43  xpathCtx = xmlXPathNewContext (doc);
44  xpathObj = xmlXPathEvalExpression (BAD_CAST search, xpathCtx);
45  xmlXPathFreeContext (xpathCtx);
46  return xpathObj;
47}
48
49/**
50 * Create (or append to) an array valued maps value = "["",""]"
51 *
52 * @param m the conf maps containing the main.cfg settings
53 * @param mo the map to update
54 * @param mi the map to append
55 * @param elem the elements containing default definitions
56 * @return 0 on success, -1 on failure
57 */
58int appendMapsToMaps (maps * m, maps * mo, maps * mi, elements * elem){
59  maps *tmpMaps = getMaps (mo, mi->name);
60  map *tmap = getMapType (tmpMaps->content);
61  elements *el = getElements (elem, mi->name);
62  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                      if (test == NULL)
981                        {
982                          if (tmpmaps->content != NULL)
983                            addToMap (tmpmaps->content, "encoding",
984                                      "utf-8");
985                          else
986                            tmpmaps->content =
987                              createMap ("encoding", "utf-8");
988                          test = getMap (tmpmaps->content, "encoding");
989                        }
990
991                      if (getMap(tmpmaps->content,"dataType")==NULL && test!=NULL && strcasecmp (test->value, "base64") != 0)
992                        {
993                          xmlChar *mv = NULL;
994                          /*if(cur4!=NULL && cur4->xmlChildrenNode!=NULL)
995                            xmlChar *mv = xmlNodeListGetString (doc,
996                                                                cur4->xmlChildrenNode,
997                                                                1);*/
998                          map *ltmp =
999                            getMap (tmpmaps->content, "mimeType");
1000                          if (/*mv == NULL
1001                              ||*/
1002                              (xmlStrcasecmp
1003                               (cur4->name, BAD_CAST "ComplexData") == 0
1004                               && (ltmp == NULL
1005                                   || strncasecmp (ltmp->value,
1006                                                   "text/xml", 8) == 0)))
1007                            {
1008                              xmlDocPtr doc1 = xmlNewDoc (BAD_CAST "1.0");
1009                              int buffersize;
1010                              xmlNodePtr cur5 = cur4->children;
1011                              while (cur5 != NULL
1012                                     && cur5->type != XML_ELEMENT_NODE
1013                                     && cur5->type != XML_CDATA_SECTION_NODE)
1014                                cur5 = cur5->next;
1015                              if (cur5 != NULL
1016                                  && cur5->type != XML_CDATA_SECTION_NODE)
1017                                {
1018                                  xmlDocSetRootElement (doc1, cur5);
1019                                  xmlDocDumpFormatMemoryEnc (doc1, &mv,
1020                                                             &buffersize,
1021                                                             "utf-8", 0);
1022                                  xmlFreeDoc (doc1);
1023                                }
1024                              else
1025                                {
1026                                  if (cur5 != NULL
1027                                      && cur5->type == XML_CDATA_SECTION_NODE){
1028                                    xmlDocPtr doc2 = xmlReadMemory((const char*)cur5->content,xmlStrlen(cur5->content),
1029                                                                   "input_content.xml", NULL, XML_PARSE_RECOVER);
1030                                    xmlDocDumpFormatMemoryEnc (doc2, &mv,
1031                                                               &buffersize,
1032                                                               "utf-8", 0);
1033                                    xmlFreeDoc (doc2);
1034                                  }
1035                                }
1036                              addIntToMap (tmpmaps->content, "size",
1037                                           buffersize);
1038                            }else{
1039
1040                            if(xmlStrcasecmp
1041                               (cur4->name, BAD_CAST "BoundingBoxData") == 0){
1042                              xmlDocPtr doc1 = xmlNewDoc(BAD_CAST "1.0");
1043                              int buffersize;
1044                              xmlDocSetRootElement(doc1,cur4);
1045                              xmlDocDumpFormatMemoryEnc(doc1,&mv,
1046                                                        &buffersize,
1047                                                        "utf-8",0);
1048                              addIntToMap (tmpmaps->content, "size",
1049                                           buffersize);
1050                              xmlParseBoundingBox(main_conf,&tmpmaps->content,doc1);
1051                            }else{
1052                              xmlNodePtr cur5 = cur4->children;
1053                              while (cur5 != NULL
1054                                     && cur5->type != XML_ELEMENT_NODE
1055                                     && cur5->type != XML_TEXT_NODE
1056                                     && cur5->type != XML_CDATA_SECTION_NODE)
1057                                cur5 = cur5->next;
1058                              if (cur5 != NULL
1059                                  && cur5->type != XML_CDATA_SECTION_NODE
1060                                  && cur5->type != XML_TEXT_NODE)
1061                                {
1062                                  xmlDocPtr doc1 = xmlNewDoc (BAD_CAST "1.0");
1063                                  int buffersize;
1064                                  xmlDocSetRootElement (doc1, cur5);
1065                                  xmlDocDumpFormatMemoryEnc (doc1, &mv,
1066                                                             &buffersize,
1067                                                             "utf-8", 0);
1068                                  addIntToMap (tmpmaps->content, "size",
1069                                               buffersize);
1070                                }
1071                              else if (cur5 != NULL)/*
1072                                     && cur5->type == XML_CDATA_SECTION_NODE)*/{
1073                                xmlFree(mv);
1074                                if(cur5->content!=NULL){
1075                                  mv=xmlStrdup(cur5->content);
1076                                }
1077                              }
1078                            }
1079                          }
1080                          if (mv != NULL)
1081                            {
1082                              addToMap (tmpmaps->content, "value",
1083                                        (char*) mv);
1084                              xmlFree (mv);
1085                            }
1086                        }
1087                      else
1088                        {
1089                          xmlNodePtr cur5 = cur4->children;
1090                          while (cur5 != NULL
1091                                 && cur5->type != XML_CDATA_SECTION_NODE)
1092                            cur5 = cur5->next;
1093                          if (cur5 != NULL
1094                              && cur5->type == XML_CDATA_SECTION_NODE)
1095                            {
1096                              addToMap (tmpmaps->content,
1097                                        "value",
1098                                        (char *) cur5->content);
1099                            }
1100                          else{
1101                            if(cur4->xmlChildrenNode!=NULL){
1102                              xmlChar *tmp = xmlNodeListGetRawString (doc,
1103                                                                      cur4->xmlChildrenNode,
1104                                                                      0);
1105                              addToMap (tmpmaps->content, "value",
1106                                        (char *) tmp);
1107                              xmlFree (tmp);
1108                            }
1109                          }
1110                        }
1111
1112                      cur4 = cur4->next;
1113                    }
1114                }
1115              cur2 = cur2->next;
1116              while (cur2 != NULL && cur2->type != XML_ELEMENT_NODE){
1117                cur2 = cur2->next;
1118              }
1119            }
1120          if(memory!=NULL && strncasecmp(memory->value,"load",4)!=0)
1121            if(getMap(tmpmaps->content,"to_load")==NULL){
1122              addToMap(tmpmaps->content,"to_load","false");
1123            }
1124          {
1125            map* test=getMap(tmpmaps->content,"value");
1126            if(test==NULL && tmpmaps->child==NULL)
1127              addToMap(tmpmaps->content,"value","");
1128            maps *testPresence = getMaps (*request_output, tmpmaps->name);
1129            maps *cursor=*request_output;
1130            while(testPresence == NULL && cursor!=NULL){
1131              if(cursor->child!=NULL){
1132                testPresence = getMaps (cursor->child, tmpmaps->name);
1133              }
1134              cursor=cursor->next;
1135            }
1136            if (testPresence != NULL)
1137              {
1138                elements *elem = getElements (s->inputs, tmpmaps->name);
1139                elements *cursor=s->inputs;
1140                while(elem == NULL && cursor!=NULL){
1141                  if(cursor->child!=NULL){
1142                    elem = getElements (cursor->child, tmpmaps->name);
1143                  }
1144                  cursor=cursor->next;
1145                }
1146                if (elem != NULL)
1147                  {
1148                    if (appendMapsToMaps
1149                        (*main_conf, testPresence, tmpmaps, elem) < 0)
1150                      {
1151                        return errorException (*main_conf,
1152                                               _("Unable to append maps to maps."),
1153                                               "InternalError",
1154                                               NULL);
1155                      }
1156                  }
1157              }
1158            else{
1159              addMapsToMaps (request_output, tmpmaps);
1160            }
1161          }
1162          freeMaps (&tmpmaps);
1163          free (tmpmaps);
1164          tmpmaps = NULL;
1165        }
1166    }
1167  return 1;
1168}
1169
1170/**
1171 * Parse a BoundingBoxData node
1172 *
1173 * http://schemas.opengis.net/ows/1.1.0/owsCommon.xsd: BoundingBoxType
1174 *
1175 * A map to store boundingbox information will contain:
1176 *  - LowerCorner : double double (minimum within this bounding box)
1177 *  - UpperCorner : double double (maximum within this bounding box)
1178 *  - crs : URI (Reference to definition of the CRS)
1179 *  - dimensions : int
1180 *
1181 * @param main_conf the conf maps containing the main.cfg settings
1182 * @param request_inputs the map storing KVP raw value
1183 * @param doc the xmlDocPtr containing the BoudingoxData node
1184 * @return a map containing all the bounding box keys
1185 */
1186int xmlParseBoundingBox(maps** main_conf,map** current_input,xmlDocPtr doc){
1187  xmlNode *root_element = xmlDocGetRootElement(doc);
1188  for(xmlAttrPtr attr = root_element->properties; NULL != attr; attr = attr->next){
1189    xmlChar *val = xmlGetProp (root_element, BAD_CAST attr->name);
1190    addToMap(*current_input,(char*)attr->name,(char*)val);
1191    xmlFree(val);
1192    xmlNodePtr cur = root_element->children;
1193    while(cur!=NULL && cur->type != XML_ELEMENT_NODE)
1194      cur=cur->next;
1195    while(cur!=NULL && cur->type==XML_ELEMENT_NODE){
1196      xmlChar *val =
1197        xmlNodeListGetString (doc, cur->xmlChildrenNode, 1);
1198      addToMap(*current_input,(char*)cur->name,(char*)val);
1199      cur=cur->next;
1200      xmlFree(val);
1201      while(cur!=NULL && cur->type != XML_ELEMENT_NODE)
1202        cur=cur->next;
1203    }
1204  }
1205  return 0;
1206}
1207
1208/**
1209 * Parse outputs from XML nodes and store them in a maps (WPS version 2.0.0).
1210 *
1211 * @param main_conf the conf maps containing the main.cfg settings
1212 * @param request_inputs the map storing KVP raw value
1213 * @param request_output the maps to store the KVP pairs
1214 * @param doc the xmlDocPtr containing the original request
1215 * @param cur the xmlNodePtr corresponding to the ResponseDocument or RawDataOutput XML node
1216 * @param raw true if the node is RawDataOutput, false in case of ResponseDocument
1217 * @return 0 on success, -1 on failure
1218 */
1219int xmlParseOutputs2(maps** main_conf,map** request_inputs,maps** request_output,xmlDocPtr doc,xmlNodeSet* nodes){
1220  int k = 0;
1221  int l = 0;
1222  for (k=0; k < nodes->nodeNr; k++){
1223    maps *tmpmaps = NULL;
1224    xmlNodePtr cur = nodes->nodeTab[k];
1225    if (cur->type == XML_ELEMENT_NODE){
1226      maps *tmpmaps = NULL;
1227      xmlChar *val = xmlGetProp (cur, BAD_CAST "id");
1228      if(val!=NULL)
1229        tmpmaps = createMaps((char *)val);
1230      else
1231        tmpmaps = createMaps("unknownIdentifier");
1232      const char ress[4][13] =
1233        { "mimeType", "encoding", "schema", "transmission" };
1234      xmlFree (val);
1235      for (l = 0; l < 4; l++){
1236        val = xmlGetProp (cur, BAD_CAST ress[l]);
1237        if (val != NULL && strlen ((char *) val) > 0)
1238          {
1239            if (tmpmaps->content != NULL)
1240              addToMap (tmpmaps->content, ress[l],
1241                        (char *) val);
1242            else
1243              tmpmaps->content =
1244                createMap (ress[l], (char *) val);
1245            if(l==3 && strncasecmp((char*)val,"reference",xmlStrlen(val))==0)
1246              addToMap (tmpmaps->content,"asReference","true");
1247          }
1248        xmlFree (val);
1249      }
1250      if(cur->children!=NULL){
1251        xmlNodePtr ccur = cur->children;
1252        while (ccur != NULL){
1253          if(ccur->type == XML_ELEMENT_NODE){
1254            char *xpathExpr=(char*)malloc(66+strlen(tmpmaps->name));
1255            sprintf(xpathExpr,"/*/*[local-name()='Output' and @id='%s']/*[local-name()='Output']",tmpmaps->name);           
1256            xmlXPathObjectPtr tmpsptr = extractFromDoc (doc, xpathExpr);
1257            xmlNodeSet* cnodes = tmpsptr->nodesetval;
1258            xmlParseOutputs2(main_conf,request_inputs,&tmpmaps->child,doc,cnodes);
1259            xmlXPathFreeObject (tmpsptr);
1260            free(xpathExpr);
1261            break;
1262          }
1263          ccur = ccur->next;
1264        }
1265      }
1266      if (*request_output == NULL){
1267        *request_output = dupMaps(&tmpmaps);
1268      }
1269      else{
1270        addMapsToMaps(request_output,tmpmaps);
1271      }
1272      freeMaps(&tmpmaps);
1273      free(tmpmaps);
1274    }
1275  }
1276  return 0;
1277}
1278
1279/**
1280 * Parse outputs from XML nodes and store them in a maps.
1281 *
1282 * @param main_conf the conf maps containing the main.cfg settings
1283 * @param request_inputs the map storing KVP raw value
1284 * @param request_output the maps to store the KVP pairs
1285 * @param doc the xmlDocPtr containing the original request
1286 * @param cur the xmlNodePtr corresponding to the ResponseDocument or RawDataOutput XML node
1287 * @param raw true if the node is RawDataOutput, false in case of ResponseDocument
1288 * @return 0 on success, -1 on failure
1289 */
1290int xmlParseOutputs(maps** main_conf,map** request_inputs,maps** request_output,xmlDocPtr doc,xmlNodePtr cur,bool raw){
1291  int l=0;
1292  if( raw == true)
1293    {
1294      addToMap (*request_inputs, "RawDataOutput", "");
1295      if (cur->type == XML_ELEMENT_NODE)
1296        {
1297
1298          maps *tmpmaps = createMaps("unknownIdentifier");
1299          if (tmpmaps == NULL)
1300            {
1301              return errorException (*main_conf, _("Unable to allocate memory"),
1302                                     "InternalError", NULL);
1303            }
1304
1305          // Get every attribute from a RawDataOutput node
1306          // mimeType, encoding, schema, uom
1307          const char *outs[4] =
1308            { "mimeType", "encoding", "schema", "uom" };
1309          for (l = 0; l < 4; l++)
1310            {
1311              xmlChar *val = xmlGetProp (cur, BAD_CAST outs[l]);
1312              if (val != NULL)
1313                {
1314                  if (strlen ((char *) val) > 0)
1315                    {
1316                      if (tmpmaps->content != NULL)
1317                        addToMap (tmpmaps->content, outs[l],
1318                                  (char *) val);
1319                      else
1320                        tmpmaps->content =
1321                          createMap (outs[l], (char *) val);
1322                    }
1323                  xmlFree (val);
1324                }
1325            }
1326          xmlNodePtr cur2 = cur->children;
1327          while (cur2 != NULL && cur2->type != XML_ELEMENT_NODE)
1328            cur2 = cur2->next;
1329          while (cur2 != NULL)
1330            {
1331              if (xmlStrncasecmp
1332                  (cur2->name, BAD_CAST "Identifier",
1333                   xmlStrlen (cur2->name)) == 0)
1334                {
1335                  xmlChar *val =
1336                    xmlNodeListGetString (NULL, cur2->xmlChildrenNode, 1);
1337                  free (tmpmaps->name);
1338                  tmpmaps->name = zStrdup ((char *) val);
1339                  xmlFree (val);
1340                }
1341              cur2 = cur2->next;
1342              while (cur2 != NULL && cur2->type != XML_ELEMENT_NODE)
1343                cur2 = cur2->next;
1344            }
1345          if (*request_output == NULL)
1346            *request_output = dupMaps (&tmpmaps);
1347          else
1348            addMapsToMaps (request_output, tmpmaps);
1349          if (tmpmaps != NULL)
1350            {
1351              freeMaps (&tmpmaps);
1352              free (tmpmaps);
1353              tmpmaps = NULL;
1354            }
1355        }
1356    }
1357  else
1358    {
1359      addToMap (*request_inputs, "ResponseDocument", "");
1360
1361      if (cur->type == XML_ELEMENT_NODE) {
1362        // Get every attribute: storeExecuteResponse, lineage, status
1363        const char *ress[3] =
1364          { "storeExecuteResponse", "lineage", "status" };
1365        xmlChar *val;
1366        for (l = 0; l < 3; l++)
1367          {
1368            val = xmlGetProp (cur, BAD_CAST ress[l]);
1369            if (val != NULL && strlen ((char *) val) > 0)
1370              {
1371                addToMap (*request_inputs, ress[l], (char *) val);
1372              }
1373            xmlFree (val);
1374          }
1375                       
1376        xmlNodePtr cur1 = cur->children;               
1377        while (cur1 != NULL) // iterate over Output nodes
1378          {
1379            if (cur1->type != XML_ELEMENT_NODE || 
1380                xmlStrncasecmp(cur1->name, BAD_CAST "Output", 
1381                               xmlStrlen (cur1->name)) != 0) {
1382              cur1 = cur1->next;
1383              continue;
1384            }
1385                               
1386            maps *tmpmaps = createMaps("unknownIdentifier"); // one per Output node
1387            if (tmpmaps == NULL) {
1388              return errorException (*main_conf,
1389                                     _
1390                                     ("Unable to allocate memory"),
1391                                     "InternalError", NULL);
1392            }
1393                               
1394            xmlNodePtr elems = cur1->children;
1395                               
1396            while (elems != NULL) {
1397
1398              // Identifier
1399              if (xmlStrncasecmp
1400                  (elems->name, BAD_CAST "Identifier",
1401                   xmlStrlen (elems->name)) == 0)
1402                {
1403                  xmlChar *val =
1404                    xmlNodeListGetString (doc, elems->xmlChildrenNode, 1);
1405               
1406                  free(tmpmaps->name);
1407                  tmpmaps->name = zStrdup ((char *) val);
1408                  if (tmpmaps->content == NULL) {
1409                    tmpmaps->content = createMap("Identifier", zStrdup ((char *) val));
1410                  }
1411                  else {
1412                    addToMap(tmpmaps->content, "Identifier", zStrdup ((char *) val));
1413                  }
1414
1415                  map* tt = getMap (*request_inputs, "ResponseDocument");
1416                  if (strlen(tt->value) == 0) {
1417                    addToMap (*request_inputs, "ResponseDocument",
1418                              (char *) val);
1419                  }
1420                  else {
1421                    char* tmp = (char*) malloc((strlen(tt->value) + 1 
1422                                                + strlen((char*) val) + 1) * sizeof(char));
1423                    sprintf (tmp, "%s;%s", tt->value, (char *) val);
1424                    free(tt->value);
1425                    tt->value = tmp;
1426                  }
1427                  xmlFree (val);
1428                }
1429             
1430              // Title, Abstract
1431              else if (xmlStrncasecmp(elems->name, BAD_CAST "Title",
1432                                      xmlStrlen (elems->name)) == 0
1433                       || xmlStrncasecmp(elems->name, BAD_CAST "Abstract",
1434                                         xmlStrlen (elems->name)) == 0)
1435                {
1436                  xmlChar *val =
1437                    xmlNodeListGetString (doc, elems->xmlChildrenNode, 1);
1438                                                       
1439                  if (tmpmaps->content == NULL) {
1440                    tmpmaps->content = createMap((char*) elems->name, zStrdup ((char *) val));
1441                  }
1442                  else {
1443                    addToMap(tmpmaps->content, (char*) elems->name, zStrdup ((char *) val));
1444                  }
1445                  xmlFree (val);
1446                }
1447              elems = elems->next;
1448            }
1449                               
1450            // Get every attribute from an Output node:
1451            // mimeType, encoding, schema, uom, asReference
1452            const char *outs[5] =
1453              { "mimeType", "encoding", "schema", "uom", "asReference" };
1454                                         
1455            for (l = 0; l < 5; l++) {
1456              xmlChar *val = xmlGetProp (cur1, BAD_CAST outs[l]);                               
1457              if (val != NULL && xmlStrlen(val) > 0) {
1458                if (tmpmaps->content != NULL) {
1459                  addToMap (tmpmaps->content, outs[l], (char *) val);
1460                }                         
1461                else {
1462                  tmpmaps->content = createMap (outs[l], (char *) val);
1463                }       
1464              }
1465              xmlFree (val);
1466            }
1467                               
1468            if (*request_output == NULL) {
1469              *request_output = tmpmaps;
1470            }   
1471            else if (getMaps(*request_output, tmpmaps->name) != NULL) {
1472              return errorException (*main_conf,
1473                                     _
1474                                     ("Duplicate <Output> elements in WPS Execute request"),
1475                                     "InternalError", NULL);
1476            }
1477            else {
1478              maps* mptr = *request_output;
1479              while (mptr->next != NULL) {
1480                mptr = mptr->next;
1481              }
1482              mptr->next = tmpmaps;     
1483            }                                   
1484            cur1 = cur1->next;
1485          }                     
1486      }
1487    }
1488  return 1;
1489}
1490
1491/**
1492 * Parse XML request and store information in maps.
1493 *
1494 * @param main_conf the conf maps containing the main.cfg settings
1495 * @param post the string containing the XML request
1496 * @param request_inputs the map storing KVP raw value
1497 * @param s the service
1498 * @param inputs the maps to store the KVP pairs
1499 * @param outputs the maps to store the KVP pairs
1500 * @param hInternet the HINTERNET queue to add potential requests
1501 * @return 0 on success, -1 on failure
1502 */
1503int xmlParseRequest(maps** main_conf,const char* post,map** request_inputs,service* s,maps** inputs,maps** outputs,HINTERNET* hInternet){
1504
1505  map* version=getMapFromMaps(*main_conf,"main","rversion");
1506  int vid=getVersionId(version->value);
1507
1508  xmlInitParser ();
1509  xmlDocPtr doc = xmlReadMemory (post, cgiContentLength, "input_request.xml", NULL, XML_PARSE_RECOVER);
1510
1511  /**
1512   * Extract Input nodes from the XML Request.
1513   */
1514  xmlXPathObjectPtr tmpsptr =
1515    extractFromDoc (doc, (vid==0?"/*/*/*[local-name()='Input']":"/*/*[local-name()='Input']"));
1516  xmlNodeSet *tmps = tmpsptr->nodesetval;
1517  if(tmps==NULL || xmlParseInputs(main_conf,s,inputs,doc,tmps,hInternet)<0){
1518    xmlXPathFreeObject (tmpsptr);
1519    xmlFreeDoc (doc);
1520    xmlCleanupParser ();
1521    return -1;
1522  }
1523  xmlXPathFreeObject (tmpsptr);
1524
1525  if(vid==1){
1526    tmpsptr =
1527      extractFromDoc (doc, "/*[local-name()='Execute']");
1528    bool asRaw = false;
1529    tmps = tmpsptr->nodesetval;
1530    if(tmps->nodeNr > 0){
1531      int k = 0;
1532      for (k=0; k < tmps->nodeNr; k++){
1533        maps *tmpmaps = NULL;
1534        xmlNodePtr cur = tmps->nodeTab[k];
1535        if (cur->type == XML_ELEMENT_NODE){
1536          xmlChar *val = xmlGetProp (cur, BAD_CAST "mode");
1537          if(val!=NULL)
1538            addToMap(*request_inputs,"mode",(char*)val);
1539          else
1540            addToMap(*request_inputs,"mode","auto");
1541          xmlFree(val);
1542          val = xmlGetProp (cur, BAD_CAST "response");
1543          if(val!=NULL){
1544            addToMap(*request_inputs,"response",(char*)val);
1545            if(strncasecmp((char*)val,"raw",xmlStrlen(val))==0)
1546              addToMap(*request_inputs,"RawDataOutput","");
1547            else
1548              addToMap(*request_inputs,"ResponseDocument","");
1549          }
1550          else{
1551            addToMap(*request_inputs,"response","document");
1552            addToMap(*request_inputs,"ResponseDocument","");
1553          }
1554          xmlFree(val);
1555        }
1556      }
1557    }
1558    xmlXPathFreeObject (tmpsptr);
1559    tmpsptr =
1560      extractFromDoc (doc, "/*/*[local-name()='Output']");
1561    tmps = tmpsptr->nodesetval;
1562    if(tmps->nodeNr > 0){
1563      if(xmlParseOutputs2(main_conf,request_inputs,outputs,doc,tmps)<0){
1564        xmlXPathFreeObject (tmpsptr);
1565        xmlFreeDoc (doc);
1566        xmlCleanupParser ();
1567        return -1;
1568      }
1569    }
1570  }
1571  else{
1572    // Extract ResponseDocument / RawDataOutput from the XML Request
1573    tmpsptr =
1574      extractFromDoc (doc, "/*/*/*[local-name()='ResponseDocument']");
1575    bool asRaw = false;
1576    tmps = tmpsptr->nodesetval;
1577    if (tmps->nodeNr == 0)
1578      {
1579        xmlXPathFreeObject (tmpsptr);
1580        tmpsptr =
1581          extractFromDoc (doc, "/*/*/*[local-name()='RawDataOutput']");
1582        tmps = tmpsptr->nodesetval;
1583        asRaw = true;
1584      }
1585    if(tmps->nodeNr != 0){
1586      if(xmlParseOutputs(main_conf,request_inputs,outputs,doc,tmps->nodeTab[0],asRaw)<0){
1587        xmlXPathFreeObject (tmpsptr);
1588        xmlFreeDoc (doc);
1589        xmlCleanupParser ();
1590        return -1;
1591      }
1592    }
1593  }
1594  xmlXPathFreeObject (tmpsptr);
1595  xmlFreeDoc (doc);
1596  xmlCleanupParser ();
1597  return 1;
1598}
1599
1600/**
1601 * Parse request and store information in maps.
1602 *
1603 * @param main_conf the conf maps containing the main.cfg settings
1604 * @param post the string containing the XML request
1605 * @param request_inputs the map storing KVP raw value
1606 * @param s the service
1607 * @param inputs the maps to store the KVP pairs
1608 * @param outputs the maps to store the KVP pairs
1609 * @param hInternet the HINTERNET queue to add potential requests
1610 * @return 0 on success, -1 on failure
1611 * @see kvpParseOutputs,kvpParseInputs,xmlParseRequest
1612 */
1613int parseRequest(maps** main_conf,map** request_inputs,service* s,maps** inputs,maps** outputs,HINTERNET* hInternet){
1614  map *postRequest = NULL;
1615  postRequest = getMap (*request_inputs, "xrequest");
1616  if (postRequest == NULLMAP)
1617    {
1618      if(kvpParseOutputs(main_conf,*request_inputs,outputs)<0){
1619        return -1;
1620      }
1621      if(kvpParseInputs(main_conf,s,*request_inputs,inputs,hInternet)<0){
1622        return -1;
1623      }
1624    }
1625  else
1626    {
1627      //Parse XML request
1628      if(xmlParseRequest(main_conf,postRequest->value,request_inputs,s,inputs,outputs,hInternet)<0){
1629        return -1;
1630      }
1631    }
1632  return 1;
1633}
1634
1635/**
1636 * Ensure that each requested arguments are present in the request
1637 * DataInputs and ResponseDocument / RawDataOutput. Potentially run
1638 * http requests from the queue in parallel.
1639 * For optional inputs add default values defined in the ZCFG file.
1640 *
1641 * @param main_conf
1642 * @param s
1643 * @param original_request
1644 * @param request_inputs
1645 * @param request_outputs
1646 * @param hInternet
1647 *
1648 * @see runHttpRequests
1649 */
1650int validateRequest(maps** main_conf,service* s,map* original_request, maps** request_inputs,maps** request_outputs,HINTERNET* hInternet){
1651
1652  map* errI0=NULL;
1653  runHttpRequests (main_conf, request_inputs, hInternet,&errI0);
1654  if(errI0!=NULL){
1655    printExceptionReportResponse (*main_conf, errI0);
1656    InternetCloseHandle (hInternet);
1657    return -1;
1658  }
1659  InternetCloseHandle (hInternet);
1660
1661
1662  map* errI=NULL;
1663  char *dfv = addDefaultValues (request_inputs, s->inputs, *main_conf, 0,&errI);
1664
1665  maps *ptr = *request_inputs;
1666  while (ptr != NULL)
1667    {
1668      map *tmp0 = getMap (ptr->content, "size");
1669      map *tmp1 = getMap (ptr->content, "maximumMegabytes");
1670      if (tmp1 != NULL && tmp0 != NULL)
1671        {
1672          float i = atof (tmp0->value) / 1048576.0;
1673          if (i >= atoi (tmp1->value))
1674            {
1675              char tmps[1024];
1676              map *tmpe = createMap ("code", "FileSizeExceeded");
1677              snprintf (tmps, 1024,
1678                        _
1679                        ("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)."),
1680                        ptr->name, tmp1->value, i);
1681              addToMap (tmpe, "locator", ptr->name);
1682              addToMap (tmpe, "text", tmps);
1683              printExceptionReportResponse (*main_conf, tmpe);
1684              freeMap (&tmpe);
1685              free (tmpe);
1686              return -1;
1687            }
1688        }
1689      ptr = ptr->next;
1690    }
1691
1692  map* errO=NULL;
1693  char *dfv1 =
1694    addDefaultValues (request_outputs, s->outputs, *main_conf, 1,&errO);
1695
1696  if (strcmp (dfv1, "") != 0 || strcmp (dfv, "") != 0)
1697    {
1698      char tmps[1024];
1699      map *tmpe = NULL;
1700      if (strcmp (dfv, "") != 0)
1701        {
1702          tmpe = createMap ("code", "MissingParameterValue");
1703          int nb=0;
1704          int length=1;
1705          map* len=getMap(errI,"length");
1706          if(len!=NULL)
1707            length=atoi(len->value);
1708          for(nb=0;nb<length;nb++){
1709            map* errp=getMapArray(errI,"value",nb);
1710            snprintf (tmps, 1024,
1711                      _
1712                      ("The <%s> argument was not specified in DataInputs but is required according to the ZOO ServicesProvider configuration file."),
1713                      errp->value);
1714            setMapArray (tmpe, "locator", nb , errp->value);
1715            setMapArray (tmpe, "text", nb , tmps);
1716            setMapArray (tmpe, "code", nb , "MissingParameterValue");
1717          }
1718        }
1719      if (strcmp (dfv1, "") != 0)
1720        {
1721          int ilength=0;
1722          if(tmpe==NULL)
1723            tmpe = createMap ("code", "InvalidParameterValue");
1724          else{
1725            map* len=getMap(tmpe,"length");
1726            if(len!=NULL)
1727              ilength=atoi(len->value);
1728          }
1729          int nb=0;
1730          int length=1;
1731          map* len=getMap(errO,"length");
1732          if(len!=NULL)
1733            length=atoi(len->value);
1734          for(nb=0;nb<length;nb++){
1735            map* errp=getMapArray(errO,"value",nb);
1736            snprintf (tmps, 1024,
1737                      _
1738                      ("The <%s> argument specified as %s identifier was not recognized (not defined in the ZOO Configuration File)."),
1739                      errp->value,
1740                      ((getMap(original_request,"RawDataOutput")!=NULL)?"RawDataOutput":"ResponseDocument"));
1741            setMapArray (tmpe, "locator", nb+ilength , errp->value);
1742            setMapArray (tmpe, "text", nb+ilength , tmps);
1743            setMapArray (tmpe, "code", nb+ilength , "InvalidParameterValue");
1744          }
1745        }
1746      printExceptionReportResponse (*main_conf, tmpe);
1747      if(errI!=NULL){
1748        freeMap(&errI);
1749        free(errI);
1750      }
1751      if(errO!=NULL){
1752        freeMap(&errO);
1753        free(errO);
1754      }
1755      freeMap (&tmpe);
1756      free (tmpe);
1757      return -1;
1758    }
1759  maps *tmpReqI = *request_inputs;
1760  while (tmpReqI != NULL)
1761    {
1762      char name[1024];
1763      if (getMap (tmpReqI->content, "isFile") != NULL)
1764        {
1765          if (cgiFormFileName (tmpReqI->name, name, sizeof (name)) ==
1766              cgiFormSuccess)
1767            {
1768              int BufferLen = 1024;
1769              cgiFilePtr file;
1770              int targetFile;
1771              char *storageNameOnServer;
1772              char *fileNameOnServer;
1773              char contentType[1024];
1774              char buffer[1024];
1775              char *tmpStr = NULL;
1776              int size;
1777              int got, t;
1778              map *path = getMapFromMaps (*main_conf, "main", "tmpPath");
1779              cgiFormFileSize (tmpReqI->name, &size);
1780              cgiFormFileContentType (tmpReqI->name, contentType,
1781                                      sizeof (contentType));
1782              if (cgiFormFileOpen (tmpReqI->name, &file) == cgiFormSuccess)
1783                {
1784                  t = -1;
1785                  while (1)
1786                    {
1787                      tmpStr = strstr (name + t + 1, "\\");
1788                      if (NULL == tmpStr)
1789                        tmpStr = strstr (name + t + 1, "/");
1790                      if (NULL != tmpStr)
1791                        t = (int) (tmpStr - name);
1792                      else
1793                        break;
1794                    }
1795                  fileNameOnServer=(char*)malloc((strlen(name) - t - 1 )*sizeof(char));
1796                  strcpy (fileNameOnServer, name + t + 1);
1797
1798                  storageNameOnServer=(char*)malloc((strlen(path->value) + strlen(fileNameOnServer) + 2)*sizeof(char));
1799                  sprintf (storageNameOnServer, "%s/%s", path->value,
1800                           fileNameOnServer);
1801#ifdef DEBUG
1802                  fprintf (stderr, "Name on server %s\n",
1803                           storageNameOnServer);
1804                  fprintf (stderr, "fileNameOnServer: %s\n",
1805                           fileNameOnServer);
1806#endif
1807                  targetFile =
1808                    open (storageNameOnServer, O_RDWR | O_CREAT | O_TRUNC,
1809                          S_IRWXU | S_IRGRP | S_IROTH);
1810                  if (targetFile < 0)
1811                    {
1812#ifdef DEBUG
1813                      fprintf (stderr, "could not create the new file,%s\n",
1814                               fileNameOnServer);
1815#endif
1816                    }
1817                  else
1818                    {
1819                      while (cgiFormFileRead (file, buffer, BufferLen, &got)
1820                             == cgiFormSuccess)
1821                        {
1822                          if (got > 0)
1823                            write (targetFile, buffer, got);
1824                        }
1825                    }
1826                  addToMap (tmpReqI->content, "lref", storageNameOnServer);
1827                  cgiFormFileClose (file);
1828                  close (targetFile);
1829                  free(fileNameOnServer);
1830                  free(storageNameOnServer);
1831#ifdef DEBUG
1832                  fprintf (stderr, "File \"%s\" has been uploaded",
1833                           fileNameOnServer);
1834#endif
1835                }
1836            }
1837        }
1838      tmpReqI = tmpReqI->next;
1839    }
1840
1841  ensureDecodedBase64 (request_inputs);
1842  return 1;
1843}
1844
1845
1846/**
1847 * Verify if a parameter value is valid.
1848 *
1849 * @param request the request map
1850 * @param res the error map potentially generated
1851 * @param toCheck the parameter to use
1852 * @param avalues the acceptable values (or null if testing only for presence)
1853 * @param mandatory verify the presence of the parameter if mandatory > 0
1854 */
1855void checkValidValue(map* request,map** res,const char* toCheck,const char** avalues,int mandatory){
1856  map* lres=*res;
1857  map* r_inputs = getMap (request,toCheck);
1858  if (r_inputs == NULL){
1859    if(mandatory>0){
1860      char *replace=_("Mandatory parameter <%s> was not specified");
1861      char *message=(char*)malloc((strlen(replace)+strlen(toCheck)+1)*sizeof(char));
1862      sprintf(message,replace,toCheck);
1863      if(lres==NULL){
1864        lres=createMap("code","MissingParameterValue");
1865        addToMap(lres,"text",message);
1866        addToMap(lres,"locator",toCheck);       
1867      }else{
1868        int length=1;
1869        map* len=getMap(lres,"length");
1870        if(len!=NULL){
1871          length=atoi(len->value);
1872        }
1873        setMapArray(lres,"text",length,message);
1874        setMapArray(lres,"locator",length,toCheck);
1875        setMapArray(lres,"code",length,"MissingParameterValue");
1876      }
1877      free(message);
1878    }
1879  }else{
1880    if(avalues==NULL)
1881      return;
1882    int nb=0;
1883    int hasValidValue=-1;
1884    if(strncasecmp(toCheck,"Accept",6)==0){
1885      char *tmp=zStrdup(r_inputs->value);
1886      char *pToken,*saveptr;
1887      pToken=strtok_r(tmp,",",&saveptr);
1888      while(pToken!=NULL){
1889        while(avalues[nb]!=NULL){
1890          if(strcasecmp(avalues[nb],pToken)==0){
1891            hasValidValue=1;
1892            break;
1893          }
1894          nb++;
1895        }
1896        pToken=strtok_r(NULL,",",&saveptr);
1897      }
1898      free(tmp);
1899    }else{
1900      while(avalues[nb]!=NULL){
1901        if(strcasecmp(avalues[nb],r_inputs->value)==0){
1902          hasValidValue=1;
1903          break;
1904        }
1905        nb++;
1906      }
1907    }
1908    if(hasValidValue<0){
1909      char *replace=_("The value <%s> was not recognized, %s %s the only acceptable value.");
1910      nb=0;
1911      char *vvalues=NULL;
1912      char* num=_("is");
1913      while(avalues[nb]!=NULL){
1914        char *tvalues;
1915        if(vvalues==NULL){
1916          vvalues=(char*)malloc((strlen(avalues[nb])+3)*sizeof(char));
1917          sprintf(vvalues,"%s",avalues[nb]);
1918        }
1919        else{
1920          tvalues=zStrdup(vvalues);
1921          vvalues=(char*)realloc(vvalues,(strlen(tvalues)+strlen(avalues[nb])+3)*sizeof(char));
1922          sprintf(vvalues,"%s, %s",tvalues,avalues[nb]);
1923          free(tvalues);
1924          num=_("are");
1925        }
1926        nb++;
1927      }
1928      char *message=(char*)malloc((strlen(replace)+strlen(num)+strlen(vvalues)+strlen(toCheck)+1)*sizeof(char));
1929      sprintf(message,replace,toCheck,vvalues,num);
1930      const char *code="VersionNegotiationFailed";
1931      code="InvalidParameterValue";
1932      const char *locator=toCheck;
1933      if( strncasecmp(toCheck,"version",7)==0 ||
1934          strncasecmp(toCheck,"AcceptVersions",14)==0 )
1935        code="VersionNegotiationFailed";
1936      if( strncasecmp(toCheck,"request",7)==0){
1937        code="OperationNotSupported";
1938        locator=r_inputs->value;
1939      }
1940      if(lres==NULL){
1941        lres=createMap("code",code);
1942        addToMap(lres,"text",message);
1943        addToMap(lres,"locator",locator);       
1944      }else{
1945        int length=1;
1946        map* len=getMap(lres,"length");
1947        if(len!=NULL){
1948          length=atoi(len->value);
1949        }
1950        setMapArray(lres,"text",length,message);
1951        setMapArray(lres,"locator",length,locator);
1952        setMapArray(lres,"code",length,code);
1953      }
1954    }
1955  }
1956  if(lres!=NULL){
1957    *res=lres;
1958  }
1959}
1960
1961/**
1962 * Parse cookie contained in request headers.
1963 *
1964 * @param conf the conf maps containinfg the main.cfg
1965 * @param cookie the
1966 */
1967void parseCookie(maps** conf,const char* cookie){
1968  char* tcook=zStrdup(cookie);
1969  char *token, *saveptr;
1970  token = strtok_r (tcook, "; ", &saveptr);
1971  maps* res=createMaps("cookies");
1972  while (token != NULL){
1973    char *token1, *saveptr1, *name;
1974    int i=0;
1975    token1 = strtok_r (token, "=", &saveptr1);
1976    while (token1 != NULL){
1977      if(i==0){
1978        name=zStrdup(token1);
1979        i++;
1980      }
1981      else{
1982        if(res->content==NULL)
1983          res->content=createMap(name,token1);
1984        else
1985          addToMap(res->content,name,token1);
1986        free(name);
1987        name=NULL;
1988        i=0;
1989      }
1990      token1 = strtok_r (NULL, "=", &saveptr1);
1991    }
1992    if(name!=NULL)
1993      free(name);
1994    token = strtok_r (NULL, "; ", &saveptr);
1995  }
1996  addMapsToMaps(conf,res);
1997  freeMaps(&res);
1998  free(res);
1999  free(tcook);
2000}
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