response_writer.hpp
// ---------------------------------------------------------------------
// pion: a Boost C++ framework for building lightweight HTTP interfaces
// ---------------------------------------------------------------------
// Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion)
//
// Distributed under the Boost Software License, Version 1.0.
// See http://www.boost.org/LICENSE_1_0.txt
//
#ifndef __PION_HTTP_RESPONSE_WRITER_HEADER__
#define __PION_HTTP_RESPONSE_WRITER_HEADER__
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/noncopyable.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <pion/config.hpp>
#include <pion/http/writer.hpp>
#include <pion/http/request.hpp>
#include <pion/http/response.hpp>
namespace pion { // begin namespace pion
namespace http { // begin namespace http
class PION_API response_writer :
public http::writer,
public boost::enable_shared_from_this<response_writer>
{
public:
virtual ~response_writer() {}
static inline boost::shared_ptr<response_writer> create(const tcp::connection_ptr& tcp_conn,
const http::response_ptr& http_response_ptr,
finished_handler_t handler = finished_handler_t())
{
return boost::shared_ptr<response_writer>(new response_writer(tcp_conn, http_response_ptr, handler));
}
static inline boost::shared_ptr<response_writer> create(const tcp::connection_ptr& tcp_conn,
const http::request& http_request,
finished_handler_t handler = finished_handler_t())
{
return boost::shared_ptr<response_writer>(new response_writer(tcp_conn, http_request, handler));
}
inline http::response& get_response(void) { return *m_http_response; }
protected:
response_writer(const tcp::connection_ptr& tcp_conn, const http::response_ptr& http_response_ptr,
finished_handler_t handler)
: http::writer(tcp_conn, handler), m_http_response(http_response_ptr)
{
set_logger(PION_GET_LOGGER("pion.http.response_writer"));
// tell the http::writer base class whether or not the client supports chunks
supports_chunked_messages(m_http_response->get_chunks_supported());
// check if we should initialize the payload content using
// the response's content buffer
if (m_http_response->get_content_length() > 0
&& m_http_response->get_content() != NULL
&& m_http_response->get_content()[0] != '\0')
{
write_no_copy(m_http_response->get_content(), m_http_response->get_content_length());
}
}
response_writer(const tcp::connection_ptr& tcp_conn, const http::request& http_request,
finished_handler_t handler)
: http::writer(tcp_conn, handler), m_http_response(new http::response(http_request))
{
set_logger(PION_GET_LOGGER("pion.http.response_writer"));
// tell the http::writer base class whether or not the client supports chunks
supports_chunked_messages(m_http_response->get_chunks_supported());
}
virtual void prepare_buffers_for_send(http::message::write_buffers_t& write_buffers) {
if (get_content_length() > 0)
m_http_response->set_content_length(get_content_length());
m_http_response->prepare_buffers_for_send(write_buffers,
get_connection()->get_keep_alive(),
sending_chunked_message());
}
virtual write_handler_t bind_to_write_handler(void) {
return boost::bind(&response_writer::handle_write, shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred);
}
virtual void handle_write(const boost::system::error_code& write_error,
std::size_t bytes_written)
{
logger log_ptr(get_logger());
if (!write_error) {
// response sent OK
if (sending_chunked_message()) {
PION_LOG_DEBUG(log_ptr, "Sent HTTP response chunk of " << bytes_written << " bytes");
} else {
PION_LOG_DEBUG(log_ptr, "Sent HTTP response of " << bytes_written << " bytes ("
<< (get_connection()->get_keep_alive() ? "keeping alive)" : "closing)"));
}
}
finished_writing(write_error);
}
private:
http::response_ptr m_http_response;
std::string m_response_line;
};
typedef boost::shared_ptr<response_writer> response_writer_ptr;
template <typename T>
const response_writer_ptr& operator<<(const response_writer_ptr& writer, const T& data) {
writer->write(data);
return writer;
}
inline response_writer_ptr& operator<<(response_writer_ptr& writer, std::ostream& (*iomanip)(std::ostream&)) {
writer->write(iomanip);
return writer;
}
} // end namespace http
} // end namespace pion
#endif
pion::http::response_writer::prepare_buffers_for_send
virtual void prepare_buffers_for_send(http::message::write_buffers_t &write_buffers)
Definition: response_writer.hpp:126
pion::http::response_writer
Definition: response_writer.hpp:31
pion::http::response_writer::~response_writer
virtual ~response_writer()
default destructor
Definition: response_writer.hpp:38
pion::http::writer::write_handler_t
boost::function2< void, const boost::system::error_code &, std::size_t > write_handler_t
data type for a function that handles write operations
Definition: writer.hpp:43
pion::http::response_writer::response_writer
response_writer(const tcp::connection_ptr &tcp_conn, const http::request &http_request, finished_handler_t handler)
Definition: response_writer.hpp:111
pion::http::response
Definition: response.hpp:27
pion::http::response_writer::create
static boost::shared_ptr< response_writer > create(const tcp::connection_ptr &tcp_conn, const http::response_ptr &http_response_ptr, finished_handler_t handler=finished_handler_t())
Definition: response_writer.hpp:50
pion::http::request
Definition: request.hpp:26
pion::http::writer::finished_handler_t
boost::function1< void, const boost::system::error_code & > finished_handler_t
function called after the HTTP message has been sent
Definition: writer.hpp:40
pion::logger
Definition: logger.hpp:238
pion::http::response_writer::response_writer
response_writer(const tcp::connection_ptr &tcp_conn, const http::response_ptr &http_response_ptr, finished_handler_t handler)
Definition: response_writer.hpp:87
pion
Definition: admin_rights.hpp:19
pion::http::response_writer::handle_write
virtual void handle_write(const boost::system::error_code &write_error, std::size_t bytes_written)
Definition: response_writer.hpp:147
pion::http::response_writer::get_response
http::response & get_response(void)
returns a non-const reference to the response that will be sent
Definition: response_writer.hpp:75
pion::http::response_writer::create
static boost::shared_ptr< response_writer > create(const tcp::connection_ptr &tcp_conn, const http::request &http_request, finished_handler_t handler=finished_handler_t())
Definition: response_writer.hpp:67
pion::http::message::write_buffers_t
std::vector< boost::asio::const_buffer > write_buffers_t
data type for I/O write buffers (these wrap existing data to be sent)
Definition: message.hpp:61
pion::http::response_writer::bind_to_write_handler
virtual write_handler_t bind_to_write_handler(void)
returns a function bound to http::writer::handle_write()
Definition: response_writer.hpp:135
pion::http::writer
Definition: writer.hpp:34