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

Last change on this file since 933 was 933, checked in by knut, 5 years ago

Resolve certain string-related type conflicts, e.g., char* vs. const char* or char[N], that may cause errors in some build environments. Resolve a problem with the include order of fcgi_stdio.h (note: should verify that this harmonizes with resolution of same problem in trunk).

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

Search

Context Navigation

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