Savarese Software Research Corporation
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

Savarese Software Research Corporation
Copyright © 2006-2011 Savarese Software Research Corporation. All rights reserved.