pion-net  4.0.9
net/include/pion/net/HTTPRequestWriter.hpp
00001 // ------------------------------------------------------------------
00002 // pion-net: a C++ framework for building lightweight HTTP interfaces
00003 // ------------------------------------------------------------------
00004 // Copyright (C) 2007-2008 Atomic Labs, Inc.  (http://www.atomiclabs.com)
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_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 {    // begin namespace pion
00024 namespace net {     // begin namespace net (Pion Network Library)
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         // check if we should initialize the payload content using
00102         // the request's content buffer
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             // request sent OK
00145             if (sendingChunkedMessage()) {
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         finishedWriting(write_error);
00153     }
00154 
00155 
00156 private:
00157     
00159     HTTPRequestPtr          m_http_request;
00160     
00162     std::string             m_request_line;
00163 };
00164 
00165 
00167 typedef boost::shared_ptr<HTTPRequestWriter>    HTTPRequestWriterPtr;
00168 
00169 
00171 template <typename T>
00172 const HTTPRequestWriterPtr& operator<<(const HTTPRequestWriterPtr& writer, const T& data) {
00173     writer->write(data);
00174     return writer;
00175 }
00176 
00177 
00178 }   // end namespace net
00179 }   // end namespace pion
00180 
00181 #endif