author | Michael Krelin <hacker@klever.net> | 2005-03-31 22:06:45 (UTC) |
---|---|---|
committer | Michael Krelin <hacker@klever.net> | 2005-03-31 22:06:45 (UTC) |
commit | 0942697ed6ee058809db963f9cc3126f93139de2 (patch) (unidiff) | |
tree | 2a5cdf5d200e302a6d6394e4a0193929dcb11bb0 | |
parent | 5b50415afdb7b708874293ac7047b9b70de78e59 (diff) | |
download | kingate-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
-rw-r--r-- | include/kingate/cgi_gateway.h | 117 | ||||
-rw-r--r-- | include/kingate/exception.h | 9 | ||||
-rw-r--r-- | include/kingate/util.h | 35 | ||||
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/cgi_gateway.cc | 175 | ||||
-rw-r--r-- | src/util.cc | 4 |
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 | ||
12 | namespace kingate { | 20 | namespace 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 | |||
6 | namespace kingate { | 14 | namespace 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 | |||
3 | if HAVE_FCGI | 3 | if HAVE_FCGI |
4 | lib_LTLIBRARIES += libkingate-fcgi.la | 4 | lib_LTLIBRARIES += libkingate-fcgi.la |
5 | endif | 5 | endif |
6 | 6 | ||
7 | INCLUDES = -I${top_srcdir}/include -I${top_srcdir} | 7 | INCLUDES = -I${top_srcdir}/include -I${top_srcdir} |
8 | AM_CXXFLAGS = ${KONFORKA_CFLAGS} | 8 | AM_CXXFLAGS = ${KONFORKA_CFLAGS} |
9 | LDADD = ${KONFORKA_LIBS} | 9 | LDADD = ${KONFORKA_LIBS} |
10 | 10 | ||
11 | libkingate_la_SOURCES = \ | 11 | libkingate_la_SOURCES = \ |
12 | cgi_gateway.cc \ | 12 | cgi_gateway.cc \ |
13 | cgi_interface.cc \ | 13 | cgi_interface.cc \ |
14 | util.cc | 14 | util.cc |
15 | libkingate_la_LDFLAGS = -version-info 1:0:0 | 15 | libkingate_la_LDFLAGS = -version-info 2:0:0 |
16 | 16 | ||
17 | libkingate_fcgi_la_SOURCES = \ | 17 | libkingate_fcgi_la_SOURCES = \ |
18 | fastcgi.cc | 18 | fastcgi.cc |
19 | libkingate_fcgi_la_LDFLAGS = -version-info 1:0:0 | 19 | libkingate_fcgi_la_LDFLAGS = -version-info 1:0:0 |
20 | 20 | ||
21 | libkingate_plaincgi_la_SOURCES = \ | 21 | libkingate_plaincgi_la_SOURCES = \ |
22 | plaincgi.cc | 22 | plaincgi.cc |
23 | libkingate_plaincgi_la_LDFLAGS = -version-info 1:0:0 | 23 | libkingate_plaincgi_la_LDFLAGS = -version-info 1:0:0 |
24 | 24 | ||
25 | EXTRA_DIST = ${libkingate_fcgi_la_SOURCES} | 25 | EXTRA_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 | ||
5 | namespace kingate { | 7 | namespace 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 | ||
4 | namespace kingate { | 4 | namespace 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? |