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