VS10 solution files, convert from NULL macro to nullptr.
[shibboleth/sp.git] / shibsp / util / CGIParser.cpp
1 /*
2  *  Copyright 2001-2010 Internet2
3  * 
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 /**
18  * CGIParser.cpp
19  * 
20  * CGI GET/POST parameter parsing.
21  */
22
23 #include "internal.h"
24 #include "util/CGIParser.h"
25
26 #include <xmltooling/XMLToolingConfig.h>
27 #include <xmltooling/io/HTTPRequest.h>
28 #include <xmltooling/util/URLEncoder.h>
29
30 using namespace shibsp;
31 using namespace xmltooling;
32 using namespace std;
33
34
35 CGIParser::CGIParser(const HTTPRequest& request)
36 {
37     const char* pch=nullptr;
38     if (!strcmp(request.getMethod(),"POST"))
39         pch=request.getRequestBody();
40     else
41         pch=request.getQueryString();
42     size_t cl=pch ? strlen(pch) : 0;
43     
44     const URLEncoder* dec = XMLToolingConfig::getConfig().getURLEncoder();
45     while (cl && pch) {
46         char *name;
47         char *value;
48         value=fmakeword('&',&cl,&pch);
49         plustospace(value);
50         dec->decode(value);
51         name=makeword(value,'=');
52         kvp_map.insert(pair<const string,char*>(name,value));
53         free(name);
54     }
55 }
56
57 CGIParser::~CGIParser()
58 {
59     for (multimap<string,char*>::iterator i=kvp_map.begin(); i!=kvp_map.end(); i++)
60         free(i->second);
61 }
62
63 pair<CGIParser::walker,CGIParser::walker> CGIParser::getParameters(const char* name) const
64 {
65     if (name)
66         return kvp_map.equal_range(name);
67     return make_pair(kvp_map.begin(), kvp_map.end());
68 }
69
70 /* Parsing routines modified from NCSA source. */
71 char* CGIParser::makeword(char *line, char stop)
72 {
73     int x = 0,y;
74     char *word = (char *) malloc(sizeof(char) * (strlen(line) + 1));
75
76     for(x=0;((line[x]) && (line[x] != stop));x++)
77         word[x] = line[x];
78
79     word[x] = '\0';
80     if(line[x])
81         ++x;
82     y=0;
83
84     while(line[x])
85       line[y++] = line[x++];
86     line[y] = '\0';
87     return word;
88 }
89
90 char* CGIParser::fmakeword(char stop, size_t *cl, const char** ppch)
91 {
92     int wsize;
93     char *word;
94     int ll;
95
96     wsize = 1024;
97     ll=0;
98     word = (char *) malloc(sizeof(char) * (wsize + 1));
99
100     while(1)
101     {
102         word[ll] = *((*ppch)++);
103         if(ll==wsize-1)
104         {
105             word[ll+1] = '\0';
106             wsize+=1024;
107             word = (char *)realloc(word,sizeof(char)*(wsize+1));
108         }
109         --(*cl);
110         if((word[ll] == stop) || word[ll] == EOF || (!(*cl)))
111         {
112             if(word[ll] != stop)
113                 ll++;
114             word[ll] = '\0';
115             return word;
116         }
117         ++ll;
118     }
119 }
120
121 void CGIParser::plustospace(char *str)
122 {
123     register int x;
124
125     for(x=0;str[x];x++)
126         if(str[x] == '+') str[x] = ' ';
127 }