- Main Page
- Classes
- Files

- File List

# 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