# 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