Branch data Line data Source code
1 : : /*
2 : : * Copyright 2006-2009 Savarese Software Research Corporation
3 : : *
4 : : * Licensed under the Apache License, Version 2.0 (the "License");
5 : : * you may not use this file except in compliance with the License.
6 : : * You may obtain a copy of the License at
7 : : *
8 : : * https://www.savarese.com/software/ApacheLicense-2.0
9 : : *
10 : : * Unless required by applicable law or agreed to in writing, software
11 : : * distributed under the License is distributed on an "AS IS" BASIS,
12 : : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 : : * See the License for the specific language governing permissions and
14 : : * limitations under the License.
15 : : */
16 : :
17 : : /**
18 : : * @file
19 : : * This header defines the FCGIRequest class.
20 : : */
21 : :
22 : : #ifndef __SSRC_WSPR_FCGI_FCGI_REQUEST_H
23 : : #define __SSRC_WSPR_FCGI_FCGI_REQUEST_H
24 : :
25 : : #include <ssrc/wispers/fcgi/HTTPRequest.h>
26 : : #include <ssrc/wispers/utility/CircularFind.h>
27 : :
28 : : #include <boost/shared_ptr.hpp>
29 : :
30 : : #include <stdexcept>
31 : : #include <cctype>
32 : : #include <cstring>
33 : :
34 : : __BEGIN_NS_FCGI_INCLUDE
35 : : #include <fcgi/fcgiapp.h>
36 : : __END_NS_FCGI_INCLUDE
37 : :
38 : : __BEGIN_NS_SSRC_WSPR_FCGI
39 : :
40 : : using NS_SSRC_WSPR_UTILITY::CircularFind;
41 : :
42 : : const int PORT_HTTP = 80;
43 : : const int PORT_HTTPS = 443;
44 : :
45 : : typedef boost::shared_ptr<FCGI::FCGX_Request> fcgx_request_ptr;
46 : :
47 : : class FCGIRequest : public HTTPRequest {
48 : : friend class FCGIResponse;
49 : :
50 : : const fcgx_request_ptr _fcgx_request;
51 : : bool _https;
52 : : HTTPRequestMethod _method;
53 : : string _session_id;
54 : :
55 : 0 : static string header_to_http_env(const string & header) {
56 [ # # ]: 0 : string key("HTTP_");
57 : :
58 [ # # ]: 0 : key.append(header);
59 : :
60 [ # # # # ]: 0 : for(unsigned int i = 5; i < key.size(); ++i) {
61 [ # # # # ]: 0 : if(key[i] == '-')
62 [ # # ]: 0 : key[i] = '_';
63 : : else
64 [ # # # # ]: 0 : key[i] = std::toupper(key[i]);
65 : : }
66 : :
67 : 0 : return key;
68 : : }
69 : :
70 : : struct StrCmp {
71 : : const char * const str;
72 : :
73 : : StrCmp(const char *str) : str(str) { }
74 : :
75 : : bool operator()(const char *c_str) const {
76 : : return (std::strcmp(str, c_str) == 0);
77 : : }
78 : : };
79 : :
80 : : typedef CircularFind<const char * const *> HTTPRequestMethodMap;
81 : : static const HTTPRequestMethodMap RequestMethodMap;
82 : :
83 : : void set_session_id();
84 : :
85 : : public:
86 : :
87 : : explicit FCGIRequest(const fcgx_request_ptr & request) :
88 : : _fcgx_request(request), _https(false), _method(MethodUndefined)
89 : : {
90 : : char *val = FCGI::FCGX_GetParam("HTTPS", _fcgx_request->envp);
91 : :
92 : : if(val)
93 : : _https = (*val == 'o' && *(val + 1) == 'n');
94 : :
95 : : HTTPRequestMethodMap::iterator it =
96 : : RequestMethodMap.find_if(StrCmp(FCGI::FCGX_GetParam("REQUEST_METHOD", _fcgx_request->envp)));
97 : :
98 : : if(it != RequestMethodMap.end())
99 : : _method = static_cast<HTTPRequestMethod>(it - RequestMethodMap.begin());
100 : :
101 : : set_session_id();
102 : : }
103 : :
104 [ # # # # : 0 : virtual ~FCGIRequest() { }
# # ]
105 : :
106 : : const string & session_id() { return _session_id; }
107 : :
108 : : # define CGI_GET_VALUE(key) \
109 : : char *val = FCGI::FCGX_GetParam(#key, _fcgx_request->envp); \
110 : : return (val ? val : "")
111 : :
112 : : # define CGI_GET_INT_VALUE(int_type, key) \
113 : : int_type result = -1; \
114 : : char *str = FCGI::FCGX_GetParam(#key, _fcgx_request->envp); \
115 : : \
116 : : if(str) { \
117 : : char *end(0); \
118 : : result = std::strtol(str, &end, 10); \
119 : : \
120 : : if(end == str) \
121 : : result = -1; \
122 : : } \
123 : : \
124 : : return result
125 : :
126 : 0 : virtual string auth_type() const {
127 [ # # # # ]: 0 : CGI_GET_VALUE(AUTH_TYPE);
128 : : }
129 : 0 : virtual string content_type() const {
130 [ # # # # ]: 0 : CGI_GET_VALUE(CONTENT_TYPE);
131 : : }
132 : 0 : virtual long content_length() const {
133 [ # # # # ]: 0 : CGI_GET_INT_VALUE(long, CONTENT_LENGTH);
134 : : }
135 : 0 : virtual string document_root() const {
136 [ # # # # ]: 0 : CGI_GET_VALUE(DOCUMENT_ROOT);
137 : : }
138 : 0 : virtual string gateway_interface() const {
139 [ # # # # ]: 0 : CGI_GET_VALUE(GATEWAY_INTERFACE);
140 : : }
141 : 0 : virtual string path_info() const {
142 [ # # # # ]: 0 : CGI_GET_VALUE(PATH_INFO);
143 : : }
144 : 0 : virtual string path_translated() const {
145 [ # # # # ]: 0 : CGI_GET_VALUE(PATH_TRANSLATED);
146 : : }
147 : 0 : virtual string query_string() const {
148 [ # # # # ]: 0 : CGI_GET_VALUE(QUERY_STRING);
149 : : }
150 : 0 : virtual string redirect_request() const {
151 [ # # # # ]: 0 : CGI_GET_VALUE(REDIRECT_REQUEST);
152 : : }
153 : 0 : virtual string redirect_query_string() const {
154 [ # # # # ]: 0 : CGI_GET_VALUE(REDIRECT_QUERY_STRING);
155 : : }
156 : 0 : virtual string redirect_status() const {
157 [ # # # # ]: 0 : CGI_GET_VALUE(REDIRECT_STATUS);
158 : : }
159 : 0 : virtual string redirect_url() const {
160 [ # # # # ]: 0 : CGI_GET_VALUE(REDIRECT_URL);
161 : : }
162 : 0 : virtual string remote_address() const {
163 [ # # # # ]: 0 : CGI_GET_VALUE(REMOTE_ADDR);
164 : : }
165 : 0 : virtual string remote_host() const {
166 [ # # # # ]: 0 : CGI_GET_VALUE(REMOTE_HOST);
167 : : }
168 : 0 : virtual string remote_ident() const {
169 [ # # # # ]: 0 : CGI_GET_VALUE(REMOTE_IDENT);
170 : : }
171 : 0 : virtual int remote_port() const {
172 [ # # # # ]: 0 : CGI_GET_INT_VALUE(int, REMOTE_PORT);
173 : : }
174 : 0 : virtual string remote_user() const {
175 [ # # # # ]: 0 : CGI_GET_VALUE(REMOTE_USER);
176 : : }
177 : 0 : virtual string remote_group() const {
178 [ # # # # ]: 0 : CGI_GET_VALUE(REMOTE_GROUP);
179 : : }
180 : :
181 : 0 : virtual HTTPRequestMethod http_request_method() const { return _method; }
182 : :
183 : 0 : virtual string request_method() const {
184 [ # # # # ]: 0 : CGI_GET_VALUE(REQUEST_METHOD);
185 : : }
186 : 0 : virtual string request_uri() const {
187 [ # # # # ]: 0 : CGI_GET_VALUE(REQUEST_URI);
188 : : }
189 : 0 : virtual string script_filename() const {
190 [ # # # # ]: 0 : CGI_GET_VALUE(SCRIPT_FILENAME);
191 : : }
192 : 0 : virtual string script_name() const {
193 [ # # # # ]: 0 : CGI_GET_VALUE(SCRIPT_NAME);
194 : : }
195 : 0 : virtual string server_address() const {
196 [ # # # # ]: 0 : CGI_GET_VALUE(SERVER_ADDR);
197 : : }
198 : 0 : virtual string server_admin() const {
199 [ # # # # ]: 0 : CGI_GET_VALUE(SERVER_ADMIN);
200 : : }
201 : : // The raw server name. Lighttpd includes the port number, which is
202 : : // incorrect, so we postprocess it in server_name().
203 : 0 : string raw_server_name() const {
204 [ # # # # ]: 0 : CGI_GET_VALUE(SERVER_NAME);
205 : : }
206 : 0 : virtual string server_name() const {
207 : 0 : string name = raw_server_name();
208 [ # # ]: 0 : string::size_type pos = name.find(':');
209 : :
210 [ # # # # ]: 0 : if(pos < name.size())
211 [ # # ]: 0 : name.resize(pos);
212 : :
213 : 0 : return name;
214 : : }
215 : 0 : virtual int server_port() const {
216 [ # # # # ]: 0 : CGI_GET_INT_VALUE(int, SERVER_PORT);
217 : : }
218 : 0 : virtual string server_root() const {
219 [ # # # # ]: 0 : CGI_GET_VALUE(SERVER_ROOT);
220 : : }
221 : 0 : virtual string server_protocol() const {
222 [ # # # # ]: 0 : CGI_GET_VALUE(SERVER_PROTOCOL);
223 : : }
224 : 0 : virtual string server_software() const {
225 [ # # # # ]: 0 : CGI_GET_VALUE(SERVER_SOFTWARE);
226 : : }
227 : :
228 : 0 : virtual bool https() const {
229 : 0 : return _https;
230 : : }
231 : :
232 : 0 : virtual string scheme() const {
233 [ # # # # ]: 0 : return (_https ? "https" : "http");
234 : : }
235 : :
236 : 0 : virtual string header_value(const string & header) const {
237 : : const char *result =
238 : 0 : FCGI::FCGX_GetParam(header_to_http_env(header).c_str(),
239 [ # # # # ]: 0 : _fcgx_request->envp);
240 [ # # # # ]: 0 : return (result ? result : "");
241 : : }
242 : :
243 : : string env_value(const char *key) {
244 : : const char *result = FCGI::FCGX_GetParam(key, _fcgx_request->envp);
245 : : return (result ? result : string());
246 : : }
247 : :
248 : 0 : const char * fcgx_get_param(const char *key) const {
249 : 0 : return FCGI::FCGX_GetParam(key, _fcgx_request->envp);
250 : : }
251 : :
252 : : // Should this really be const? _fcgx_request state changes.
253 : 0 : int fcgx_get_str(char *str, int n) const {
254 : 0 : return FCGI::FCGX_GetStr(str, n, _fcgx_request->in);
255 : : }
256 : :
257 : : # undef CGI_GET_VALUE
258 : : # undef CGI_GET_INT_VALUE
259 : :
260 : : string to_absolute_url(const string & url) const
261 : : SSRC_DECL_THROW(std::invalid_argument);
262 : : };
263 : :
264 : : __END_NS_SSRC_WSPR_FCGI
265 : :
266 : : #endif
|