Fawkes API
Fawkes Development Version
|
00001 00002 /*************************************************************************** 00003 * reply.cpp - Web request reply 00004 * 00005 * Created: Thu Oct 23 12:01:05 2008 00006 * Copyright 2006-2009 Tim Niemueller [www.niemueller.de] 00007 * 00008 ****************************************************************************/ 00009 00010 /* This program is free software; you can redistribute it and/or modify 00011 * it under the terms of the GNU General Public License as published by 00012 * the Free Software Foundation; either version 2 of the License, or 00013 * (at your option) any later version. 00014 * 00015 * This program is distributed in the hope that it will be useful, 00016 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00018 * GNU Library General Public License for more details. 00019 * 00020 * Read the full text in the LICENSE.GPL file in the doc directory. 00021 */ 00022 00023 #include <webview/reply.h> 00024 00025 #include <core/exception.h> 00026 #include <cstdlib> 00027 #include <cstdarg> 00028 #include <cstdio> 00029 00030 namespace fawkes { 00031 #if 0 /* just to make Emacs auto-indent happy */ 00032 } 00033 #endif 00034 00035 /** @class WebReply <webview/reply.h> 00036 * Basic web reply. 00037 * The base class for all web replies. Though the WebRequestDispatcher expects 00038 * sub-classes of StaticWebReply or DynamicWebReply. 00039 * @author Tim Niemueller 00040 */ 00041 00042 /** Constructor. 00043 * @param code HTTP response code 00044 */ 00045 WebReply::WebReply(response_code_t code) 00046 { 00047 __code = code; 00048 } 00049 00050 00051 /** Destructor. */ 00052 WebReply::~WebReply() 00053 { 00054 } 00055 00056 00057 /** Get response code. 00058 * @return HTTP response code 00059 */ 00060 WebReply::response_code_t 00061 WebReply::code() const 00062 { 00063 return __code; 00064 } 00065 00066 00067 /** Add a HTTP header. 00068 * @param header header entry name 00069 * @param content content of the header field 00070 */ 00071 void 00072 WebReply::add_header(std::string header, std::string content) 00073 { 00074 __headers[header] = content; 00075 } 00076 00077 00078 /** Add a HTTP header. 00079 * @param header_string header string of the format "Key: Value". 00080 */ 00081 void 00082 WebReply::add_header(std::string header_string) 00083 { 00084 std::string::size_type pos; 00085 if ((pos = header_string.find(":")) != std::string::npos) { 00086 std::string header = header_string.substr(0, pos); 00087 std::string content; 00088 if (header_string[pos+1] == ' ') { 00089 content = header_string.substr(pos+2); 00090 } else { 00091 content = header_string.substr(pos+1); 00092 } 00093 __headers[header] = content; 00094 } else { 00095 throw Exception("Invalid header '%s'", header_string.c_str()); 00096 } 00097 } 00098 00099 00100 /** get headers. 00101 * @return map of header name/content pairs. 00102 */ 00103 const WebReply::HeaderMap & 00104 WebReply::headers() const 00105 { 00106 return __headers; 00107 } 00108 00109 00110 /** @class DynamicWebReply <webview/reply.h> 00111 * Dynamic web reply. 00112 * A reply of this type is send out in chunks, not all as a whole. It should be 00113 * used for payloads that can get very large, like file transfers. 00114 * @author Tim Niemueller 00115 * 00116 * @fn size_t DynamicWebReply::size() = 0 00117 * Total size of the web reply. 00118 * Return the total size of the reply if known, or 0 if it is not known. In the 00119 * latter case your next_chunk() method has to return -1 at some point to end 00120 * the transfer. If possible by any means return a meaningful value, as it will 00121 * improve the experience of users, especially for long transfers! 00122 * @return total size of reply in bytes 00123 * 00124 * @fn size_t DynamicWebReply::next_chunk(size_t pos, char *buffer, size_t buf_max_size) = 0 00125 * Get data of next chunk. 00126 * @param pos position in the stream. Note that a certain position may be called 00127 * several times. 00128 * @param buffer buffer to store data in 00129 * @param buf_max_size maximum size in bytes of data that can be put into buffer 00130 * @return number of bytes written to buffer, or -1 to immediately stop the 00131 * transfer. 00132 */ 00133 00134 /** Constructor. 00135 * @param code HTTP response code 00136 */ 00137 DynamicWebReply::DynamicWebReply(response_code_t code) 00138 : WebReply(code) 00139 { 00140 } 00141 00142 00143 /** Chunksize. 00144 * The size that a single chunk should have. A sub-class may override this if a 00145 * specific chunk size is beneficial or even required. The default is 32kb. 00146 * @return chunk size in bytes 00147 */ 00148 size_t 00149 DynamicWebReply::chunk_size() 00150 { 00151 // use 32k chunks by default 00152 return 32 * 1024; 00153 } 00154 00155 00156 /** @class StaticWebReply <webview/reply.h> 00157 * Static web reply. 00158 * The static web reply is send out as a whole at once and is immediately 00159 * deleted after sending. Use it for regular-sized pages and content. 00160 * @author Tim Niemueller 00161 */ 00162 00163 /** Constructor. 00164 * @param code HTTP response code 00165 * @param body optional initial body 00166 */ 00167 StaticWebReply::StaticWebReply(response_code_t code, std::string body) 00168 : WebReply(code) 00169 { 00170 _body = body; 00171 } 00172 00173 00174 /** Append to body. 00175 * @param format format of the text to append. Supports the same format as 00176 * printf(). 00177 */ 00178 void 00179 StaticWebReply::append_body(const char *format, ...) 00180 { 00181 va_list args; 00182 va_start(args, format); 00183 char *s; 00184 if ( vasprintf(&s, format, args) != -1 ) { 00185 _body += s; 00186 free(s); 00187 } 00188 va_end(args); 00189 } 00190 00191 00192 /** Append simple text line. 00193 * @param text text to append to body 00194 * @return reference to this instance 00195 */ 00196 StaticWebReply & 00197 StaticWebReply::operator+=(std::string text) 00198 { 00199 _body += text; 00200 return *this; 00201 } 00202 00203 00204 /** Get body. 00205 * @return reference to body. 00206 */ 00207 const std::string & 00208 StaticWebReply::body() 00209 { 00210 return _body; 00211 } 00212 00213 00214 /** Get length of body. 00215 * @return body length 00216 */ 00217 std::string::size_type 00218 StaticWebReply::body_length() 00219 { 00220 return _body.length(); 00221 } 00222 00223 00224 /** Pack the data. 00225 * This method is called just before the reply is sent. 00226 * You can implement this method if you need to compose your reply before 00227 * body() and body_length() provide valid output. 00228 */ 00229 void 00230 StaticWebReply::pack() 00231 { 00232 } 00233 00234 } // end namespace fawkes