reply.cpp

00001
00002 /***************************************************************************
00003  *  reply.cpp - Web request reply
00004  *
00005  *  Created: Thu Oct 23 12:01:05 2008
00006  *  Copyright  2006-2008  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 "reply.h"
00024
00025 #include <cstdlib>
00026 #include <cstdarg>
00027 #include <cstdio>
00028 
00029 /** @class WebReply "reply.h"
00030  * Basic web reply.
00031  * The base class for all web replies. Though the WebRequestDispatcher expects
00032  * sub-classes of StaticWebReply or DynamicWebReply.
00033  * @author Tim Niemueller
00034  */
00035 
00036 /** Constructor.
00037  * @param code HTTP response code
00038  */
00039 WebReply::WebReply(response_code_t code)
00040 {
00041   __code = code;
00042 }
00043
00044 
00045 /** Destructor. */
00046 WebReply::~WebReply()
00047 {
00048 }
00049
00050 
00051 /** Get response code.
00052  * @return HTTP response code
00053  */
00054 WebReply::response_code_t
00055 WebReply::code() const
00056 {
00057   return __code;
00058 }
00059
00060 
00061 /** Add a HTTP header.
00062  * @param header header entry name
00063  * @param content content of the header field
00064  */
00065 void
00066 WebReply::add_header(std::string header, std::string content)
00067 {
00068   __headers[header] = content;
00069 }
00070
00071 
00072 /** get headers.
00073  * @return map of header name/content pairs.
00074  */
00075 const WebReply::HeaderMap &
00076 WebReply::headers() const
00077 {
00078   return __headers;
00079 }
00080
00081 
00082 /** @class DynamicWebReply "reply.h"
00083  * Dynamic web reply.
00084  * A reply of this type is send out in chunks, not all as a whole. It should be
00085  * used for payloads that can get very large, like file transfers.
00086  * @author Tim Niemueller
00087  *
00088  * @fn size_t DynamicWebReply::size() = 0
00089  * Total size of the web reply.
00090  * Return the total size of the reply if known, or 0 if it is not known. In the
00091  * latter case your next_chunk() method has to return -1 at some point to end
00092  * the transfer. If possible by any means return a meaningful value, as it will
00093  * improve the experience of users, especially for long transfers!
00094  * @return total size of reply in bytes
00095  *
00096  * @fn size_t DynamicWebReply::next_chunk(size_t pos, char *buffer, size_t buf_max_size) = 0
00097  * Get data of next chunk.
00098  * @param pos position in the stream. Note that a certain position may be called
00099  * several times.
00100  * @param buffer buffer to store data in
00101  * @param buf_max_size maximum size in bytes of data that can be put into buffer
00102  * @return number of bytes written to buffer, or -1 to immediately stop the
00103  * transfer.
00104  */
00105 
00106 /** Constructor.
00107  * @param code HTTP response code
00108  */
00109 DynamicWebReply::DynamicWebReply(response_code_t code)
00110   : WebReply(code)
00111 {
00112 }
00113
00114 
00115 /** Chunksize.
00116  * The size that a single chunk should have. A sub-class may override this if a
00117  * specific chunk size is beneficial or even required. The default is 32kb.
00118  * @return chunk size in bytes
00119  */
00120 size_t
00121 DynamicWebReply::chunk_size()
00122 {
00123   // use 32k chunks by default
00124   return 32 * 1024;
00125 }
00126
00127 
00128 /** @class StaticWebReply "reply.h"
00129  * Static web reply.
00130  * The static web reply is send out as a whole at once and is immediately
00131  * deleted after sending. Use it for regular-sized pages and content.
00132  * @author Tim Niemueller
00133  */
00134 
00135 /** Constructor.
00136  * @param code HTTP response code
00137  * @param body optional initial body
00138  */
00139 StaticWebReply::StaticWebReply(response_code_t code, std::string body)
00140   : WebReply(code)
00141 {
00142   _body = body;
00143 }
00144
00145 
00146 /** Append to body.
00147  * @param format format of the text to append. Supports the same format as
00148  * printf().
00149  */
00150 void
00151 StaticWebReply::append_body(const char *format, ...)
00152 {
00153   va_list args;
00154   va_start(args, format);
00155   char *s;
00156   if ( vasprintf(&s, format, args) != -1 ) {
00157     _body += s;
00158     free(s);
00159   }
00160   va_end(args);
00161 }
00162
00163 
00164 /** Append simple text line.
00165  * @param text text to append to body
00166  * @return reference to this instance
00167  */
00168 StaticWebReply &
00169 StaticWebReply::operator+=(std::string text)
00170 {
00171   _body += text;
00172   return *this;
00173 }
00174
00175 
00176 /** Get body.
00177  * @return reference to body.
00178  */
00179 const std::string &
00180 StaticWebReply::body()
00181 {
00182   return _body;
00183 }
00184
00185 
00186 /** Get length of body.
00187  * @return body length
00188  */
00189 std::string::size_type
00190 StaticWebReply::body_length()
00191 {
00192   return _body.length();
00193 }
00194
00195 
00196 /** Pack the data.
00197  * This method is called just before the reply is sent.
00198  * You can implement this method if you need to compose your reply before
00199  * body() and body_length() provide valid output.
00200  */
00201 void
00202 StaticWebReply::pack()
00203 {
00204 }