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 FCGIResponse class.
20 : : */
21 : :
22 : : #ifndef __SSRC_WSPR_FCGI_FCGI_RESPONSE_H
23 : : #define __SSRC_WSPR_FCGI_FCGI_RESPONSE_H
24 : :
25 : : #include <ssrc/wispers/fcgi/HTTPResponse.h>
26 : : #include <ssrc/wispers/fcgi/FCGIRequest.h>
27 : : #include <ssrc/wispers/types.h>
28 : :
29 : : __BEGIN_NS_SSRC_WSPR_FCGI
30 : :
31 : : /**
32 : : *
33 : : */
34 : : class FCGIResponse : public HTTPResponse {
35 : : typedef HTTPResponse super;
36 : :
37 : : boost::shared_ptr<FCGIRequest> _request;
38 : : bool _completed, _suspended;
39 : : HTTPStatusCode _status;
40 : : sid_type _session_id;
41 : : string _content_type;
42 : : // TODO: replace with generic add_header/set_header using parameter_map.
43 : : // Since we don't use any other custom headers, we don't implement those yet.
44 : : string _session_cookie;
45 : :
46 : : public:
47 : :
48 : : explicit FCGIResponse(const boost::shared_ptr<FCGIRequest> & request) :
49 : : super(), _request(request),
50 : : _completed(false), _suspended(false),
51 : : _status(StatusOK), _session_id(_request->session_id()),
52 : : _content_type("text/html"), _session_cookie()
53 : : {
54 : : // Check size as first line of protection against garbage identifiers.
55 : : if(_session_id.size() != SessionIdNumChars && !_session_id.empty())
56 : : _session_id.clear();
57 : : }
58 : :
59 [ # # # # : 0 : virtual ~FCGIResponse() {
# # # # ]
60 : : // Should be StatusGatewayTimeout, but lighttpd won't forward message body.
61 [ # # ]: 0 : if(!completed())
62 [ # # ]: 0 : send_error(StatusInternalServerError);
63 [ # # ]: 0 : }
64 : :
65 : : void fcgi_output(const char *content = 0,
66 : : const unsigned int content_length = 0,
67 : : bool cache_disable = CacheDisable);
68 : :
69 : 0 : void fcgx_finish(const HTTPStatusCode status) {
70 : 0 : _completed = true;
71 : 0 : set_status(status);
72 : 0 : FCGI::FCGX_SetExitStatus(status, _request->_fcgx_request->in);
73 : 0 : FCGI::FCGX_Finish_r(_request->_fcgx_request.get());
74 : 0 : }
75 : :
76 : 0 : virtual void complete(const char *content = 0,
77 : : const unsigned int content_length = 0,
78 : : bool cache_disable = CacheDisable)
79 : : {
80 : 0 : fcgi_output(content, content_length, cache_disable);
81 : 0 : fcgx_finish(status());
82 : 0 : }
83 : :
84 : 0 : virtual bool completed() const {
85 : 0 : return _completed;
86 : : }
87 : :
88 : 0 : virtual void suspend() {
89 : 0 : _suspended = true;
90 : 0 : }
91 : :
92 : 0 : virtual void resume() {
93 : 0 : _suspended = false;
94 : 0 : }
95 : :
96 : 0 : virtual bool suspended() const {
97 : 0 : return _suspended;
98 : : }
99 : :
100 : 0 : virtual void send_error(const HTTPStatusCode status) {
101 : 0 : _completed = true;
102 : : // TODO: Add a proper HTML body.
103 : 0 : FCGI::FCGX_FPrintF(_request->_fcgx_request->out,
104 : : "Status: %d\r\nContent-Type: text/html\r\n\r\n"
105 : 0 : "<h1>%d - Error</h1>", status, status);
106 : 0 : fcgx_finish(status);
107 : 0 : }
108 : :
109 : : virtual void send_redirect(const string & redirect);
110 : :
111 : 0 : virtual void set_content_type(const string & type) {
112 : 0 : _content_type = type;
113 : 0 : }
114 : :
115 : 0 : virtual const string & content_type() const {
116 : 0 : return _content_type;
117 : : }
118 : :
119 : 0 : virtual void set_status(const HTTPStatusCode status) {
120 : 0 : _status = status;
121 : 0 : }
122 : :
123 : 0 : virtual HTTPStatusCode status() const {
124 : 0 : return _status;
125 : : }
126 : :
127 : : virtual void set_session_id(const sid_type & session_id,
128 : : const unsigned int max_age = 1,
129 : : const bool secure = false);
130 : :
131 : 0 : virtual void clear_session_id() {
132 : 0 : _session_id.clear();
133 : : _session_cookie.assign("Set-Cookie: WSPRSID=; path=/; "
134 : : "expires=Thursday, 01-Jan-1970 00:00:00 GMT\r\n"
135 : : "Set-Cookie: WSPRSID=; Path=/; "
136 : : "Version=1; Max-Age=0\r\n"
137 : : /*
138 : : "Set-Cookie2: WSPRSID=; Path=/; "
139 : : "Version=1; Max-Age=0\r\n"
140 : : */
141 : 0 : "Wispers-Event: ClearSession");
142 : 0 : }
143 : :
144 : 0 : virtual const sid_type & session_id() const {
145 : 0 : return _session_id;
146 : : }
147 : : };
148 : :
149 : :
150 : : __END_NS_SSRC_WSPR_FCGI
151 : :
152 : : #endif
|