00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #ifndef __PION_HTTPREQUESTWRITER_HEADER__
00011 #define __PION_HTTPREQUESTWRITER_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/PionConfig.hpp>
00019 #include <pion/net/HTTPWriter.hpp>
00020 #include <pion/net/HTTPRequest.hpp>
00021
00022
00023 namespace pion {
00024 namespace net {
00025
00029 class HTTPRequestWriter :
00030 public HTTPWriter,
00031 public boost::enable_shared_from_this<HTTPRequestWriter>
00032 {
00033 public:
00034
00036 virtual ~HTTPRequestWriter() {}
00037
00047 static inline boost::shared_ptr<HTTPRequestWriter> create(TCPConnectionPtr& tcp_conn,
00048 FinishedHandler handler = FinishedHandler())
00049 {
00050 return boost::shared_ptr<HTTPRequestWriter>(new HTTPRequestWriter(tcp_conn, handler));
00051 }
00052
00063 static inline boost::shared_ptr<HTTPRequestWriter> create(TCPConnectionPtr& tcp_conn,
00064 HTTPRequestPtr& http_request,
00065 FinishedHandler handler = FinishedHandler())
00066 {
00067 return boost::shared_ptr<HTTPRequestWriter>(new HTTPRequestWriter(tcp_conn, http_request, handler));
00068 }
00069
00071 inline HTTPRequest& getRequest(void) { return *m_http_request; }
00072
00073
00074 protected:
00075
00083 HTTPRequestWriter(TCPConnectionPtr& tcp_conn, FinishedHandler handler)
00084 : HTTPWriter(tcp_conn, handler), m_http_request(new HTTPRequest)
00085 {
00086 setLogger(PION_GET_LOGGER("pion.net.HTTPRequestWriter"));
00087 }
00088
00096 HTTPRequestWriter(TCPConnectionPtr& tcp_conn, HTTPRequestPtr& http_request,
00097 FinishedHandler handler)
00098 : HTTPWriter(tcp_conn, handler), m_http_request(http_request)
00099 {
00100 setLogger(PION_GET_LOGGER("pion.net.HTTPRequestWriter"));
00101
00102
00103 if (m_http_request->getContentLength() > 0
00104 && m_http_request->getContent() != NULL
00105 && m_http_request->getContent()[0] != '\0')
00106 {
00107 writeNoCopy(m_http_request->getContent(),
00108 m_http_request->getContentLength());
00109 }
00110 }
00111
00112
00118 virtual void prepareBuffersForSend(HTTPMessage::WriteBuffers& write_buffers) {
00119 if (getContentLength() > 0)
00120 m_http_request->setContentLength(getContentLength());
00121 m_http_request->prepareBuffersForSend(write_buffers,
00122 getTCPConnection()->getKeepAlive(),
00123 sendingChunkedMessage());
00124 }
00125
00127 virtual WriteHandler bindToWriteHandler(void) {
00128 return boost::bind(&HTTPRequestWriter::handleWrite, shared_from_this(),
00129 boost::asio::placeholders::error,
00130 boost::asio::placeholders::bytes_transferred);
00131 }
00132
00139 virtual void handleWrite(const boost::system::error_code& write_error,
00140 std::size_t bytes_written)
00141 {
00142 PionLogger log_ptr(getLogger());
00143 if (write_error) {
00144
00145 PION_LOG_WARN(log_ptr, "Unable to send HTTP request (" << write_error.message() << ')');
00146 } else {
00147
00148 if (sendingChunkedMessage()) {
00149 PION_LOG_DEBUG(log_ptr, "Sent HTTP request chunk of " << bytes_written << " bytes");
00150 clear();
00151 } else {
00152 PION_LOG_DEBUG(log_ptr, "Sent HTTP request of " << bytes_written << " bytes");
00153 }
00154 }
00155 finishedWriting();
00156 }
00157
00158
00159 private:
00160
00162 HTTPRequestPtr m_http_request;
00163
00165 std::string m_request_line;
00166 };
00167
00168
00170 typedef boost::shared_ptr<HTTPRequestWriter> HTTPRequestWriterPtr;
00171
00172
00174 template <typename T>
00175 HTTPRequestWriterPtr& operator<<(HTTPRequestWriterPtr& writer, const T& data) {
00176 writer->write(data);
00177 return writer;
00178 }
00179
00180
00181 }
00182 }
00183
00184 #endif