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

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

Add the optional handleText parameter in the main section of the main.cfg file to make sure that text node provided in multiple CDATA nodes child of the complex data are pure text.

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