pion
5.0.6
|
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