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
@@ -4,6 +4,14 @@
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.
@@ -59,7 +67,7 @@ namespace kingate {
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.
@@ -98,7 +106,7 @@ namespace kingate {
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.
@@ -111,7 +119,7 @@ namespace kingate {
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.
@@ -126,26 +134,123 @@ namespace kingate {
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
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
@@ -36,6 +36,15 @@ namespace kingate {
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 */
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
@@ -3,21 +3,44 @@
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 */
diff --git a/src/Makefile.am b/src/Makefile.am
index d516d37..12bb1f8 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -12,7 +12,7 @@ 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
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
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,19 +1,23 @@
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);
@@ -28,7 +32,7 @@ namespace kingate {
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");
@@ -37,7 +41,7 @@ namespace kingate {
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");
@@ -46,7 +50,7 @@ namespace kingate {
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;
@@ -56,9 +60,12 @@ namespace kingate {
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 {
@@ -67,6 +74,152 @@ namespace kingate {
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()) {
@@ -78,9 +231,9 @@ namespace kingate {
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 }
diff --git a/src/util.cc b/src/util.cc
index 2e2d305..3166e62 100644
--- a/src/util.cc
+++ b/src/util.cc
@@ -9,7 +9,7 @@ namespace kingate {
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(;;) {
@@ -30,7 +30,7 @@ namespace kingate {
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(;;) {