Fawkes API  Fawkes Development Version
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
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 /** @class WebReply <webview/reply.h>
36  * Basic web reply.
37  * The base class for all web replies. Though the WebRequestDispatcher expects
38  * sub-classes of StaticWebReply or DynamicWebReply.
39  * @author Tim Niemueller
40  */
41 
42 /** Constructor.
43  * @param code HTTP response code
44  */
45 WebReply::WebReply(response_code_t code)
46 {
47  __code = code;
48 }
49 
50 
51 /** Destructor. */
52 WebReply::~WebReply()
53 {
54 }
55 
56 
57 /** Get response code.
58  * @return HTTP response code
59  */
61 WebReply::code() const
62 {
63  return __code;
64 }
65 
66 
67 /** Add a HTTP header.
68  * @param header header entry name
69  * @param content content of the header field
70  */
71 void
72 WebReply::add_header(std::string header, std::string content)
73 {
74  __headers[header] = content;
75 }
76 
77 
78 /** Add a HTTP header.
79  * @param header_string header string of the format "Key: Value".
80  */
81 void
82 WebReply::add_header(std::string header_string)
83 {
84  std::string::size_type pos;
85  if ((pos = header_string.find(":")) != std::string::npos) {
86  std::string header = header_string.substr(0, pos);
87  std::string content;
88  if (header_string[pos+1] == ' ') {
89  content = header_string.substr(pos+2);
90  } else {
91  content = header_string.substr(pos+1);
92  }
93  __headers[header] = content;
94  } else {
95  throw Exception("Invalid header '%s'", header_string.c_str());
96  }
97 }
98 
99 
100 /** get headers.
101  * @return map of header name/content pairs.
102  */
103 const WebReply::HeaderMap &
104 WebReply::headers() const
105 {
106  return __headers;
107 }
108 
109 
110 /** @class DynamicWebReply <webview/reply.h>
111  * Dynamic web reply.
112  * A reply of this type is send out in chunks, not all as a whole. It should be
113  * used for payloads that can get very large, like file transfers.
114  * @author Tim Niemueller
115  *
116  * @fn size_t DynamicWebReply::size() = 0
117  * Total size of the web reply.
118  * Return the total size of the reply if known, or 0 if it is not known. In the
119  * latter case your next_chunk() method has to return -1 at some point to end
120  * the transfer. If possible by any means return a meaningful value, as it will
121  * improve the experience of users, especially for long transfers!
122  * @return total size of reply in bytes
123  *
124  * @fn size_t DynamicWebReply::next_chunk(size_t pos, char *buffer, size_t buf_max_size) = 0
125  * Get data of next chunk.
126  * @param pos position in the stream. Note that a certain position may be called
127  * several times.
128  * @param buffer buffer to store data in
129  * @param buf_max_size maximum size in bytes of data that can be put into buffer
130  * @return number of bytes written to buffer, or -1 to immediately stop the
131  * transfer.
132  */
133 
134 /** Constructor.
135  * @param code HTTP response code
136  */
137 DynamicWebReply::DynamicWebReply(response_code_t code)
138  : WebReply(code)
139 {
140 }
141 
142 
143 /** Chunksize.
144  * The size that a single chunk should have. A sub-class may override this if a
145  * specific chunk size is beneficial or even required. The default is 32kb.
146  * @return chunk size in bytes
147  */
148 size_t
150 {
151  // use 32k chunks by default
152  return 32 * 1024;
153 }
154 
155 
156 /** @class StaticWebReply <webview/reply.h>
157  * Static web reply.
158  * The static web reply is send out as a whole at once and is immediately
159  * deleted after sending. Use it for regular-sized pages and content.
160  * @author Tim Niemueller
161  */
162 
163 /** Constructor.
164  * @param code HTTP response code
165  * @param body optional initial body
166  */
168  : WebReply(code)
169 {
170  _body = body;
171 }
172 
173 
174 /** Append to body.
175  * @param format format of the text to append. Supports the same format as
176  * printf().
177  */
178 void
179 StaticWebReply::append_body(const char *format, ...)
180 {
181  va_list args;
182  va_start(args, format);
183  char *s;
184  if ( vasprintf(&s, format, args) != -1 ) {
185  _body += s;
186  free(s);
187  }
188  va_end(args);
189 }
190 
191 
192 /** Append simple text line.
193  * @param text text to append to body
194  * @return reference to this instance
195  */
197 StaticWebReply::operator+=(std::string text)
198 {
199  _body += text;
200  return *this;
201 }
202 
203 
204 /** Get body.
205  * @return reference to body.
206  */
207 const std::string &
209 {
210  return _body;
211 }
212 
213 
214 /** Get length of body.
215  * @return body length
216  */
217 std::string::size_type
219 {
220  return _body.length();
221 }
222 
223 
224 /** Pack the data.
225  * This method is called just before the reply is sent.
226  * You can implement this method if you need to compose your reply before
227  * body() and body_length() provide valid output.
228  */
229 void
231 {
232 }
233 
234 } // end namespace fawkes
virtual size_t chunk_size()
Chunksize.
Definition: reply.cpp:149
StaticWebReply(response_code_t code, std::string body="")
Constructor.
Definition: reply.cpp:167
std::string _body
Body of the reply.
Definition: reply.h:139
virtual const std::string & body()
Get body.
Definition: reply.cpp:208
Base class for exceptions in Fawkes.
Definition: exception.h:36
std::map< std::string, std::string > HeaderMap
Map of headers.
Definition: reply.h:99
response_code_t
HTTP response code.
Definition: reply.h:38
Basic web reply.
Definition: reply.h:34
void append_body(const char *format,...)
Append to body.
Definition: reply.cpp:179
StaticWebReply & operator+=(std::string text)
Append simple text line.
Definition: reply.cpp:197
virtual void pack()
Pack the data.
Definition: reply.cpp:230
virtual std::string::size_type body_length()
Get length of body.
Definition: reply.cpp:218
Static web reply.
Definition: reply.h:125