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) (side-by-side diff) | |
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 @@ -5,4 +5,12 @@ #include "kingate/cgi_interface.h" +#ifndef __deprecated +#if ( __GNUC__ == 3 && __GNUC_MINOR__ > 0 ) || __GNUC__ > 3 +#define __deprecated __attribute__((deprecated)) +#else +#define __deprecated +#endif +#endif + /** * @file @@ -60,5 +68,5 @@ namespace kingate { * @see cgi_interface::get_meta() */ - string get_meta(const string& n) const { return iface.get_meta(n); } + const string& get_meta(const string& n) const { return iface.get_meta(n); } /** @@ -99,5 +107,5 @@ namespace kingate { * @see exception_notfound */ - string get_GET(const string& n) const; + const string& get_GET(const string& n) const; /** * Check to see whether the parameter was passed via POST. @@ -112,5 +120,5 @@ namespace kingate { * @see exception_notfound */ - string get_POST(const string& n) const; + const string& get_POST(const string& n) const; /** * Check to see whether the parameter was passed either via POST or @@ -127,5 +135,5 @@ namespace kingate { * @see exception_notfound. */ - string get_param(const string& n) const; + const string& get_param(const string& n) const; /** @@ -134,5 +142,5 @@ namespace kingate { * @return the content type. */ - const string& get_content_type() const; + const string& __deprecated get_content_type() const; /** * Retrieve the POST content length (as passed via the @@ -140,5 +148,5 @@ namespace kingate { * @return the content length. */ - unsigned long get_content_length() const; + unsigned long __deprecated get_content_length() const; /** @@ -147,4 +155,101 @@ namespace kingate { */ bool is_content_parsed() const { return b_parsed_content; } + + /** + * Retrieve the HTTP header value from the HTTP_ meta-variable. + * (see RFC3875) + * @param hn header field name. + * @return the HTTP header value. + */ + const string& http_request_header(const string& hn) const; + + /** + * Retrieve the AUTH_TYPE meta-variable (see RFC3875) + * @return authentication type. + */ + const string& auth_type() const; + /** + * Retrieve the CONTENT_LENGTH meta-variable (see RFC3875) + * @return size of the request message body. + */ + unsigned long cgi_gateway::content_length() const; + /** + * Retrieve the CONTENT_TYPE meta-variable (see RFC3875) + * @return media type of the request message body. + */ + const string& content_type() const; + /** + * Retrieve the GATEWAY_INTERFACE meta-variable (see RFC3875) + * @return the gateway interface dialect. + */ + const string& gateway_interface() const; + /** + * Retrieve the PATH_INFO meta-variable (see RFC3875) + * @return path to be interpreted by the script. + */ + const string& path_info() const; + /** + * Retrieve the PATH_TRANSLATED meta-variable (see RFC3875) + * @return the translated path to the document. + */ + const string& path_translated() const; + /** + * Retrieve the QUERY_STRING meta-variable (see RFC3875) + * @return the query string. + */ + const string& query_string() const; + /** + * Retrieve the REMOTE_ADDR meta-variable (see RFC3875) + * @return the network address of the remote host. + */ + const string& remote_addr() const; + /** + * Retrieve the REMOTE_HOST meta-variable (see RFC3875) + * @return the fully qualified domain name of the client if + * available. REMOTE_ADDR otherwise. + * @see remote_addr() + */ + const string& remote_host() const; + /** + * Retrieve the REMOTE_IDENT meta-variable (see RFC3875) + * @return remote user identity (see RFC1413). + */ + const string& remote_ident() const; + /** + * Retrieve the REMOTE_USER meta-variable (see RFC3875) + * @return the authenticated user name. + */ + const string& remote_user() const; + /** + * Retrieve the REQUEST_METHOD meta-variable (see RFC3875) + * @return the http request method. + */ + const string& request_method() const; + /** + * Retrieve the SCRIPT_NAME meta-variable (see RFC3875) + * @return the uri path identifying the script. + */ + const string& script_name() const; + /** + * Retrieve the SERVER_NAME meta-variable (see RFC3875) + * @return the server name of the script. + */ + const string& server_name() const; + /** + * Retrieve the SERVER_PORT meta-variable (see RFC3875) + * @return the port on which request was received. + */ + unsigned int server_port() const; + /** + * Retrieve the SERVER_PROTOCOL meta-variable (see RFC3875) + * @return the protocol used for the request. + */ + const string& server_protocol() const; + /** + * Retrieve the SERVER_SOFTWARE meta-variable (see RFC3875) + * @return the name and version of server software. + */ + const string& server_software() const; + private: /** 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 @@ -37,4 +37,13 @@ namespace kingate { : exception(fi,fu,l,w) { } }; + + /** + * Thrown in case of unexpected server behaviour. + */ + class server_error : public exception { + public: + server_error(const string& fi,const string& fu,int l,const string& w) + : exception(fi,fu,l,w) { } + }; } 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 @@ -4,19 +4,42 @@ #include <string> +#ifndef __deprecated +#if ( __GNUC__ == 3 && __GNUC_MINOR__ > 0 ) || __GNUC__ > 3 +#define __deprecated __attribute__((deprecated)) +#else +#define __deprecated +#endif +#endif + namespace kingate { using namespace std; /** - * Escape string for passing via URL. - * @param str string unescaped. - * @return the escaped string. + * Encode string for passing via URL. + * @param str string unencoded. + * @return the encoded string. */ - string url_escape(const string& str); + string url_encode(const string& str); /** * Remove URL-encoding from the string. * @param str the URL-encoded string. - * @return the unescaped string. + * @return the decoded string. + */ + string url_decode(const string& str); + + /** + * deprecated alias to url_encode. + * @see url_encode + */ + inline string __deprecated url_escape(const string& str) { + return url_encode(str); + } + /** + * deprecated alias to url_decode. + * @see url_decode */ - string url_unescape(const string& str); + inline string __deprecated url_unescape(const string& str) { + return url_decode(str); + } } diff --git a/src/Makefile.am b/src/Makefile.am index d516d37..12bb1f8 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -13,5 +13,5 @@ libkingate_la_SOURCES = \ cgi_interface.cc \ util.cc -libkingate_la_LDFLAGS = -version-info 1:0:0 +libkingate_la_LDFLAGS = -version-info 2:0:0 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,2 +1,4 @@ +#include <errno.h> +#include <ctype.h> #include "kingate/cgi_gateway.h" #include "kingate/util.h" @@ -5,14 +7,16 @@ namespace kingate { + static string empty_string; + cgi_gateway::cgi_gateway(cgi_interface& ci) : iface(ci), b_parsed_content(false) { // Fetch GET content - if(iface.has_meta("QUERY_STRING")) { - string qs = iface.get_meta("QUERY_STRING"); + try { + string qs = get_meta("QUERY_STRING"); parse_query(qs,get); - } + }catch(exception_notfound& enf) { } // Fetch POST content - if(!strcasecmp(get_content_type().c_str(),"application/x-www-form-urlencoded")) { - unsigned long cl = get_content_length(); + if(!strcasecmp(content_type().c_str(),"application/x-www-form-urlencoded")) { + unsigned long cl = content_length(); if(cl) { char * tmp = new char[cl]; @@ -29,5 +33,5 @@ namespace kingate { return get.find(n) != get.end(); } - string cgi_gateway::get_GET(const string& n) const { + const string& cgi_gateway::get_GET(const string& n) const { params_t::const_iterator i = get.find(n); if(i==get.end()) @@ -38,5 +42,5 @@ namespace kingate { return post.find(n) != post.end(); } - string cgi_gateway::get_POST(const string& n) const { + const string& cgi_gateway::get_POST(const string& n) const { params_t::const_iterator i = post.find(n); if(i==post.end()) @@ -47,5 +51,5 @@ namespace kingate { return has_GET(n) || has_POST(n); } - string cgi_gateway::get_param(const string& n) const { + const string& cgi_gateway::get_param(const string& n) const { params_t::const_iterator i = get.find(n); if(i!=get.end()) @@ -57,7 +61,10 @@ namespace kingate { } + /* + * deprecated stuff. + */ const string& cgi_gateway::get_content_type() const { if(!has_meta("CONTENT_TYPE")) - return ""; // XXX: + return empty_string; return get_meta("CONTENT_TYPE"); } @@ -68,4 +75,150 @@ namespace kingate { return strtol(cl.c_str(),NULL,10); } + /* + * + */ + + const string& cgi_gateway::http_request_header(const string& hn) const { + string mvn = "HTTP_"; + for(const char* p=hn.c_str();*p;p++) { + if(*p=='-') + mvn += '_'; + else + mvn += toupper(*p); + } + return get_meta(mvn); + } + + const string& cgi_gateway::auth_type() const { + try { + return get_meta("AUTH_TYPE"); + }catch(exception_notfound& enf) { + return empty_string; + } + } + unsigned long cgi_gateway::content_length() const { + try { + const string& cl = get_meta("CONTENT_LENGTH"); + errno = 0; + const char *clp = cl.c_str(); + unsigned long rv = strtol(clp,(char**)&clp,10); + if(errno || *clp) + throw server_error(CODEPOINT,"Invalid CONTENT_LENGTH value passed from server"); + return rv; + }catch(exception_notfound& enf) { + return 0; + } + } + const string& cgi_gateway::content_type() const { + try { + return get_meta("CONTENT_TYPE"); + }catch(exception_notfound& enf) { + return empty_string; + } + } + const string& cgi_gateway::gateway_interface() const { + try { + return get_meta("GATEWAY_INTERFACE"); + }catch(exception_notfound& enf) { + return empty_string; + } + } + const string& cgi_gateway::path_info() const { + try { + return get_meta("PATH_INFO"); + }catch(exception_notfound& enf) { + return empty_string; + } + } + const string& cgi_gateway::path_translated() const { + try { + return get_meta("PATH_TRANSLATED"); + }catch(exception_notfound& enf) { + return empty_string; + } + } + const string& cgi_gateway::query_string() const { + try { + return get_meta("QUERY_STRING"); + }catch(exception_notfound& enf) { + return empty_string; + } + } + const string& cgi_gateway::remote_addr() const { + try { + return get_meta("REMOTE_ADDR"); + }catch(exception_notfound& enf) { + return empty_string; + } + } + const string& cgi_gateway::remote_host() const { + try { + return get_meta("REMOTE_HOST"); + }catch(exception_notfound& enf) { + return remote_addr(); + } + } + const string& cgi_gateway::remote_ident() const { + try { + return get_meta("REMOTE_IDENT"); + }catch(exception_notfound& enf) { + return empty_string; + } + } + const string& cgi_gateway::remote_user() const { + try { + return get_meta("REMOTE_USER"); + }catch(exception_notfound& enf) { + return empty_string; + } + } + const string& cgi_gateway::request_method() const { + try { + return get_meta("REQUEST_METHOD"); + }catch(exception_notfound& enf) { + throw server_error(CODEPOINT,"No REQUEST_METHOD passed from server"); + } + } + const string& cgi_gateway::script_name() const { + try { + return get_meta("SCRIPT_NAME"); + }catch(exception_notfound& enf) { + throw server_error(CODEPOINT,"No SCRIPT_NAME passed from server"); + } + } + const string& cgi_gateway::server_name() const { + try { + return get_meta("SERVER_NAME"); + }catch(exception_notfound& enf) { + throw server_error(CODEPOINT,"No SERVER_NAME passed from server"); + } + } + unsigned int cgi_gateway::server_port() const { + try { + const string& sp = get_meta("SERVER_PORT"); + errno = 0; + const char *spp = sp.c_str(); + unsigned int rv = strtol(spp,(char**)&spp,10); + if(errno || *spp) + throw server_error(CODEPOINT,"Invalid SERVER_PORT value passed from server"); + return rv; + }catch(exception_notfound& enf) { + throw server_error(CODEPOINT,"No SERVER_PORT passed from server"); + } + } + const string& cgi_gateway::server_protocol() const { + try { + return get_meta("SERVER_PROTOCOL"); + }catch(exception_notfound& enf) { + throw server_error(CODEPOINT,"No SERVER_PROTOCOL passed from server"); + } + } + const string& cgi_gateway::server_software() const { + try { + return get_meta("SERVER_SOFTWARE"); + }catch(exception_notfound& enf) { + throw server_error(CODEPOINT,"No SERVER_SOFTWARE passed from server"); + } + } void cgi_gateway::parse_query(string& q,params_t& p) { @@ -79,7 +232,7 @@ namespace kingate { string::size_type eq = pp.find('='); if(eq == string::npos) { - p.insert(params_t::value_type("",url_unescape(pp))); + p.insert(params_t::value_type("",url_decode(pp))); }else{ - p.insert(params_t::value_type(url_unescape(pp.substr(0,eq)),url_unescape(pp.substr(eq+1)))); + p.insert(params_t::value_type(url_decode(pp.substr(0,eq)),url_decode(pp.substr(eq+1)))); } } diff --git a/src/util.cc b/src/util.cc index 2e2d305..3166e62 100644 --- a/src/util.cc +++ b/src/util.cc @@ -10,5 +10,5 @@ namespace kingate { "_-" ; - string url_escape(const string& str) { + string url_encode(const string& str) { string rv = str; string::size_type screwed = 0; @@ -31,5 +31,5 @@ namespace kingate { return rv; } - string url_unescape(const string& str) { + string url_decode(const string& str) { string rv = str; string::size_type unscrewed = 0; |