FCGIRequest.h
Go to the documentation of this file.
00001 /* 00002 * Copyright 2006-2009 Savarese Software Research Corporation 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * https://www.savarese.com/software/ApacheLicense-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00022 #ifndef __SSRC_WSPR_FCGI_FCGI_REQUEST_H 00023 #define __SSRC_WSPR_FCGI_FCGI_REQUEST_H 00024 00025 #include <ssrc/wispers/fcgi/HTTPRequest.h> 00026 #include <ssrc/wispers/utility/CircularFind.h> 00027 00028 #include <boost/shared_ptr.hpp> 00029 00030 #include <stdexcept> 00031 #include <cctype> 00032 #include <cstring> 00033 00034 __BEGIN_NS_FCGI_INCLUDE 00035 #include <fcgi/fcgiapp.h> 00036 __END_NS_FCGI_INCLUDE 00037 00038 __BEGIN_NS_SSRC_WSPR_FCGI 00039 00040 using NS_SSRC_WSPR_UTILITY::CircularFind; 00041 00042 const int PORT_HTTP = 80; 00043 const int PORT_HTTPS = 443; 00044 00045 typedef boost::shared_ptr<FCGI::FCGX_Request> fcgx_request_ptr; 00046 00047 class FCGIRequest : public HTTPRequest { 00048 friend class FCGIResponse; 00049 00050 const fcgx_request_ptr _fcgx_request; 00051 bool _https; 00052 HTTPRequestMethod _method; 00053 string _session_id; 00054 00055 static string header_to_http_env(const string & header) { 00056 string key("HTTP_"); 00057 00058 key.append(header); 00059 00060 for(unsigned int i = 5; i < key.size(); ++i) { 00061 if(key[i] == '-') 00062 key[i] = '_'; 00063 else 00064 key[i] = std::toupper(key[i]); 00065 } 00066 00067 return key; 00068 } 00069 00070 struct StrCmp { 00071 const char * const str; 00072 00073 StrCmp(const char *str) : str(str) { } 00074 00075 bool operator()(const char *c_str) const { 00076 return (std::strcmp(str, c_str) == 0); 00077 } 00078 }; 00079 00080 typedef CircularFind<const char * const *> HTTPRequestMethodMap; 00081 static const HTTPRequestMethodMap RequestMethodMap; 00082 00083 void set_session_id(); 00084 00085 public: 00086 00087 explicit FCGIRequest(const fcgx_request_ptr & request) : 00088 _fcgx_request(request), _https(false), _method(MethodUndefined) 00089 { 00090 char *val = FCGI::FCGX_GetParam("HTTPS", _fcgx_request->envp); 00091 00092 if(val) 00093 _https = (*val == 'o' && *(val + 1) == 'n'); 00094 00095 HTTPRequestMethodMap::iterator it = 00096 RequestMethodMap.find_if(StrCmp(FCGI::FCGX_GetParam("REQUEST_METHOD", _fcgx_request->envp))); 00097 00098 if(it != RequestMethodMap.end()) 00099 _method = static_cast<HTTPRequestMethod>(it - RequestMethodMap.begin()); 00100 00101 set_session_id(); 00102 } 00103 00104 virtual ~FCGIRequest() { } 00105 00106 const string & session_id() { return _session_id; } 00107 00108 # define CGI_GET_VALUE(key) \ 00109 char *val = FCGI::FCGX_GetParam(#key, _fcgx_request->envp); \ 00110 return (val ? val : "") 00111 00112 # define CGI_GET_INT_VALUE(int_type, key) \ 00113 int_type result = -1; \ 00114 char *str = FCGI::FCGX_GetParam(#key, _fcgx_request->envp); \ 00115 \ 00116 if(str) { \ 00117 char *end(0); \ 00118 result = std::strtol(str, &end, 10); \ 00119 \ 00120 if(end == str) \ 00121 result = -1; \ 00122 } \ 00123 \ 00124 return result 00125 00126 virtual string auth_type() const { 00127 CGI_GET_VALUE(AUTH_TYPE); 00128 } 00129 virtual string content_type() const { 00130 CGI_GET_VALUE(CONTENT_TYPE); 00131 } 00132 virtual long content_length() const { 00133 CGI_GET_INT_VALUE(long, CONTENT_LENGTH); 00134 } 00135 virtual string document_root() const { 00136 CGI_GET_VALUE(DOCUMENT_ROOT); 00137 } 00138 virtual string gateway_interface() const { 00139 CGI_GET_VALUE(GATEWAY_INTERFACE); 00140 } 00141 virtual string path_info() const { 00142 CGI_GET_VALUE(PATH_INFO); 00143 } 00144 virtual string path_translated() const { 00145 CGI_GET_VALUE(PATH_TRANSLATED); 00146 } 00147 virtual string query_string() const { 00148 CGI_GET_VALUE(QUERY_STRING); 00149 } 00150 virtual string redirect_request() const { 00151 CGI_GET_VALUE(REDIRECT_REQUEST); 00152 } 00153 virtual string redirect_query_string() const { 00154 CGI_GET_VALUE(REDIRECT_QUERY_STRING); 00155 } 00156 virtual string redirect_status() const { 00157 CGI_GET_VALUE(REDIRECT_STATUS); 00158 } 00159 virtual string redirect_url() const { 00160 CGI_GET_VALUE(REDIRECT_URL); 00161 } 00162 virtual string remote_address() const { 00163 CGI_GET_VALUE(REMOTE_ADDR); 00164 } 00165 virtual string remote_host() const { 00166 CGI_GET_VALUE(REMOTE_HOST); 00167 } 00168 virtual string remote_ident() const { 00169 CGI_GET_VALUE(REMOTE_IDENT); 00170 } 00171 virtual int remote_port() const { 00172 CGI_GET_INT_VALUE(int, REMOTE_PORT); 00173 } 00174 virtual string remote_user() const { 00175 CGI_GET_VALUE(REMOTE_USER); 00176 } 00177 virtual string remote_group() const { 00178 CGI_GET_VALUE(REMOTE_GROUP); 00179 } 00180 00181 virtual HTTPRequestMethod http_request_method() const { return _method; } 00182 00183 virtual string request_method() const { 00184 CGI_GET_VALUE(REQUEST_METHOD); 00185 } 00186 virtual string request_uri() const { 00187 CGI_GET_VALUE(REQUEST_URI); 00188 } 00189 virtual string script_filename() const { 00190 CGI_GET_VALUE(SCRIPT_FILENAME); 00191 } 00192 virtual string script_name() const { 00193 CGI_GET_VALUE(SCRIPT_NAME); 00194 } 00195 virtual string server_address() const { 00196 CGI_GET_VALUE(SERVER_ADDR); 00197 } 00198 virtual string server_admin() const { 00199 CGI_GET_VALUE(SERVER_ADMIN); 00200 } 00201 // The raw server name. Lighttpd includes the port number, which is 00202 // incorrect, so we postprocess it in server_name(). 00203 string raw_server_name() const { 00204 CGI_GET_VALUE(SERVER_NAME); 00205 } 00206 virtual string server_name() const { 00207 string name = raw_server_name(); 00208 string::size_type pos = name.find(':'); 00209 00210 if(pos < name.size()) 00211 name.resize(pos); 00212 00213 return name; 00214 } 00215 virtual int server_port() const { 00216 CGI_GET_INT_VALUE(int, SERVER_PORT); 00217 } 00218 virtual string server_root() const { 00219 CGI_GET_VALUE(SERVER_ROOT); 00220 } 00221 virtual string server_protocol() const { 00222 CGI_GET_VALUE(SERVER_PROTOCOL); 00223 } 00224 virtual string server_software() const { 00225 CGI_GET_VALUE(SERVER_SOFTWARE); 00226 } 00227 00228 virtual bool https() const { 00229 return _https; 00230 } 00231 00232 virtual string scheme() const { 00233 return (_https ? "https" : "http"); 00234 } 00235 00236 virtual string header_value(const string & header) const { 00237 const char *result = 00238 FCGI::FCGX_GetParam(header_to_http_env(header).c_str(), 00239 _fcgx_request->envp); 00240 return (result ? result : ""); 00241 } 00242 00243 string env_value(const char *key) { 00244 const char *result = FCGI::FCGX_GetParam(key, _fcgx_request->envp); 00245 return (result ? result : string()); 00246 } 00247 00248 const char * fcgx_get_param(const char *key) const { 00249 return FCGI::FCGX_GetParam(key, _fcgx_request->envp); 00250 } 00251 00252 // Should this really be const? _fcgx_request state changes. 00253 int fcgx_get_str(char *str, int n) const { 00254 return FCGI::FCGX_GetStr(str, n, _fcgx_request->in); 00255 } 00256 00257 # undef CGI_GET_VALUE 00258 # undef CGI_GET_INT_VALUE 00259 00260 string to_absolute_url(const string & url) const 00261 SSRC_DECL_THROW(std::invalid_argument); 00262 }; 00263 00264 __END_NS_SSRC_WSPR_FCGI 00265 00266 #endif
Copyright © 2006-2011 Savarese Software Research Corporation. All rights reserved.