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

Last change on this file since 957 was 957, checked in by knut, 4 years ago

Added function for allocating memory for map values (allocateMapValue). Fixed issue with getting attributes from input data node. Added code to support MIME subtype attributes in key-value pairs.

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