pion  5.0.6
request_writer.hpp
1 // ---------------------------------------------------------------------
2 // pion: a Boost C++ framework for building lightweight HTTP interfaces
3 // ---------------------------------------------------------------------
4 // Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion)
5 //
6 // Distributed under the Boost Software License, Version 1.0.
7 // See http://www.boost.org/LICENSE_1_0.txt
8 //
9 
10 #ifndef __PION_HTTP_REQUEST_WRITER_HEADER__
11 #define __PION_HTTP_REQUEST_WRITER_HEADER__
12 
13 #include <boost/asio.hpp>
14 #include <boost/bind.hpp>
15 #include <boost/noncopyable.hpp>
16 #include <boost/shared_ptr.hpp>
17 #include <boost/enable_shared_from_this.hpp>
18 #include <pion/config.hpp>
19 #include <pion/http/writer.hpp>
20 #include <pion/http/request.hpp>
21 
22 
23 namespace pion { // begin namespace pion
24 namespace http { // begin namespace http
25 
26 
31  public http::writer,
32  public boost::enable_shared_from_this<request_writer>
33 {
34 public:
35 
37  virtual ~request_writer() {}
38 
48  static inline boost::shared_ptr<request_writer> create(const tcp::connection_ptr& tcp_conn,
50  {
51  return boost::shared_ptr<request_writer>(new request_writer(tcp_conn, handler));
52  }
53 
64  static inline boost::shared_ptr<request_writer> create(const tcp::connection_ptr& tcp_conn,
65  const http::request_ptr& http_request_ptr,
67  {
68  return boost::shared_ptr<request_writer>(new request_writer(tcp_conn, http_request_ptr, handler));
69  }
70 
72  inline http::request& get_request(void) { return *m_http_request; }
73 
74 
75 protected:
76 
83  request_writer(const tcp::connection_ptr& tcp_conn, finished_handler_t handler)
84  : http::writer(tcp_conn, handler), m_http_request(new http::request)
85  {
86  set_logger(PION_GET_LOGGER("pion.http.request_writer"));
87  }
88 
96  request_writer(const tcp::connection_ptr& tcp_conn, const http::request_ptr& http_request_ptr,
97  finished_handler_t handler)
98  : http::writer(tcp_conn, handler), m_http_request(http_request_ptr)
99  {
100  set_logger(PION_GET_LOGGER("pion.http.request_writer"));
101  // check if we should initialize the payload content using
102  // the request's content buffer
103  if (m_http_request->get_content_length() > 0
104  && m_http_request->get_content() != NULL
105  && m_http_request->get_content()[0] != '\0')
106  {
107  write_no_copy(m_http_request->get_content(),
108  m_http_request->get_content_length());
109  }
110  }
111 
112 
119  if (get_content_length() > 0)
120  m_http_request->set_content_length(get_content_length());
121  m_http_request->prepare_buffers_for_send(write_buffers,
122  get_connection()->get_keep_alive(),
124  }
125 
128  return boost::bind(&request_writer::handle_write, shared_from_this(),
129  boost::asio::placeholders::error,
130  boost::asio::placeholders::bytes_transferred);
131  }
132 
139  virtual void handle_write(const boost::system::error_code& write_error,
140  std::size_t bytes_written)
141  {
142  logger log_ptr(get_logger());
143  if (! write_error) {
144  // request sent OK
145  if (sending_chunked_message()) {
146  PION_LOG_DEBUG(log_ptr, "Sent HTTP request chunk of " << bytes_written << " bytes");
147  clear();
148  } else {
149  PION_LOG_DEBUG(log_ptr, "Sent HTTP request of " << bytes_written << " bytes");
150  }
151  }
152  finished_writing(write_error);
153  }
154 
155 
156 private:
157 
159  http::request_ptr m_http_request;
160 
162  std::string m_request_line;
163 };
164 
165 
167 typedef boost::shared_ptr<request_writer> request_writer_ptr;
168 
169 
171 template <typename T>
172 const request_writer_ptr& operator<<(const request_writer_ptr& writer, const T& data) {
173  writer->write(data);
174  return writer;
175 }
176 
177 
178 } // end namespace http
179 } // end namespace pion
180 
181 #endif
void clear(void)
clears out all of the memory buffers used to cache payload content data
Definition: writer.hpp:91
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
size_t get_content_length(void) const
returns the length of the payload content (in bytes)
Definition: writer.hpp:240
writer(const tcp::connection_ptr &tcp_conn, finished_handler_t handler)
Definition: writer.hpp:52
static boost::shared_ptr< request_writer > create(const tcp::connection_ptr &tcp_conn, finished_handler_t handler=finished_handler_t())
logger get_logger(void)
returns the logger currently in use
Definition: writer.hpp:255
virtual void handle_write(const boost::system::error_code &write_error, std::size_t bytes_written)
virtual ~request_writer()
default destructor
void finished_writing(const boost::system::error_code &ec)
called after we have finished sending the HTTP message
Definition: writer.hpp:80
http::request & get_request(void)
returns a non-const reference to the request that will be sent
tcp::connection_ptr & get_connection(void)
returns a shared pointer to the TCP connection
Definition: writer.hpp:237
boost::function1< void, const boost::system::error_code & > finished_handler_t
function called after the HTTP message has been sent
Definition: writer.hpp:40
request_writer(const tcp::connection_ptr &tcp_conn, finished_handler_t handler)
void write_no_copy(const std::string &data)
Definition: writer.hpp:137
void set_logger(logger log_ptr)
sets the logger to be used
Definition: writer.hpp:252
virtual void prepare_buffers_for_send(http::message::write_buffers_t &write_buffers)
static boost::shared_ptr< request_writer > create(const tcp::connection_ptr &tcp_conn, const http::request_ptr &http_request_ptr, finished_handler_t handler=finished_handler_t())
virtual write_handler_t bind_to_write_handler(void)
returns a function bound to http::writer::handle_write()
bool sending_chunked_message() const
returns true if we are sending a chunked message to the client
Definition: writer.hpp:249
request_writer(const tcp::connection_ptr &tcp_conn, const http::request_ptr &http_request_ptr, finished_handler_t handler)
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