Fawkes API Fawkes Development Version
reply.cpp
1
2/***************************************************************************
3 * reply.cpp - Web request reply
4 *
5 * Created: Thu Oct 23 12:01:05 2008
6 * Copyright 2006-2009 Tim Niemueller [www.niemueller.de]
7 *
8 ****************************************************************************/
9
10/* This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Library General Public License for more details.
19 *
20 * Read the full text in the LICENSE.GPL file in the doc directory.
21 */
22
23#include <core/exception.h>
24#include <webview/reply.h>
25
26#include <cstdarg>
27#include <cstdio>
28#include <cstdlib>
29
30namespace fawkes {
31
32/** Disable caching on a reply.
33 * This is a convenience wrapper to reply->set_caching(false). It enables
34 * the following call styles:
35 * @code
36 * return no_caching(new StaticWebReply(Reply::HTTP_NOT_FOUND, "Not Found"));
37 *
38 * return no_caching(some_handler());
39 * @endcode
40 * This works on any reply without always patching a boolean flag into
41 * the ctor and without first storing the pointer, calling the function,
42 * and then returning.
43 * @param reply reply to disable caching for
44 * @return this
45 */
46WebReply *
48{
49 reply->set_caching(false);
50 return reply;
51}
52
53/** @class WebReply <webview/reply.h>
54 * Basic web reply.
55 * The base class for all web replies. Though the WebRequestDispatcher expects
56 * sub-classes of StaticWebReply or DynamicWebReply.
57 * @author Tim Niemueller
58 */
59
60/// Enable caching for this reply?
61bool WebReply::caching_default_ = true;
62
63/** Constructor.
64 * @param code HTTP response code
65 */
67{
68 code_ = code;
69 request_ = NULL;
70
71 caching_ = caching_default_;
72}
73
74/** Destructor. */
76{
77}
78
79/** Enable or disable caching default for replies.
80 * This static setting controls whether following replies will allow
81 * for client-side of the web pages or not by default. Disabling this
82 * allows to force clients to always reload the pages.
83 * @param caching true to enable client-side caching, false to disable
84 */
85void
87{
88 caching_default_ = caching;
89}
90
91/** Enable or disable caching for this specific reply.
92 * @param caching true to enable client-side caching, false to disable
93 */
94void
96{
97 caching_ = caching;
98}
99
100/** Get response code.
101 * @return HTTP response code
102 */
105{
106 return code_;
107}
108
109/** Set response code.
110 * @param code HTTP response code
111 */
112void
114{
115 code_ = code;
116}
117
118/** Add a HTTP header.
119 * @param header header entry name
120 * @param content content of the header field
121 */
122void
123WebReply::add_header(const std::string &header, const std::string &content)
124{
125 headers_[header] = content;
126}
127
128/** Add a HTTP header.
129 * @param header_string header string of the format "Key: Value".
130 */
131void
132WebReply::add_header(const std::string &header_string)
133{
134 std::string::size_type pos;
135 if ((pos = header_string.find(":")) != std::string::npos) {
136 std::string header = header_string.substr(0, pos);
137 std::string content;
138 if (header_string[pos + 1] == ' ') {
139 content = header_string.substr(pos + 2);
140 } else {
141 content = header_string.substr(pos + 1);
142 }
143 headers_[header] = content;
144 } else {
145 throw Exception("Invalid header '%s'", header_string.c_str());
146 }
147}
148
149/** get headers.
150 * @return map of header name/content pairs.
151 */
154{
155 return headers_;
156}
157
158/** Get associated request.
159 * This is only valid after set_request() has been called.
160 * @return associated web request
161 */
164{
165 return request_;
166}
167
168/** Set associated request.
169 * @param request associated request
170 */
171void
173{
174 request_ = request;
175}
176
177/** Called just before the reply is sent.
178 * Sets no-caching flags if caching has been disabled.
179 */
180void
182{
183 if (!caching_) {
184 // Headers to disable caching
185 headers_["Cache-Control"] = "no-cache, no-store, must-revalidate, max-age=0";
186 }
187}
188
189/** @class DynamicWebReply <webview/reply.h>
190 * Dynamic web reply.
191 * A reply of this type is send out in chunks, not all as a whole. It should be
192 * used for payloads that can get very large, like file transfers.
193 * @author Tim Niemueller
194 *
195 * @fn size_t DynamicWebReply::size() = 0
196 * Total size of the web reply.
197 * Return the total size of the reply if known, or -1 if it is not known. In the
198 * latter case your next_chunk() method has to return -1 at some point to end
199 * the transfer. If possible by any means return a meaningful value, as it will
200 * improve the experience of users, especially for long transfers!
201 * @return total size of reply in bytes
202 *
203 * @fn size_t DynamicWebReply::next_chunk(size_t pos, char *buffer, size_t buf_max_size) = 0
204 * Get data of next chunk.
205 * @param pos position in the stream. Note that a certain position may be called
206 * several times.
207 * @param buffer buffer to store data in
208 * @param buf_max_size maximum size in bytes of data that can be put into buffer
209 * @return number of bytes written to buffer, or -1 to immediately stop the
210 * transfer.
211 */
212
213/** Constructor.
214 * @param code HTTP response code
215 */
217{
218}
219
220/** Chunksize.
221 * The size that a single chunk should have. A sub-class may override this if a
222 * specific chunk size is beneficial or even required. The default is 32kb.
223 * @return chunk size in bytes
224 */
225size_t
227{
228 // use 32k chunks by default
229 return 32 * 1024;
230}
231
232/** @class StaticWebReply <webview/reply.h>
233 * Static web reply.
234 * The static web reply is send out as a whole at once and is immediately
235 * deleted after sending. Use it for regular-sized pages and content.
236 * @author Tim Niemueller
237 */
238
239/** Constructor.
240 * @param code HTTP response code
241 * @param body optional initial body
242 */
243StaticWebReply::StaticWebReply(Code code, std::string body) : WebReply(code)
244{
245 _body = body;
246}
247
248/** Append to body.
249 * @param format format of the text to append. Supports the same format as
250 * printf().
251 */
252void
253StaticWebReply::append_body(const char *format, ...)
254{
255 va_list args;
256 va_start(args, format);
257 char *s;
258 if (vasprintf(&s, format, args) != -1) {
259 _body += s;
260 free(s);
261 }
262 va_end(args);
263}
264
265/** Append string to body.
266 * @param s string to add, this may contain null bytes
267 */
268void
269StaticWebReply::append_body(const std::string &s)
270{
271 _body += s;
272}
273
274/** Append simple text line.
275 * @param text text to append to body
276 * @return reference to this instance
277 */
280{
281 _body += text;
282 return *this;
283}
284
285/** Get body.
286 * @return reference to body.
287 */
288const std::string &
290{
291 return _body;
292}
293
294/** Get length of body.
295 * @return body length
296 */
297std::string::size_type
299{
300 return _body.length();
301}
302
303/** Pack the data.
304 * This method is called just before the reply is sent.
305 * You can implement this method if you need to compose your reply before
306 * body() and body_length() provide valid output.
307 */
308void
310{
311}
312
313} // end namespace fawkes
DynamicWebReply(Code code)
Constructor.
Definition: reply.cpp:216
virtual size_t chunk_size()
Chunksize.
Definition: reply.cpp:226
Base class for exceptions in Fawkes.
Definition: exception.h:36
Static web reply.
Definition: reply.h:136
StaticWebReply & operator+=(std::string text)
Append simple text line.
Definition: reply.cpp:279
StaticWebReply(Code code, std::string body="")
Constructor.
Definition: reply.cpp:243
void append_body(const char *format,...)
Append to body.
Definition: reply.cpp:253
std::string _body
Body of the reply.
Definition: reply.h:151
virtual std::string::size_type body_length()
Get length of body.
Definition: reply.cpp:298
virtual const std::string & body()
Get body.
Definition: reply.cpp:289
virtual void pack()
Pack the data.
Definition: reply.cpp:309
Basic web reply.
Definition: reply.h:34
void set_code(Code code)
Set response code.
Definition: reply.cpp:113
virtual ~WebReply()
Destructor.
Definition: reply.cpp:75
std::map< std::string, std::string > HeaderMap
Map of headers.
Definition: reply.h:98
static void set_caching_default(bool caching)
Enable or disable caching default for replies.
Definition: reply.cpp:86
void set_caching(bool caching)
Enable or disable caching for this specific reply.
Definition: reply.cpp:95
void add_header(const std::string &header, const std::string &content)
Add a HTTP header.
Definition: reply.cpp:123
Code code() const
Get response code.
Definition: reply.cpp:104
Code
HTTP response code.
Definition: reply.h:37
void set_request(WebRequest *request)
Set associated request.
Definition: reply.cpp:172
WebReply(Code code)
Constructor.
Definition: reply.cpp:66
const HeaderMap & headers() const
get headers.
Definition: reply.cpp:153
WebRequest * get_request() const
Get associated request.
Definition: reply.cpp:163
void pack_caching()
Called just before the reply is sent.
Definition: reply.cpp:181
Web request meta data carrier.
Definition: request.h:42
Fawkes library namespace.
WebReply * no_caching(WebReply *reply)
Disable caching on a reply.
Definition: reply.cpp:47