pion-net  4.0.9
net/src/HTTPWriter.cpp
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 #include <boost/asio.hpp>
00011 #include <pion/net/HTTPWriter.hpp>
00012 #include <pion/net/HTTPMessage.hpp>
00013 
00014 
00015 namespace pion {    // begin namespace pion
00016 namespace net {     // begin namespace net (Pion Network Library)
00017 
00018 
00019 // HTTPWriter member functions
00020 
00021 void HTTPWriter::prepareWriteBuffers(HTTPMessage::WriteBuffers& write_buffers,
00022                                      const bool send_final_chunk)
00023 {
00024     // check if the HTTP headers have been sent yet
00025     if (! m_sent_headers) {
00026         // initialize write buffers for send operation
00027         prepareBuffersForSend(write_buffers);
00028 
00029         // only send the headers once
00030         m_sent_headers = true;
00031     }
00032 
00033     // combine I/O write buffers (headers and content) so that everything
00034     // can be sent together; otherwise, we would have to send headers
00035     // and content separately, which would not be as efficient
00036     
00037     // don't send anything if there is no data in content buffers
00038     if (m_content_length > 0) {
00039         if (supportsChunkedMessages() && sendingChunkedMessage()) {
00040             // prepare the next chunk of data to send
00041             // write chunk length in hex
00042             char cast_buf[35];
00043             sprintf(cast_buf, "%lx", static_cast<long>(m_content_length));
00044             
00045             // add chunk length as a string at the back of the text cache
00046             m_text_cache.push_back(cast_buf);
00047             // append length of chunk to write_buffers
00048             write_buffers.push_back(boost::asio::buffer(m_text_cache.back()));
00049             // append an extra CRLF for chunk formatting
00050             write_buffers.push_back(boost::asio::buffer(HTTPTypes::STRING_CRLF));
00051             
00052             // append response content buffers
00053             write_buffers.insert(write_buffers.end(), m_content_buffers.begin(),
00054                                  m_content_buffers.end());
00055             // append an extra CRLF for chunk formatting
00056             write_buffers.push_back(boost::asio::buffer(HTTPTypes::STRING_CRLF));
00057         } else {
00058             // append response content buffers
00059             write_buffers.insert(write_buffers.end(), m_content_buffers.begin(),
00060                                  m_content_buffers.end());
00061         }
00062     }
00063     
00064     // prepare a zero-byte (final) chunk
00065     if (send_final_chunk && supportsChunkedMessages() && sendingChunkedMessage()) {
00066         // add chunk length as a string at the back of the text cache
00067         m_text_cache.push_back("0");
00068         // append length of chunk to write_buffers
00069         write_buffers.push_back(boost::asio::buffer(m_text_cache.back()));
00070         // append an extra CRLF for chunk formatting
00071         write_buffers.push_back(boost::asio::buffer(HTTPTypes::STRING_CRLF));
00072         write_buffers.push_back(boost::asio::buffer(HTTPTypes::STRING_CRLF));
00073     }
00074 }
00075 
00076 }   // end namespace net
00077 }   // end namespace pion
00078