.. _program_listing_file_stream-client_stream_impl_http_socket.ipp: Program Listing for File http_socket.ipp ======================================== |exhale_lsh| :ref:`Return to documentation for file ` (``stream-client/stream/impl/http_socket.ipp``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp #pragma once namespace stream_client { namespace http { template const size_t base_socket::kHeaderLimit = 1 << 20; // 1Mb limit template const size_t base_socket::kBodyLimit = 10 << 20; // 10Mb limit template template boost::optional> base_socket::perform(const boost::beast::http::request& request, boost::system::error_code& ec, const time_point_type& deadline) { send_request(request, ec, deadline); if (ec) { return boost::none; } return recv_response(ec, deadline); } template template void base_socket::send_request(const boost::beast::http::request& request, boost::system::error_code& ec, const time_point_type& deadline) { boost::beast::http::request_serializer serializer(request); serializer.split(false); std::size_t n_bytes = 0; while (!serializer.is_done()) { n_bytes = 0; serializer.next(ec, [this, &n_bytes, &deadline](boost::system::error_code& ec, const auto& buffers) { n_bytes = stream_.write_some(buffers, ec, deadline); }); if (n_bytes) { serializer.consume(n_bytes); } if (ec) { break; } } } template template void base_socket::recv_response(Parser& response_parser, DynamicBuffer& buffer, boost::system::error_code& ec, const time_point_type& deadline) { std::size_t n_bytes = 0; while (!response_parser.is_done()) { // obtain writable buffer sequence boost::optional out_buff; const auto read_size = std::min(65536, buffer.max_size() - buffer.size() - 1); try { out_buff.emplace(buffer.prepare(read_size)); } catch (const std::length_error&) { ec = boost::beast::http::error::buffer_overflow; break; } // read data from stream into writable buffer n_bytes = stream_.read_some(*out_buff, ec, deadline); if (ec == boost::asio::error::eof) { if (response_parser.got_some()) { // caller sees EOF on next read response_parser.put_eof(ec); if (!ec) { continue; } } else { ec = boost::beast::http::error::end_of_stream; } } if (ec) { break; } // commit written data from writable buffer to readable one buffer.commit(n_bytes); // parse data from redable buffer n_bytes = response_parser.put(buffer.data(), ec); buffer.consume(n_bytes); if (ec && ec != boost::beast::http::error::need_more) { break; } } } template template boost::optional> base_socket::recv_response(boost::system::error_code& ec, const time_point_type& deadline) { boost::beast::http::response_parser parser; parser.header_limit(kHeaderLimit); parser.body_limit(kBodyLimit); parser.eager(true); buffer_.consume(buffer_.size()); recv_response(parser, buffer_, ec, deadline); if (ec) { return boost::none; } return parser.get(); } } // namespace http } // namespace stream_client