pion  5.0.6
include/pion/http/request_writer.hpp
00001 // ---------------------------------------------------------------------
00002 // pion:  a Boost C++ framework for building lightweight HTTP interfaces
00003 // ---------------------------------------------------------------------
00004 // Copyright (C) 2007-2014 Splunk Inc.  (https://github.com/splunk/pion)
00005 //
00006 // Distributed under the Boost Software License, Version 1.0.
00007 // See http://www.boost.org/LICENSE_1_0.txt
00008 //
00009 
00010 #ifndef __PION_HTTP_REQUEST_WRITER_HEADER__
00011 #define __PION_HTTP_REQUEST_WRITER_HEADER__
00012 
00013 #include <boost/asio.hpp>
00014 #include <boost/bind.hpp>
00015 #include <boost/noncopyable.hpp>
00016 #include <boost/shared_ptr.hpp>
00017 #include <boost/enable_shared_from_this.hpp>
00018 #include <pion/config.hpp>
00019 #include <pion/http/writer.hpp>
00020 #include <pion/http/request.hpp>
00021 
00022 
00023 namespace pion {    // begin namespace pion
00024 namespace http {    // begin namespace http
00025 
00026 
00030 class request_writer :
00031     public http::writer,
00032     public boost::enable_shared_from_this<request_writer>
00033 {
00034 public:
00035     
00037     virtual ~request_writer() {}
00038 
00048     static inline boost::shared_ptr<request_writer> create(tcp::connection_ptr& tcp_conn,
00049                                                               finished_handler_t handler = finished_handler_t())
00050     {
00051         return boost::shared_ptr<request_writer>(new request_writer(tcp_conn, handler));
00052     }
00053     
00064     static inline boost::shared_ptr<request_writer> create(tcp::connection_ptr& tcp_conn,
00065                                                               http::request_ptr& http_request_ptr,
00066                                                               finished_handler_t handler = finished_handler_t())
00067     {
00068         return boost::shared_ptr<request_writer>(new request_writer(tcp_conn, http_request_ptr, handler));
00069     }
00070 
00072     inline http::request& get_request(void) { return *m_http_request; }
00073     
00074     
00075 protected:
00076     
00083     request_writer(tcp::connection_ptr& tcp_conn, finished_handler_t handler)
00084         : http::writer(tcp_conn, handler), m_http_request(new http::request)
00085     {
00086         set_logger(PION_GET_LOGGER("pion.http.request_writer"));
00087     }
00088     
00096     request_writer(tcp::connection_ptr& tcp_conn, http::request_ptr& http_request_ptr,
00097                       finished_handler_t handler)
00098         : http::writer(tcp_conn, handler), m_http_request(http_request_ptr)
00099     {
00100         set_logger(PION_GET_LOGGER("pion.http.request_writer"));
00101         // check if we should initialize the payload content using
00102         // the request's content buffer
00103         if (m_http_request->get_content_length() > 0
00104             && m_http_request->get_content() != NULL
00105             && m_http_request->get_content()[0] != '\0')
00106         {
00107             write_no_copy(m_http_request->get_content(),
00108                         m_http_request->get_content_length());
00109         }
00110     }
00111 
00112     
00118     virtual void prepare_buffers_for_send(http::message::write_buffers_t& write_buffers) {
00119         if (get_content_length() > 0)
00120             m_http_request->set_content_length(get_content_length());
00121         m_http_request->prepare_buffers_for_send(write_buffers,
00122                                               get_connection()->get_keep_alive(),
00123                                               sending_chunked_message());
00124     }
00125 
00127     virtual write_handler_t bind_to_write_handler(void) {
00128         return boost::bind(&request_writer::handle_write, shared_from_this(),
00129                            boost::asio::placeholders::error,
00130                            boost::asio::placeholders::bytes_transferred);
00131     }
00132 
00139     virtual void handle_write(const boost::system::error_code& write_error,
00140                              std::size_t bytes_written)
00141     {
00142         logger log_ptr(get_logger());
00143         if (! write_error) {
00144             // request sent OK
00145             if (sending_chunked_message()) {
00146                 PION_LOG_DEBUG(log_ptr, "Sent HTTP request chunk of " << bytes_written << " bytes");
00147                 clear();
00148             } else {
00149                 PION_LOG_DEBUG(log_ptr, "Sent HTTP request of " << bytes_written << " bytes");
00150             }
00151         }
00152         finished_writing(write_error);
00153     }
00154 
00155 
00156 private:
00157     
00159     http::request_ptr       m_http_request;
00160     
00162     std::string             m_request_line;
00163 };
00164 
00165 
00167 typedef boost::shared_ptr<request_writer>    request_writer_ptr;
00168 
00169 
00171 template <typename T>
00172 const request_writer_ptr& operator<<(const request_writer_ptr& writer, const T& data) {
00173     writer->write(data);
00174     return writer;
00175 }
00176 
00177 
00178 }   // end namespace http
00179 }   // end namespace pion
00180 
00181 #endif