00001
00002
00003
00004
00005
00006
00007
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 {
00024 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
00102
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
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 }
00179 }
00180
00181 #endif