summaryrefslogtreecommitdiffabout
authorMichael Krelin <hacker@klever.net>2005-03-31 22:06:45 (UTC)
committer Michael Krelin <hacker@klever.net>2005-03-31 22:06:45 (UTC)
commit0942697ed6ee058809db963f9cc3126f93139de2 (patch) (unidiff)
tree2a5cdf5d200e302a6d6394e4a0193929dcb11bb0
parent5b50415afdb7b708874293ac7047b9b70de78e59 (diff)
downloadkingate-0942697ed6ee058809db963f9cc3126f93139de2.zip
kingate-0942697ed6ee058809db963f9cc3126f93139de2.tar.gz
kingate-0942697ed6ee058809db963f9cc3126f93139de2.tar.bz2
1. renamed url_escape/unescape to encode/decode
2. introduced a number of wrappers for accessing meta-variables mentioned in RFC3875 3. bumped library version info
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--include/kingate/cgi_gateway.h117
-rw-r--r--include/kingate/exception.h9
-rw-r--r--include/kingate/util.h35
-rw-r--r--src/Makefile.am2
-rw-r--r--src/cgi_gateway.cc175
-rw-r--r--src/util.cc4
6 files changed, 316 insertions, 26 deletions
diff --git a/include/kingate/cgi_gateway.h b/include/kingate/cgi_gateway.h
index f683580..a5c4056 100644
--- a/include/kingate/cgi_gateway.h
+++ b/include/kingate/cgi_gateway.h
@@ -1,18 +1,26 @@
1#ifndef __KINGATE_CGI_GATEWAY_H 1#ifndef __KINGATE_CGI_GATEWAY_H
2#define __KINGATE_CGI_GATEWAY_H 2#define __KINGATE_CGI_GATEWAY_H
3 3
4#include <map> 4#include <map>
5#include "kingate/cgi_interface.h" 5#include "kingate/cgi_interface.h"
6 6
7#ifndef __deprecated
8#if ( __GNUC__ == 3 && __GNUC_MINOR__ > 0 ) || __GNUC__ > 3
9#define __deprecated __attribute__((deprecated))
10#else
11#define __deprecated
12#endif
13#endif
14
7/** 15/**
8 * @file 16 * @file
9 * @brief the cgi_gateway -- main interface to CGI. 17 * @brief the cgi_gateway -- main interface to CGI.
10 */ 18 */
11 19
12namespace kingate { 20namespace kingate {
13 using namespace std; 21 using namespace std;
14 22
15 /** 23 /**
16 * The main class interfacing with the CGI environment. 24 * The main class interfacing with the CGI environment.
17 */ 25 */
18 class cgi_gateway { 26 class cgi_gateway {
@@ -50,25 +58,25 @@ namespace kingate {
50 * @return true if yes. 58 * @return true if yes.
51 * @see cgi_interface::has_meta() 59 * @see cgi_interface::has_meta()
52 * @see get_meta() 60 * @see get_meta()
53 */ 61 */
54 bool has_meta(const string& n) const { return iface.has_meta(n); } 62 bool has_meta(const string& n) const { return iface.has_meta(n); }
55 /** 63 /**
56 * Retrieve the 'environment' meta-variable value. 64 * Retrieve the 'environment' meta-variable value.
57 * @param n variable name. 65 * @param n variable name.
58 * @return variable contents. 66 * @return variable contents.
59 * @see exception_notfound 67 * @see exception_notfound
60 * @see cgi_interface::get_meta() 68 * @see cgi_interface::get_meta()
61 */ 69 */
62 string get_meta(const string& n) const { return iface.get_meta(n); } 70 const string& get_meta(const string& n) const { return iface.get_meta(n); }
63 71
64 /** 72 /**
65 * fetch reference to the 'stdin' stream. 73 * fetch reference to the 'stdin' stream.
66 * @return the reference to the corresponding istream object. 74 * @return the reference to the corresponding istream object.
67 * @see cgi_interface::in() 75 * @see cgi_interface::in()
68 */ 76 */
69 istream& in() { return iface.in(); } 77 istream& in() { return iface.in(); }
70 /** 78 /**
71 * fetch reference to the 'stdout' stream. 79 * fetch reference to the 'stdout' stream.
72 * @return the reference to the corresponding ostream object. 80 * @return the reference to the corresponding ostream object.
73 * @see cgi_interface::out() 81 * @see cgi_interface::out()
74 */ 82 */
@@ -89,72 +97,169 @@ namespace kingate {
89 /** 97 /**
90 * Check to see whether the parameter was passed via GET. 98 * Check to see whether the parameter was passed via GET.
91 * @param n the parameter name. 99 * @param n the parameter name.
92 * @return true if yes. 100 * @return true if yes.
93 */ 101 */
94 bool has_GET(const string& n) const; 102 bool has_GET(const string& n) const;
95 /** 103 /**
96 * Retrieve the parameter passed via GET. 104 * Retrieve the parameter passed via GET.
97 * @param n the parameter name. 105 * @param n the parameter name.
98 * @return the parameter contents. 106 * @return the parameter contents.
99 * @see exception_notfound 107 * @see exception_notfound
100 */ 108 */
101 string get_GET(const string& n) const; 109 const string& get_GET(const string& n) const;
102 /** 110 /**
103 * Check to see whether the parameter was passed via POST. 111 * Check to see whether the parameter was passed via POST.
104 * @param n the parameter name. 112 * @param n the parameter name.
105 * @return true if yes. 113 * @return true if yes.
106 */ 114 */
107 bool has_POST(const string& n) const; 115 bool has_POST(const string& n) const;
108 /** 116 /**
109 * Retrieve the POST-parameter. 117 * Retrieve the POST-parameter.
110 * @param n the parameter name. 118 * @param n the parameter name.
111 * @return the parameter contents. 119 * @return the parameter contents.
112 * @see exception_notfound 120 * @see exception_notfound
113 */ 121 */
114 string get_POST(const string& n) const; 122 const string& get_POST(const string& n) const;
115 /** 123 /**
116 * Check to see whether the parameter was passed either via POST or 124 * Check to see whether the parameter was passed either via POST or
117 * GET. 125 * GET.
118 * @param n the parameter name. 126 * @param n the parameter name.
119 * @return true if yes. 127 * @return true if yes.
120 */ 128 */
121 bool has_param(const string& n) const; 129 bool has_param(const string& n) const;
122 /** 130 /**
123 * Retrieve the parameter passed either via POST or GET 131 * Retrieve the parameter passed either via POST or GET
124 * (GET-parameter takes precedence). 132 * (GET-parameter takes precedence).
125 * @param n the parameter name. 133 * @param n the parameter name.
126 * @return true if yes. 134 * @return true if yes.
127 * @see exception_notfound. 135 * @see exception_notfound.
128 */ 136 */
129 string get_param(const string& n) const; 137 const string& get_param(const string& n) const;
130 138
131 /** 139 /**
132 * Retrieve the POST content-type (as passed via CONTENT_TYPE 140 * Retrieve the POST content-type (as passed via CONTENT_TYPE
133 * environment variable). 141 * environment variable).
134 * @return the content type. 142 * @return the content type.
135 */ 143 */
136 const string& get_content_type() const; 144 const string& __deprecated get_content_type() const;
137 /** 145 /**
138 * Retrieve the POST content length (as passed via the 146 * Retrieve the POST content length (as passed via the
139 * CONTENT_LENGTH environment variable). 147 * CONTENT_LENGTH environment variable).
140 * @return the content length. 148 * @return the content length.
141 */ 149 */
142 unsigned long get_content_length() const; 150 unsigned long __deprecated get_content_length() const;
143 151
144 /** 152 /**
145 * Check to see whether the content from stdin stream was parsed. 153 * Check to see whether the content from stdin stream was parsed.
146 * @return true if yes. 154 * @return true if yes.
147 */ 155 */
148 bool is_content_parsed() const { return b_parsed_content; } 156 bool is_content_parsed() const { return b_parsed_content; }
157
158 /**
159 * Retrieve the HTTP header value from the HTTP_ meta-variable.
160 * (see RFC3875)
161 * @param hn header field name.
162 * @return the HTTP header value.
163 */
164 const string& http_request_header(const string& hn) const;
165
166 /**
167 * Retrieve the AUTH_TYPE meta-variable (see RFC3875)
168 * @return authentication type.
169 */
170 const string& auth_type() const;
171 /**
172 * Retrieve the CONTENT_LENGTH meta-variable (see RFC3875)
173 * @return size of the request message body.
174 */
175 unsigned long cgi_gateway::content_length() const;
176 /**
177 * Retrieve the CONTENT_TYPE meta-variable (see RFC3875)
178 * @return media type of the request message body.
179 */
180 const string& content_type() const;
181 /**
182 * Retrieve the GATEWAY_INTERFACE meta-variable (see RFC3875)
183 * @return the gateway interface dialect.
184 */
185 const string& gateway_interface() const;
186 /**
187 * Retrieve the PATH_INFO meta-variable (see RFC3875)
188 * @return path to be interpreted by the script.
189 */
190 const string& path_info() const;
191 /**
192 * Retrieve the PATH_TRANSLATED meta-variable (see RFC3875)
193 * @return the translated path to the document.
194 */
195 const string& path_translated() const;
196 /**
197 * Retrieve the QUERY_STRING meta-variable (see RFC3875)
198 * @return the query string.
199 */
200 const string& query_string() const;
201 /**
202 * Retrieve the REMOTE_ADDR meta-variable (see RFC3875)
203 * @return the network address of the remote host.
204 */
205 const string& remote_addr() const;
206 /**
207 * Retrieve the REMOTE_HOST meta-variable (see RFC3875)
208 * @return the fully qualified domain name of the client if
209 * available. REMOTE_ADDR otherwise.
210 * @see remote_addr()
211 */
212 const string& remote_host() const;
213 /**
214 * Retrieve the REMOTE_IDENT meta-variable (see RFC3875)
215 * @return remote user identity (see RFC1413).
216 */
217 const string& remote_ident() const;
218 /**
219 * Retrieve the REMOTE_USER meta-variable (see RFC3875)
220 * @return the authenticated user name.
221 */
222 const string& remote_user() const;
223 /**
224 * Retrieve the REQUEST_METHOD meta-variable (see RFC3875)
225 * @return the http request method.
226 */
227 const string& request_method() const;
228 /**
229 * Retrieve the SCRIPT_NAME meta-variable (see RFC3875)
230 * @return the uri path identifying the script.
231 */
232 const string& script_name() const;
233 /**
234 * Retrieve the SERVER_NAME meta-variable (see RFC3875)
235 * @return the server name of the script.
236 */
237 const string& server_name() const;
238 /**
239 * Retrieve the SERVER_PORT meta-variable (see RFC3875)
240 * @return the port on which request was received.
241 */
242 unsigned int server_port() const;
243 /**
244 * Retrieve the SERVER_PROTOCOL meta-variable (see RFC3875)
245 * @return the protocol used for the request.
246 */
247 const string& server_protocol() const;
248 /**
249 * Retrieve the SERVER_SOFTWARE meta-variable (see RFC3875)
250 * @return the name and version of server software.
251 */
252 const string& server_software() const;
253
149 private: 254 private:
150 /** 255 /**
151 * Parse the query string, putting the parameters into the map 256 * Parse the query string, putting the parameters into the map
152 * specified. 257 * specified.
153 * @param q the query string. 258 * @param q the query string.
154 * @param p destination parameters map. 259 * @param p destination parameters map.
155 */ 260 */
156 static void parse_query(string& q,params_t& p); 261 static void parse_query(string& q,params_t& p);
157 }; 262 };
158 263
159} 264}
160 265
diff --git a/include/kingate/exception.h b/include/kingate/exception.h
index 6ebb361..85d89ea 100644
--- a/include/kingate/exception.h
+++ b/include/kingate/exception.h
@@ -27,18 +27,27 @@ namespace kingate {
27 }; 27 };
28 28
29 /** 29 /**
30 * Thrown if the specified variable or parameter wasn't found. 30 * Thrown if the specified variable or parameter wasn't found.
31 */ 31 */
32 class exception_notfound : public exception { 32 class exception_notfound : public exception {
33 public: 33 public:
34 explicit exception_notfound(const string& w) 34 explicit exception_notfound(const string& w)
35 : exception(w) { } 35 : exception(w) { }
36 exception_notfound(const string& fi,const string& fu,int l,const string& w) 36 exception_notfound(const string& fi,const string& fu,int l,const string& w)
37 : exception(fi,fu,l,w) { } 37 : exception(fi,fu,l,w) { }
38 }; 38 };
39
40 /**
41 * Thrown in case of unexpected server behaviour.
42 */
43 class server_error : public exception {
44 public:
45 server_error(const string& fi,const string& fu,int l,const string& w)
46 : exception(fi,fu,l,w) { }
47 };
39} 48}
40 49
41#endif /* __KINGATE_EXCEPTION_H */ 50#endif /* __KINGATE_EXCEPTION_H */
42/* 51/*
43 * vim:set ft=cpp: 52 * vim:set ft=cpp:
44 */ 53 */
diff --git a/include/kingate/util.h b/include/kingate/util.h
index 4b0dca8..6024ccf 100644
--- a/include/kingate/util.h
+++ b/include/kingate/util.h
@@ -1,26 +1,49 @@
1#ifndef __KINGATE_UTIL_H 1#ifndef __KINGATE_UTIL_H
2#define __KINGATE_UTIL_H 2#define __KINGATE_UTIL_H
3 3
4#include <string> 4#include <string>
5 5
6#ifndef __deprecated
7#if ( __GNUC__ == 3 && __GNUC_MINOR__ > 0 ) || __GNUC__ > 3
8#define __deprecated __attribute__((deprecated))
9#else
10#define __deprecated
11#endif
12#endif
13
6namespace kingate { 14namespace kingate {
7 using namespace std; 15 using namespace std;
8 16
9 /** 17 /**
10 * Escape string for passing via URL. 18 * Encode string for passing via URL.
11 * @param str string unescaped. 19 * @param str string unencoded.
12 * @return the escaped string. 20 * @return the encoded string.
13 */ 21 */
14 string url_escape(const string& str); 22 string url_encode(const string& str);
15 /** 23 /**
16 * Remove URL-encoding from the string. 24 * Remove URL-encoding from the string.
17 * @param str the URL-encoded string. 25 * @param str the URL-encoded string.
18 * @return the unescaped string. 26 * @return the decoded string.
27 */
28 string url_decode(const string& str);
29
30 /**
31 * deprecated alias to url_encode.
32 * @see url_encode
33 */
34 inline string __deprecated url_escape(const string& str) {
35 return url_encode(str);
36 }
37 /**
38 * deprecated alias to url_decode.
39 * @see url_decode
19 */ 40 */
20 string url_unescape(const string& str); 41 inline string __deprecated url_unescape(const string& str) {
42 return url_decode(str);
43 }
21} 44}
22 45
23#endif /* __KINGATE_UTIL_H */ 46#endif /* __KINGATE_UTIL_H */
24/* 47/*
25 * vim:set ft=cpp: 48 * vim:set ft=cpp:
26 */ 49 */
diff --git a/src/Makefile.am b/src/Makefile.am
index d516d37..12bb1f8 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -3,23 +3,23 @@ lib_LTLIBRARIES = libkingate.la libkingate-plaincgi.la
3if HAVE_FCGI 3if HAVE_FCGI
4lib_LTLIBRARIES += libkingate-fcgi.la 4lib_LTLIBRARIES += libkingate-fcgi.la
5endif 5endif
6 6
7INCLUDES = -I${top_srcdir}/include -I${top_srcdir} 7INCLUDES = -I${top_srcdir}/include -I${top_srcdir}
8AM_CXXFLAGS = ${KONFORKA_CFLAGS} 8AM_CXXFLAGS = ${KONFORKA_CFLAGS}
9LDADD = ${KONFORKA_LIBS} 9LDADD = ${KONFORKA_LIBS}
10 10
11libkingate_la_SOURCES = \ 11libkingate_la_SOURCES = \
12 cgi_gateway.cc \ 12 cgi_gateway.cc \
13 cgi_interface.cc \ 13 cgi_interface.cc \
14 util.cc 14 util.cc
15libkingate_la_LDFLAGS = -version-info 1:0:0 15libkingate_la_LDFLAGS = -version-info 2:0:0
16 16
17libkingate_fcgi_la_SOURCES = \ 17libkingate_fcgi_la_SOURCES = \
18 fastcgi.cc 18 fastcgi.cc
19libkingate_fcgi_la_LDFLAGS = -version-info 1:0:0 19libkingate_fcgi_la_LDFLAGS = -version-info 1:0:0
20 20
21libkingate_plaincgi_la_SOURCES = \ 21libkingate_plaincgi_la_SOURCES = \
22 plaincgi.cc 22 plaincgi.cc
23libkingate_plaincgi_la_LDFLAGS = -version-info 1:0:0 23libkingate_plaincgi_la_LDFLAGS = -version-info 1:0:0
24 24
25EXTRA_DIST = ${libkingate_fcgi_la_SOURCES} 25EXTRA_DIST = ${libkingate_fcgi_la_SOURCES}
diff --git a/src/cgi_gateway.cc b/src/cgi_gateway.cc
index eae7a03..30410f2 100644
--- a/src/cgi_gateway.cc
+++ b/src/cgi_gateway.cc
@@ -1,88 +1,241 @@
1#include <errno.h>
2#include <ctype.h>
1#include "kingate/cgi_gateway.h" 3#include "kingate/cgi_gateway.h"
2#include "kingate/util.h" 4#include "kingate/util.h"
3#include "kingate/exception.h" 5#include "kingate/exception.h"
4 6
5namespace kingate { 7namespace kingate {
6 8
9 static string empty_string;
10
7 cgi_gateway::cgi_gateway(cgi_interface& ci) 11 cgi_gateway::cgi_gateway(cgi_interface& ci)
8 : iface(ci), b_parsed_content(false) { 12 : iface(ci), b_parsed_content(false) {
9 // Fetch GET content 13 // Fetch GET content
10 if(iface.has_meta("QUERY_STRING")) { 14 try {
11 string qs = iface.get_meta("QUERY_STRING"); 15 string qs = get_meta("QUERY_STRING");
12 parse_query(qs,get); 16 parse_query(qs,get);
13 } 17 }catch(exception_notfound& enf) { }
14 // Fetch POST content 18 // Fetch POST content
15 if(!strcasecmp(get_content_type().c_str(),"application/x-www-form-urlencoded")) { 19 if(!strcasecmp(content_type().c_str(),"application/x-www-form-urlencoded")) {
16 unsigned long cl = get_content_length(); 20 unsigned long cl = content_length();
17 if(cl) { 21 if(cl) {
18 char * tmp = new char[cl]; 22 char * tmp = new char[cl];
19 iface.in().read(tmp,cl); 23 iface.in().read(tmp,cl);
20 string qs(tmp,cl); 24 string qs(tmp,cl);
21 delete tmp; 25 delete tmp;
22 parse_query(qs,post); 26 parse_query(qs,post);
23 } 27 }
24 b_parsed_content = true; 28 b_parsed_content = true;
25 } 29 }
26 } 30 }
27 31
28 bool cgi_gateway::has_GET(const string& n) const { 32 bool cgi_gateway::has_GET(const string& n) const {
29 return get.find(n) != get.end(); 33 return get.find(n) != get.end();
30 } 34 }
31 string cgi_gateway::get_GET(const string& n) const { 35 const string& cgi_gateway::get_GET(const string& n) const {
32 params_t::const_iterator i = get.find(n); 36 params_t::const_iterator i = get.find(n);
33 if(i==get.end()) 37 if(i==get.end())
34 throw exception_notfound(CODEPOINT,"no such parameter"); 38 throw exception_notfound(CODEPOINT,"no such parameter");
35 return i->second; 39 return i->second;
36 } 40 }
37 bool cgi_gateway::has_POST(const string& n) const { 41 bool cgi_gateway::has_POST(const string& n) const {
38 return post.find(n) != post.end(); 42 return post.find(n) != post.end();
39 } 43 }
40 string cgi_gateway::get_POST(const string& n) const { 44 const string& cgi_gateway::get_POST(const string& n) const {
41 params_t::const_iterator i = post.find(n); 45 params_t::const_iterator i = post.find(n);
42 if(i==post.end()) 46 if(i==post.end())
43 throw exception_notfound(CODEPOINT,"no such parameter"); 47 throw exception_notfound(CODEPOINT,"no such parameter");
44 return i->second; 48 return i->second;
45 } 49 }
46 bool cgi_gateway::has_param(const string& n) const { 50 bool cgi_gateway::has_param(const string& n) const {
47 return has_GET(n) || has_POST(n); 51 return has_GET(n) || has_POST(n);
48 } 52 }
49 string cgi_gateway::get_param(const string& n) const { 53 const string& cgi_gateway::get_param(const string& n) const {
50 params_t::const_iterator i = get.find(n); 54 params_t::const_iterator i = get.find(n);
51 if(i!=get.end()) 55 if(i!=get.end())
52 return i->second; 56 return i->second;
53 i = post.find(n); 57 i = post.find(n);
54 if(i!=post.end()) 58 if(i!=post.end())
55 return i->second; 59 return i->second;
56 throw exception_notfound(CODEPOINT,"no such parameter"); 60 throw exception_notfound(CODEPOINT,"no such parameter");
57 } 61 }
58 62
63 /*
64 * deprecated stuff.
65 */
59 const string& cgi_gateway::get_content_type() const { 66 const string& cgi_gateway::get_content_type() const {
60 if(!has_meta("CONTENT_TYPE")) 67 if(!has_meta("CONTENT_TYPE"))
61 return ""; // XXX: 68 return empty_string;
62 return get_meta("CONTENT_TYPE"); 69 return get_meta("CONTENT_TYPE");
63 } 70 }
64 unsigned long cgi_gateway::get_content_length() const { 71 unsigned long cgi_gateway::get_content_length() const {
65 if(!has_meta("CONTENT_LENGTH")) 72 if(!has_meta("CONTENT_LENGTH"))
66 return 0; 73 return 0;
67 string cl = get_meta("CONTENT_LENGTH"); 74 string cl = get_meta("CONTENT_LENGTH");
68 return strtol(cl.c_str(),NULL,10); 75 return strtol(cl.c_str(),NULL,10);
69 } 76 }
77 /*
78 *
79 */
80
81 const string& cgi_gateway::http_request_header(const string& hn) const {
82 string mvn = "HTTP_";
83 for(const char* p=hn.c_str();*p;p++) {
84 if(*p=='-')
85 mvn += '_';
86 else
87 mvn += toupper(*p);
88 }
89 return get_meta(mvn);
90 }
91
92 const string& cgi_gateway::auth_type() const {
93 try {
94 return get_meta("AUTH_TYPE");
95 }catch(exception_notfound& enf) {
96 return empty_string;
97 }
98 }
99 unsigned long cgi_gateway::content_length() const {
100 try {
101 const string& cl = get_meta("CONTENT_LENGTH");
102 errno = 0;
103 const char *clp = cl.c_str();
104 unsigned long rv = strtol(clp,(char**)&clp,10);
105 if(errno || *clp)
106 throw server_error(CODEPOINT,"Invalid CONTENT_LENGTH value passed from server");
107 return rv;
108 }catch(exception_notfound& enf) {
109 return 0;
110 }
111 }
112 const string& cgi_gateway::content_type() const {
113 try {
114 return get_meta("CONTENT_TYPE");
115 }catch(exception_notfound& enf) {
116 return empty_string;
117 }
118 }
119 const string& cgi_gateway::gateway_interface() const {
120 try {
121 return get_meta("GATEWAY_INTERFACE");
122 }catch(exception_notfound& enf) {
123 return empty_string;
124 }
125 }
126 const string& cgi_gateway::path_info() const {
127 try {
128 return get_meta("PATH_INFO");
129 }catch(exception_notfound& enf) {
130 return empty_string;
131 }
132 }
133 const string& cgi_gateway::path_translated() const {
134 try {
135 return get_meta("PATH_TRANSLATED");
136 }catch(exception_notfound& enf) {
137 return empty_string;
138 }
139 }
140 const string& cgi_gateway::query_string() const {
141 try {
142 return get_meta("QUERY_STRING");
143 }catch(exception_notfound& enf) {
144 return empty_string;
145 }
146 }
147 const string& cgi_gateway::remote_addr() const {
148 try {
149 return get_meta("REMOTE_ADDR");
150 }catch(exception_notfound& enf) {
151 return empty_string;
152 }
153 }
154 const string& cgi_gateway::remote_host() const {
155 try {
156 return get_meta("REMOTE_HOST");
157 }catch(exception_notfound& enf) {
158 return remote_addr();
159 }
160 }
161 const string& cgi_gateway::remote_ident() const {
162 try {
163 return get_meta("REMOTE_IDENT");
164 }catch(exception_notfound& enf) {
165 return empty_string;
166 }
167 }
168 const string& cgi_gateway::remote_user() const {
169 try {
170 return get_meta("REMOTE_USER");
171 }catch(exception_notfound& enf) {
172 return empty_string;
173 }
174 }
175 const string& cgi_gateway::request_method() const {
176 try {
177 return get_meta("REQUEST_METHOD");
178 }catch(exception_notfound& enf) {
179 throw server_error(CODEPOINT,"No REQUEST_METHOD passed from server");
180 }
181 }
182 const string& cgi_gateway::script_name() const {
183 try {
184 return get_meta("SCRIPT_NAME");
185 }catch(exception_notfound& enf) {
186 throw server_error(CODEPOINT,"No SCRIPT_NAME passed from server");
187 }
188 }
189 const string& cgi_gateway::server_name() const {
190 try {
191 return get_meta("SERVER_NAME");
192 }catch(exception_notfound& enf) {
193 throw server_error(CODEPOINT,"No SERVER_NAME passed from server");
194 }
195 }
196 unsigned int cgi_gateway::server_port() const {
197 try {
198 const string& sp = get_meta("SERVER_PORT");
199 errno = 0;
200 const char *spp = sp.c_str();
201 unsigned int rv = strtol(spp,(char**)&spp,10);
202 if(errno || *spp)
203 throw server_error(CODEPOINT,"Invalid SERVER_PORT value passed from server");
204 return rv;
205 }catch(exception_notfound& enf) {
206 throw server_error(CODEPOINT,"No SERVER_PORT passed from server");
207 }
208 }
209 const string& cgi_gateway::server_protocol() const {
210 try {
211 return get_meta("SERVER_PROTOCOL");
212 }catch(exception_notfound& enf) {
213 throw server_error(CODEPOINT,"No SERVER_PROTOCOL passed from server");
214 }
215 }
216 const string& cgi_gateway::server_software() const {
217 try {
218 return get_meta("SERVER_SOFTWARE");
219 }catch(exception_notfound& enf) {
220 throw server_error(CODEPOINT,"No SERVER_SOFTWARE passed from server");
221 }
222 }
70 223
71 void cgi_gateway::parse_query(string& q,params_t& p) { 224 void cgi_gateway::parse_query(string& q,params_t& p) {
72 while(!q.empty()) { 225 while(!q.empty()) {
73 string::size_type amp = q.find('&'); 226 string::size_type amp = q.find('&');
74 string pp = (amp==string::npos)?q:q.substr(0,amp); 227 string pp = (amp==string::npos)?q:q.substr(0,amp);
75 if(amp==string::npos) 228 if(amp==string::npos)
76 q.clear(); 229 q.clear();
77 else 230 else
78 q.erase(0,amp+1); 231 q.erase(0,amp+1);
79 string::size_type eq = pp.find('='); 232 string::size_type eq = pp.find('=');
80 if(eq == string::npos) { 233 if(eq == string::npos) {
81 p.insert(params_t::value_type("",url_unescape(pp))); 234 p.insert(params_t::value_type("",url_decode(pp)));
82 }else{ 235 }else{
83 p.insert(params_t::value_type(url_unescape(pp.substr(0,eq)),url_unescape(pp.substr(eq+1)))); 236 p.insert(params_t::value_type(url_decode(pp.substr(0,eq)),url_decode(pp.substr(eq+1))));
84 } 237 }
85 } 238 }
86 } 239 }
87 240
88} 241}
diff --git a/src/util.cc b/src/util.cc
index 2e2d305..3166e62 100644
--- a/src/util.cc
+++ b/src/util.cc
@@ -1,45 +1,45 @@
1#include "kingate/util.h" 1#include "kingate/util.h"
2#include "kingate/exception.h" 2#include "kingate/exception.h"
3 3
4namespace kingate { 4namespace kingate {
5 5
6 static const char *safeChars = 6 static const char *safeChars =
7 "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 7 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
8 "abcdefghijklmnopqrstuvwxyz" 8 "abcdefghijklmnopqrstuvwxyz"
9 "0123456789" 9 "0123456789"
10 "_-" ; 10 "_-" ;
11 11
12 string url_escape(const string& str) { 12 string url_encode(const string& str) {
13 string rv = str; 13 string rv = str;
14 string::size_type screwed = 0; 14 string::size_type screwed = 0;
15 for(;;) { 15 for(;;) {
16 screwed = rv.find_first_not_of(safeChars,screwed); 16 screwed = rv.find_first_not_of(safeChars,screwed);
17 if(screwed == string::npos) 17 if(screwed == string::npos)
18 break; 18 break;
19 while(screwed<rv.length() && !strchr(safeChars,rv.at(screwed))) { 19 while(screwed<rv.length() && !strchr(safeChars,rv.at(screwed))) {
20 char danger = rv.at(screwed); 20 char danger = rv.at(screwed);
21 if(danger==' ') { 21 if(danger==' ') {
22 rv.replace(screwed++,1,1,'+'); 22 rv.replace(screwed++,1,1,'+');
23 }else{ 23 }else{
24 static char tmp[4] = {'%',0,0,0}; 24 static char tmp[4] = {'%',0,0,0};
25 snprintf(&tmp[1],3,"%02X",0xFF&(int)danger); 25 snprintf(&tmp[1],3,"%02X",0xFF&(int)danger);
26 rv.replace(screwed,1,tmp,3); 26 rv.replace(screwed,1,tmp,3);
27 screwed+=3; 27 screwed+=3;
28 } 28 }
29 } 29 }
30 } 30 }
31 return rv; 31 return rv;
32 } 32 }
33 string url_unescape(const string& str) { 33 string url_decode(const string& str) {
34 string rv = str; 34 string rv = str;
35 string::size_type unscrewed = 0; 35 string::size_type unscrewed = 0;
36 for(;;) { 36 for(;;) {
37 unscrewed = rv.find_first_of("%+",unscrewed); 37 unscrewed = rv.find_first_of("%+",unscrewed);
38 if(unscrewed == string::npos) 38 if(unscrewed == string::npos)
39 break; 39 break;
40 if(rv.at(unscrewed)=='+') { 40 if(rv.at(unscrewed)=='+') {
41 rv.replace(unscrewed++,1,1,' '); 41 rv.replace(unscrewed++,1,1,' ');
42 }else{ 42 }else{
43 if((rv.length()-unscrewed)<3) 43 if((rv.length()-unscrewed)<3)
44 throw exception(CODEPOINT,"incorrectly escaped string"); 44 throw exception(CODEPOINT,"incorrectly escaped string");
45 // XXX: ensure it's hex? 45 // XXX: ensure it's hex?