Moved URLEncoder down to tooling lib, added exception->querystring method.
[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 "util/CGIParser.h"
25
26 #include <xmltooling/XMLToolingConfig.h>
27 #include <xmltooling/util/URLEncoder.h>
28
29 using namespace opensaml;
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<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     return kvp_map.equal_range(name);
65 }
66
67 /* Parsing routines modified from NCSA source. */
68 char* CGIParser::makeword(char *line, char stop)
69 {
70     int x = 0,y;
71     char *word = (char *) malloc(sizeof(char) * (strlen(line) + 1));
72
73     for(x=0;((line[x]) && (line[x] != stop));x++)
74         word[x] = line[x];
75
76     word[x] = '\0';
77     if(line[x])
78         ++x;
79     y=0;
80
81     while(line[x])
82       line[y++] = line[x++];
83     line[y] = '\0';
84     return word;
85 }
86
87 char* CGIParser::fmakeword(char stop, size_t *cl, const char** ppch)
88 {
89     int wsize;
90     char *word;
91     int ll;
92
93     wsize = 1024;
94     ll=0;
95     word = (char *) malloc(sizeof(char) * (wsize + 1));
96
97     while(1)
98     {
99         word[ll] = *((*ppch)++);
100         if(ll==wsize-1)
101         {
102             word[ll+1] = '\0';
103             wsize+=1024;
104             word = (char *)realloc(word,sizeof(char)*(wsize+1));
105         }
106         --(*cl);
107         if((word[ll] == stop) || word[ll] == EOF || (!(*cl)))
108         {
109             if(word[ll] != stop)
110                 ll++;
111             word[ll] = '\0';
112             return word;
113         }
114         ++ll;
115     }
116 }
117
118 void CGIParser::plustospace(char *str)
119 {
120     register int x;
121
122     for(x=0;str[x];x++)
123         if(str[x] == '+') str[x] = ' ';
124 }