Savarese Software Research Corporation
FCGIResponse.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_RESPONSE_H
00023 #define __SSRC_WSPR_FCGI_FCGI_RESPONSE_H
00024 
00025 #include <ssrc/wispers/fcgi/HTTPResponse.h>
00026 #include <ssrc/wispers/fcgi/FCGIRequest.h>
00027 #include <ssrc/wispers/types.h>
00028 
00029 __BEGIN_NS_SSRC_WSPR_FCGI
00030 
00034 class FCGIResponse : public HTTPResponse {
00035   typedef HTTPResponse super;
00036 
00037   boost::shared_ptr<FCGIRequest> _request;
00038   bool _completed, _suspended;
00039   HTTPStatusCode _status;
00040   sid_type _session_id;
00041   string _content_type;
00042   // TODO: replace with generic add_header/set_header using parameter_map.
00043   // Since we don't use any other custom headers, we don't implement those yet.
00044   string _session_cookie;
00045 
00046 public:
00047 
00048   explicit FCGIResponse(const boost::shared_ptr<FCGIRequest> & request) :
00049     super(), _request(request),
00050     _completed(false), _suspended(false),
00051     _status(StatusOK), _session_id(_request->session_id()),
00052     _content_type("text/html"), _session_cookie()
00053   {
00054     // Check size as first line of protection against garbage identifiers.
00055     if(_session_id.size() != SessionIdNumChars && !_session_id.empty())
00056       _session_id.clear();
00057   }
00058 
00059   virtual ~FCGIResponse() {
00060     // Should be StatusGatewayTimeout, but lighttpd won't forward message body.
00061     if(!completed())
00062       send_error(StatusInternalServerError);
00063   }
00064 
00065   void fcgi_output(const char *content = 0,
00066                    const unsigned int content_length = 0,
00067                    bool cache_disable = CacheDisable);
00068 
00069   void fcgx_finish(const HTTPStatusCode status) {
00070     _completed = true;
00071     set_status(status);
00072     FCGI::FCGX_SetExitStatus(status, _request->_fcgx_request->in);
00073     FCGI::FCGX_Finish_r(_request->_fcgx_request.get());
00074   }
00075 
00076   virtual void complete(const char *content = 0,
00077                         const unsigned int content_length = 0,
00078                         bool cache_disable = CacheDisable)
00079   {
00080     fcgi_output(content, content_length, cache_disable);
00081     fcgx_finish(status());
00082   }
00083 
00084   virtual bool completed() const {
00085     return _completed;
00086   }
00087 
00088   virtual void suspend() {
00089     _suspended = true;
00090   }
00091 
00092   virtual void resume() {
00093     _suspended = false;
00094   }
00095 
00096   virtual bool suspended() const {
00097     return _suspended;
00098   }
00099 
00100   virtual void send_error(const HTTPStatusCode status) {
00101     _completed = true;
00102     // TODO: Add a proper HTML body.
00103     FCGI::FCGX_FPrintF(_request->_fcgx_request->out,
00104                        "Status: %d\r\nContent-Type: text/html\r\n\r\n"
00105                        "<h1>%d - Error</h1>", status, status);
00106     fcgx_finish(status);
00107   }
00108 
00109   virtual void send_redirect(const string & redirect);
00110 
00111   virtual void set_content_type(const string & type) {
00112     _content_type = type;
00113   }
00114 
00115   virtual const string & content_type() const {
00116     return _content_type;
00117   }
00118 
00119   virtual void set_status(const HTTPStatusCode status) {
00120     _status = status;
00121   }
00122 
00123   virtual HTTPStatusCode status() const {
00124     return _status;
00125   }
00126 
00127   virtual void set_session_id(const sid_type & session_id,
00128                               const unsigned int max_age = 1,
00129                               const bool secure = false);
00130 
00131   virtual void clear_session_id() {
00132     _session_id.clear();
00133     _session_cookie.assign("Set-Cookie: WSPRSID=; path=/; "
00134                            "expires=Thursday, 01-Jan-1970 00:00:00 GMT\r\n"
00135                            "Set-Cookie: WSPRSID=; Path=/; "
00136                            "Version=1; Max-Age=0\r\n"
00137                            /*
00138                            "Set-Cookie2: WSPRSID=; Path=/; "
00139                            "Version=1; Max-Age=0\r\n"
00140                            */
00141                            "Wispers-Event: ClearSession");
00142   }
00143 
00144   virtual const sid_type & session_id() const {
00145     return _session_id;
00146   }
00147 };
00148 
00149 
00150 __END_NS_SSRC_WSPR_FCGI
00151 
00152 #endif

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