1212#define BOOST_NETWORK_HTTP_SERVER_CONNECTION_BUFFER_SIZE 4096uL
1313#endif
1414
15+ #include < utility>
16+ #include < iterator>
1517#include < boost/enable_shared_from_this.hpp>
18+ #include < boost/network/constants.hpp>
1619#include < boost/network/protocol/http/server/request_parser.hpp>
1720#include < boost/network/protocol/http/request.hpp>
1821#include < boost/network/protocol/http/response.hpp>
2629#include < boost/lexical_cast.hpp>
2730#include < boost/algorithm/string/case_conv.hpp>
2831#include < boost/bind.hpp>
29- #include < boost/network/protocol/http/algorithms/flatten.hpp>
3032
3133namespace boost {namespace network {namespace http {
3234
@@ -187,8 +189,13 @@ class sync_server_connection : public boost::enable_shared_from_this<sync_server
187189 }else {
188190 response response_;
189191handler_ (request_, response_);
190- std::vector<asio::const_buffer> response_buffers;
191- flatten (response_, response_buffers);
192+ flatten_response ();
193+ std::vector<asio::const_buffer>response_buffers (output_buffers_.size ());
194+ std::transform (output_buffers_.begin (), output_buffers_.end (),
195+ response_buffers.begin (),
196+ [](buffer_typeconst &buffer) {
197+ return asio::const_buffer (buffer.data (), buffer.size ());
198+ });
192199boost::asio::async_write (
193200 socket_,
194201 response_buffers,
@@ -217,13 +224,15 @@ class sync_server_connection : public boost::enable_shared_from_this<sync_server
217224 }
218225
219226void handle_write (system::error_codeconst &ec) {
227+ // First thing we do is clear out the output buffers.
228+ output_buffers_.clear ();
220229if (ec) {
221230// TODO maybe log the error here.
222231 }
223232 }
224233
225234void client_error () {
226- static char const * bad_request =
235+ static char const bad_request[] =
227236" HTTP/1.0 400 Bad Request\r\n Connection: close\r\n Content-Type: text/plain\r\n Content-Length: 12\r\n\r\n Bad Request." ;
228237
229238asio::async_write (
@@ -262,6 +271,43 @@ class sync_server_connection : public boost::enable_shared_from_this<sync_server
262271 );
263272 }
264273
274+ void flatten_response () {
275+ uint16_t status =http::status (response_);
276+ std::string status_message =http::status_message (response_);
277+ headers_wrapper::container_type headers =network::headers (response_);
278+ std::ostringstream status_line;
279+ status_line << status <<constants::space () << status_message <<constants::space ()
280+ <<constants::http_slash ()
281+ <<" 1.1" // TODO: make this a constant
282+ <<constants::crlf ();
283+ segmented_write (status_line.str ());
284+ std::ostringstream header_stream;
285+ for (decltype (headers)::value_typeconst &header : headers) {
286+ header_stream << header.first <<constants::colon () <<constants::space ()
287+ << header.second <<constants::crlf ();
288+ }
289+ header_stream <<constants::crlf ();
290+ segmented_write (header_stream.str ());
291+ bool done =false ;
292+ while (!done) {
293+ buffer_type buffer;
294+ response_.get_body ([&done, &buffer](iterator_range<char const *> data) {
295+ if (boost::empty (data)) done =true ;
296+ else std::copy (begin (data),end (data), buffer.begin ());
297+ }, buffer.size ());
298+ if (!done) output_buffers_.emplace_back (std::move (buffer));
299+ }
300+ }
301+
302+ void segmented_write (std::string data) {
303+ while (!boost::empty (data)) {
304+ buffer_type buffer;
305+ auto end =std::copy_n (boost::begin (data), buffer.size (), buffer.begin ());
306+ data.erase (0 ,std::distance (buffer.begin (), end));
307+ output_buffers_.emplace_back (std::move (buffer));
308+ }
309+ }
310+
265311 boost::asio::io_service & service_;
266312 function<void (requestconst &, response &)> handler_;
267313 boost::asio::ip::tcp::socket socket_;
@@ -273,6 +319,7 @@ class sync_server_connection : public boost::enable_shared_from_this<sync_server
273319 request_parser parser_;
274320 request request_;
275321 response response_;
322+ std::list<buffer_type> output_buffers_;
276323 std::string partial_parsed;
277324 optional<system::system_error> error_encountered;
278325bool read_body_;