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

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

Fix issue in kvParseInput when memory!=load and handle session from the OGC API - Processes

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