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 <webview/reply.h>
24 
25 #include <core/exception.h>
26 #include <cstdlib>
27 #include <cstdarg>
28 #include <cstdio>
29 
30 namespace fawkes {
31 #if 0 /* just to make Emacs auto-indent happy */
32 }
33 #endif
34 
35 
36 
37 /** @class WebReply <webview/reply.h>
38  * Basic web reply.
39  * The base class for all web replies. Though the WebRequestDispatcher expects
40  * sub-classes of StaticWebReply or DynamicWebReply.
41  * @author Tim Niemueller
42  */
43 
44 /// Enable caching for this reply?
45 bool WebReply::__caching = true;
46 
47 /** Constructor.
48  * @param code HTTP response code
49  */
51 {
52  __code = code;
53  __request = NULL;
54 
55  if (! __caching) {
56  // Headers to disable caching
57  __headers["Cache-Control"] = "no-cache, no-store, must-revalidate";
58  __headers["Pragma"] = "no-cache";
59  __headers["Expires"] = "0";
60  }
61 }
62 
63 
64 /** Destructor. */
66 {
67 }
68 
69 
70 /** Enable or disable caching for all consecutive replies.
71  * This static setting controls whether following replies will allow
72  * for client-side of the web pages or not. Disabling this allows to
73  * force clients to always reload the pages.
74  * @param caching true to enable client-side caching, false to disable
75  */
76 void
77 WebReply::set_caching(bool caching)
78 {
79  __caching = caching;
80 }
81 
82 /** Get response code.
83  * @return HTTP response code
84  */
87 {
88  return __code;
89 }
90 
91 
92 /** Add a HTTP header.
93  * @param header header entry name
94  * @param content content of the header field
95  */
96 void
97 WebReply::add_header(std::string header, std::string content)
98 {
99  __headers[header] = content;
100 }
101 
102 
103 /** Add a HTTP header.
104  * @param header_string header string of the format "Key: Value".
105  */
106 void
107 WebReply::add_header(std::string header_string)
108 {
109  std::string::size_type pos;
110  if ((pos = header_string.find(":")) != std::string::npos) {
111  std::string header = header_string.substr(0, pos);
112  std::string content;
113  if (header_string[pos+1] == ' ') {
114  content = header_string.substr(pos+2);
115  } else {
116  content = header_string.substr(pos+1);
117  }
118  __headers[header] = content;
119  } else {
120  throw Exception("Invalid header '%s'", header_string.c_str());
121  }
122 }
123 
124 
125 /** get headers.
126  * @return map of header name/content pairs.
127  */
128 const WebReply::HeaderMap &
130 {
131  return __headers;
132 }
133 
134 
135 /** Get associated request.
136  * This is only valid after set_request() has been called.
137  * @return associated web request
138  */
139 WebRequest *
141 {
142  return __request;
143 }
144 
145 
146 /** Set associated request.
147  * @param request associated request
148  */
149 void
151 {
152  __request = request;
153 }
154 
155 /** @class DynamicWebReply <webview/reply.h>
156  * Dynamic web reply.
157  * A reply of this type is send out in chunks, not all as a whole. It should be
158  * used for payloads that can get very large, like file transfers.
159  * @author Tim Niemueller
160  *
161  * @fn size_t DynamicWebReply::size() = 0
162  * Total size of the web reply.
163  * Return the total size of the reply if known, or -1 if it is not known. In the
164  * latter case your next_chunk() method has to return -1 at some point to end
165  * the transfer. If possible by any means return a meaningful value, as it will
166  * improve the experience of users, especially for long transfers!
167  * @return total size of reply in bytes
168  *
169  * @fn size_t DynamicWebReply::next_chunk(size_t pos, char *buffer, size_t buf_max_size) = 0
170  * Get data of next chunk.
171  * @param pos position in the stream. Note that a certain position may be called
172  * several times.
173  * @param buffer buffer to store data in
174  * @param buf_max_size maximum size in bytes of data that can be put into buffer
175  * @return number of bytes written to buffer, or -1 to immediately stop the
176  * transfer.
177  */
178 
179 /** Constructor.
180  * @param code HTTP response code
181  */
183  : WebReply(code)
184 {
185 }
186 
187 
188 /** Chunksize.
189  * The size that a single chunk should have. A sub-class may override this if a
190  * specific chunk size is beneficial or even required. The default is 32kb.
191  * @return chunk size in bytes
192  */
193 size_t
195 {
196  // use 32k chunks by default
197  return 32 * 1024;
198 }
199 
200 
201 /** @class StaticWebReply <webview/reply.h>
202  * Static web reply.
203  * The static web reply is send out as a whole at once and is immediately
204  * deleted after sending. Use it for regular-sized pages and content.
205  * @author Tim Niemueller
206  */
207 
208 /** Constructor.
209  * @param code HTTP response code
210  * @param body optional initial body
211  */
213  : WebReply(code)
214 {
215  _body = body;
216 }
217 
218 
219 /** Append to body.
220  * @param format format of the text to append. Supports the same format as
221  * printf().
222  */
223 void
224 StaticWebReply::append_body(const char *format, ...)
225 {
226  va_list args;
227  va_start(args, format);
228  char *s;
229  if ( vasprintf(&s, format, args) != -1 ) {
230  _body += s;
231  free(s);
232  }
233  va_end(args);
234 }
235 
236 
237 /** Append simple text line.
238  * @param text text to append to body
239  * @return reference to this instance
240  */
242 StaticWebReply::operator+=(std::string text)
243 {
244  _body += text;
245  return *this;
246 }
247 
248 
249 /** Get body.
250  * @return reference to body.
251  */
252 const std::string &
254 {
255  return _body;
256 }
257 
258 
259 /** Get length of body.
260  * @return body length
261  */
262 std::string::size_type
264 {
265  return _body.length();
266 }
267 
268 
269 /** Pack the data.
270  * This method is called just before the reply is sent.
271  * You can implement this method if you need to compose your reply before
272  * body() and body_length() provide valid output.
273  */
274 void
276 {
277 }
278 
279 } // end namespace fawkes
const HeaderMap & headers() const
get headers.
Definition: reply.cpp:129
void set_request(WebRequest *request)
Set associated request.
Definition: reply.cpp:150
virtual size_t chunk_size()
Chunksize.
Definition: reply.cpp:194
virtual ~WebReply()
Destructor.
Definition: reply.cpp:65
WebRequest * get_request() const
Get associated request.
Definition: reply.cpp:140
Fawkes library namespace.
DynamicWebReply(Code code)
Constructor.
Definition: reply.cpp:182
void add_header(std::string header, std::string content)
Add a HTTP header.
Definition: reply.cpp:97
WebReply(Code code)
Constructor.
Definition: reply.cpp:50
std::string _body
Body of the reply.
Definition: reply.h:147
virtual const std::string & body()
Get body.
Definition: reply.cpp:253
Code code() const
Get response code.
Definition: reply.cpp:86
StaticWebReply(Code code, std::string body="")
Constructor.
Definition: reply.cpp:212
static void set_caching(bool caching)
Enable or disable caching for all consecutive replies.
Definition: reply.cpp:77
Base class for exceptions in Fawkes.
Definition: exception.h:36
std::map< std::string, std::string > HeaderMap
Map of headers.
Definition: reply.h:101
Web request meta data carrier.
Definition: request.h:42
Basic web reply.
Definition: reply.h:36
void append_body(const char *format,...)
Append to body.
Definition: reply.cpp:224
Code
HTTP response code.
Definition: reply.h:40
StaticWebReply & operator+=(std::string text)
Append simple text line.
Definition: reply.cpp:242
virtual void pack()
Pack the data.
Definition: reply.cpp:275
virtual std::string::size_type body_length()
Get length of body.
Definition: reply.cpp:263
Static web reply.
Definition: reply.h:133