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

Last change on this file since 890 was 890, checked in by djay, 5 years ago

Make this ZOO-Kernel working properly on windows platform again.

  • Property svn:keywords set to Id
File size: 56.8 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=zStrdup(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=zStrdup(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                                  zStrdup ((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                    zOpen (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                  zClose (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