pion  5.0.6
http_writer.cpp
1 // ---------------------------------------------------------------------
2 // pion: a Boost C++ framework for building lightweight HTTP interfaces
3 // ---------------------------------------------------------------------
4 // Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion)
5 //
6 // Distributed under the Boost Software License, Version 1.0.
7 // See http://www.boost.org/LICENSE_1_0.txt
8 //
9 
10 #include <boost/asio.hpp>
11 #include <pion/http/writer.hpp>
12 #include <pion/http/message.hpp>
13 
14 
15 namespace pion { // begin namespace pion
16 namespace http { // begin namespace http
17 
18 
19 // writer member functions
20 
21 void writer::prepare_write_buffers(http::message::write_buffers_t& write_buffers,
22  const bool send_final_chunk)
23 {
24  // check if the HTTP headers have been sent yet
25  if (! m_sent_headers) {
26  // initialize write buffers for send operation
27  prepare_buffers_for_send(write_buffers);
28 
29  // only send the headers once
30  m_sent_headers = true;
31  }
32 
33  // combine I/O write buffers (headers and content) so that everything
34  // can be sent together; otherwise, we would have to send headers
35  // and content separately, which would not be as efficient
36 
37  // don't send anything if there is no data in content buffers
38  if (m_content_length > 0) {
40  // prepare the next chunk of data to send
41  // write chunk length in hex
42  char cast_buf[35];
43  sprintf(cast_buf, "%lx", static_cast<long>(m_content_length));
44 
45  // add chunk length as a string at the back of the text cache
46  m_text_cache.push_back(cast_buf);
47  // append length of chunk to write_buffers
48  write_buffers.push_back(boost::asio::buffer(m_text_cache.back()));
49  // append an extra CRLF for chunk formatting
50  write_buffers.push_back(boost::asio::buffer(http::types::STRING_CRLF));
51 
52  // append response content buffers
53  write_buffers.insert(write_buffers.end(), m_content_buffers.begin(),
54  m_content_buffers.end());
55  // append an extra CRLF for chunk formatting
56  write_buffers.push_back(boost::asio::buffer(http::types::STRING_CRLF));
57  } else {
58  // append response content buffers
59  write_buffers.insert(write_buffers.end(), m_content_buffers.begin(),
60  m_content_buffers.end());
61  }
62  }
63 
64  // prepare a zero-byte (final) chunk
65  if (send_final_chunk && supports_chunked_messages() && sending_chunked_message()) {
66  // add chunk length as a string at the back of the text cache
67  m_text_cache.push_back("0");
68  // append length of chunk to write_buffers
69  write_buffers.push_back(boost::asio::buffer(m_text_cache.back()));
70  // append an extra CRLF for chunk formatting
71  write_buffers.push_back(boost::asio::buffer(http::types::STRING_CRLF));
72  write_buffers.push_back(boost::asio::buffer(http::types::STRING_CRLF));
73  }
74 }
75 
76 
77 } // end namespace http
78 } // end namespace pion
virtual void prepare_buffers_for_send(http::message::write_buffers_t &write_buffers)=0
bool supports_chunked_messages() const
returns true if the client supports chunked messages
Definition: writer.hpp:246
bool sending_chunked_message() const
returns true if we are sending a chunked message to the client
Definition: writer.hpp:249
std::vector< boost::asio::const_buffer > write_buffers_t
data type for I/O write buffers (these wrap existing data to be sent)
Definition: message.hpp:61