Imported Upstream version 2.2.1+dfsg
[shibboleth/sp.git] / shibsp / util / CGIParser.cpp
1 /*
2  *  Copyright 2001-2007 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/util/URLEncoder.h>
28
29 using namespace shibsp;
30 using namespace xmltooling;
31 using namespace std;
32
33
34 CGIParser::CGIParser(const HTTPRequest& request)
35 {
36     const char* pch=NULL;
37     if (!strcmp(request.getMethod(),"POST"))
38         pch=request.getRequestBody();
39     else
40         pch=request.getQueryString();
41     size_t cl=pch ? strlen(pch) : 0;
42     
43     const URLEncoder* dec = XMLToolingConfig::getConfig().getURLEncoder();
44     while (cl && pch) {
45         char *name;
46         char *value;
47         value=fmakeword('&',&cl,&pch);
48         plustospace(value);
49         dec->decode(value);
50         name=makeword(value,'=');
51         kvp_map.insert(pair<const string,char*>(name,value));
52         free(name);
53     }
54 }
55
56 CGIParser::~CGIParser()
57 {
58     for (multimap<string,char*>::iterator i=kvp_map.begin(); i!=kvp_map.end(); i++)
59         free(i->second);
60 }
61
62 pair<CGIParser::walker,CGIParser::walker> CGIParser::getParameters(const char* name) const
63 {
64     if (name)
65         return kvp_map.equal_range(name);
66     return make_pair(kvp_map.begin(), kvp_map.end());
67 }
68
69 /* Parsing routines modified from NCSA source. */
70 char* CGIParser::makeword(char *line, char stop)
71 {
72     int x = 0,y;
73     char *word = (char *) malloc(sizeof(char) * (strlen(line) + 1));
74
75     for(x=0;((line[x]) && (line[x] != stop));x++)
76         word[x] = line[x];
77
78     word[x] = '\0';
79     if(line[x])
80         ++x;
81     y=0;
82
83     while(line[x])
84       line[y++] = line[x++];
85     line[y] = '\0';
86     return word;
87 }
88
89 char* CGIParser::fmakeword(char stop, size_t *cl, const char** ppch)
90 {
91     int wsize;
92     char *word;
93     int ll;
94
95     wsize = 1024;
96     ll=0;
97     word = (char *) malloc(sizeof(char) * (wsize + 1));
98
99     while(1)
100     {
101         word[ll] = *((*ppch)++);
102         if(ll==wsize-1)
103         {
104             word[ll+1] = '\0';
105             wsize+=1024;
106             word = (char *)realloc(word,sizeof(char)*(wsize+1));
107         }
108         --(*cl);
109         if((word[ll] == stop) || word[ll] == EOF || (!(*cl)))
110         {
111             if(word[ll] != stop)
112                 ll++;
113             word[ll] = '\0';
114             return word;
115         }
116         ++ll;
117     }
118 }
119
120 void CGIParser::plustospace(char *str)
121 {
122     register int x;
123
124     for(x=0;str[x];x++)
125         if(str[x] == '+') str[x] = ' ';
126 }