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

Last change on this file since 962 was 962, checked in by djay, 2 years ago

Update OGC API - Processes documentation and implementation, providing a browsable User Interface to Processes.

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