pion-net  4.0.9
HTTPResponseWriter.hpp
1 // ------------------------------------------------------------------
2 // pion-net: a C++ framework for building lightweight HTTP interfaces
3 // ------------------------------------------------------------------
4 // Copyright (C) 2007-2008 Atomic Labs, Inc. (http://www.atomiclabs.com)
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_HTTPRESPONSEWRITER_HEADER__
11 #define __PION_HTTPRESPONSEWRITER_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/PionConfig.hpp>
19 #include <pion/net/HTTPWriter.hpp>
20 #include <pion/net/HTTPRequest.hpp>
21 #include <pion/net/HTTPResponse.hpp>
22 
23 
24 namespace pion { // begin namespace pion
25 namespace net { // begin namespace net (Pion Network Library)
26 
30 class PION_NET_API HTTPResponseWriter :
31  public HTTPWriter,
32  public boost::enable_shared_from_this<HTTPResponseWriter>
33 {
34 public:
35 
37  virtual ~HTTPResponseWriter() {}
38 
49  static inline boost::shared_ptr<HTTPResponseWriter> create(TCPConnectionPtr& tcp_conn,
50  HTTPResponsePtr& http_response,
51  FinishedHandler handler = FinishedHandler())
52  {
53  return boost::shared_ptr<HTTPResponseWriter>(new HTTPResponseWriter(tcp_conn, http_response, handler));
54  }
55 
66  static inline boost::shared_ptr<HTTPResponseWriter> create(TCPConnectionPtr& tcp_conn,
67  const HTTPRequest& http_request,
68  FinishedHandler handler = FinishedHandler())
69  {
70  return boost::shared_ptr<HTTPResponseWriter>(new HTTPResponseWriter(tcp_conn, http_request, handler));
71  }
72 
74  inline HTTPResponse& getResponse(void) { return *m_http_response; }
75 
76 
77 protected:
78 
86  HTTPResponseWriter(TCPConnectionPtr& tcp_conn, HTTPResponsePtr& http_response,
87  FinishedHandler handler)
88  : HTTPWriter(tcp_conn, handler), m_http_response(http_response)
89  {
90  setLogger(PION_GET_LOGGER("pion.net.HTTPResponseWriter"));
91  // tell the HTTPWriter base class whether or not the client supports chunks
92  supportsChunkedMessages(m_http_response->getChunksSupported());
93  // check if we should initialize the payload content using
94  // the response's content buffer
95  if (http_response->getContentLength() > 0
96  && http_response->getContent() != NULL
97  && http_response->getContent()[0] != '\0')
98  {
99  writeNoCopy(http_response->getContent(), http_response->getContentLength());
100  }
101  }
102 
110  HTTPResponseWriter(TCPConnectionPtr& tcp_conn, const HTTPRequest& http_request,
111  FinishedHandler handler)
112  : HTTPWriter(tcp_conn, handler), m_http_response(new HTTPResponse(http_request))
113  {
114  setLogger(PION_GET_LOGGER("pion.net.HTTPResponseWriter"));
115  // tell the HTTPWriter base class whether or not the client supports chunks
116  supportsChunkedMessages(m_http_response->getChunksSupported());
117  }
118 
119 
125  virtual void prepareBuffersForSend(HTTPMessage::WriteBuffers& write_buffers) {
126  if (getContentLength() > 0)
127  m_http_response->setContentLength(getContentLength());
128  m_http_response->prepareBuffersForSend(write_buffers,
129  getTCPConnection()->getKeepAlive(),
130  sendingChunkedMessage());
131  }
132 
135  return boost::bind(&HTTPResponseWriter::handleWrite, shared_from_this(),
136  boost::asio::placeholders::error,
137  boost::asio::placeholders::bytes_transferred);
138  }
139 
146  virtual void handleWrite(const boost::system::error_code& write_error,
147  std::size_t bytes_written)
148  {
149  PionLogger log_ptr(getLogger());
150  if (!write_error) {
151  // response sent OK
152  if (sendingChunkedMessage()) {
153  PION_LOG_DEBUG(log_ptr, "Sent HTTP response chunk of " << bytes_written << " bytes");
154  } else {
155  PION_LOG_DEBUG(log_ptr, "Sent HTTP response of " << bytes_written << " bytes ("
156  << (getTCPConnection()->getKeepAlive() ? "keeping alive)" : "closing)"));
157  }
158  }
159  finishedWriting(write_error);
160  }
161 
162 
163 private:
164 
166  HTTPResponsePtr m_http_response;
167 
169  std::string m_response_line;
170 };
171 
172 
174 typedef boost::shared_ptr<HTTPResponseWriter> HTTPResponseWriterPtr;
175 
176 
178 template <typename T>
179 const HTTPResponseWriterPtr& operator<<(const HTTPResponseWriterPtr& writer, const T& data) {
180  writer->write(data);
181  return writer;
182 }
183 
184 
185 } // end namespace net
186 } // end namespace pion
187 
188 #endif
virtual void prepareBuffersForSend(HTTPMessage::WriteBuffers &write_buffers)
virtual ~HTTPResponseWriter()
default destructor
boost::function1< void, const boost::system::error_code & > FinishedHandler
function called after the HTTP message has been sent
Definition: HTTPWriter.hpp:39
std::vector< boost::asio::const_buffer > WriteBuffers
data type for I/O write buffers (these wrap existing data to be sent)
Definition: HTTPMessage.hpp:43
HTTPResponseWriter(TCPConnectionPtr &tcp_conn, HTTPResponsePtr &http_response, FinishedHandler handler)
virtual WriteHandler bindToWriteHandler(void)
returns a function bound to HTTPWriter::handleWrite()
boost::function2< void, const boost::system::error_code &, std::size_t > WriteHandler
data type for a function that handles write operations
Definition: HTTPWriter.hpp:42
HTTPResponse & getResponse(void)
returns a non-const reference to the response that will be sent
static boost::shared_ptr< HTTPResponseWriter > create(TCPConnectionPtr &tcp_conn, const HTTPRequest &http_request, FinishedHandler handler=FinishedHandler())
static boost::shared_ptr< HTTPResponseWriter > create(TCPConnectionPtr &tcp_conn, HTTPResponsePtr &http_response, FinishedHandler handler=FinishedHandler())
HTTPResponseWriter(TCPConnectionPtr &tcp_conn, const HTTPRequest &http_request, FinishedHandler handler)
virtual void handleWrite(const boost::system::error_code &write_error, std::size_t bytes_written)