diff --git a/client_http.hpp b/client_http.hpp index 619aa09..28744d1 100644 --- a/client_http.hpp +++ b/client_http.hpp @@ -541,31 +541,19 @@ namespace SimpleWeb { } void read_chunked(const std::shared_ptr &session, const std::shared_ptr &tmp_streambuf) { - if(tmp_streambuf->size() >= config.max_response_streambuf_size) { - session->callback(session->connection, make_error_code::make_error_code(errc::message_size)); - return; - } - // chunked_streambuf is needed as new read buffer with its size adjusted depending on the size of tmp_streambuf - auto chunked_streambuf = std::make_shared(config.max_response_streambuf_size - tmp_streambuf->size()); - // Move excess read data from session->response->streambuf to chunked_streambuf - if(session->response->streambuf.size() > 0) { - std::ostream chunked_stream(chunked_streambuf.get()); - chunked_stream << &session->response->streambuf; - } session->connection->set_timeout(); - asio::async_read_until(*session->connection->socket, *chunked_streambuf, "\r\n", [this, session, chunked_streambuf, tmp_streambuf](const error_code &ec, std::size_t bytes_transferred) { + asio::async_read_until(*session->connection->socket, session->response->streambuf, "\r\n", [this, session, tmp_streambuf](const error_code &ec, size_t bytes_transferred) { session->connection->cancel_timeout(); auto lock = session->connection->handler_runner->continue_lock(); if(!lock) return; - if((!ec || ec == asio::error::not_found) && chunked_streambuf->size() == chunked_streambuf->max_size()) { + if((!ec || ec == asio::error::not_found) && session->response->streambuf.size() == session->response->streambuf.max_size()) { session->callback(session->connection, make_error_code::make_error_code(errc::message_size)); return; } if(!ec) { std::string line; - std::istream chunked_stream(chunked_streambuf.get()); - getline(chunked_stream, line); + getline(session->response->content, line); bytes_transferred -= line.size() + 1; line.pop_back(); unsigned long length; @@ -577,28 +565,27 @@ namespace SimpleWeb { return; } - auto num_additional_bytes = chunked_streambuf->size() - bytes_transferred; + auto num_additional_bytes = session->response->streambuf.size() - bytes_transferred; - auto post_process = [this, session, chunked_streambuf, tmp_streambuf, length]() { - std::istream chunked_stream(chunked_streambuf.get()); + auto post_process = [this, session, tmp_streambuf, length]() { std::ostream tmp_stream(tmp_streambuf.get()); if(length > 0) { std::unique_ptr buffer(new char[length]); - chunked_stream.read(buffer.get(), static_cast(length)); + session->response->content.read(buffer.get(), static_cast(length)); tmp_stream.write(buffer.get(), static_cast(length)); + if(tmp_streambuf->size() == tmp_streambuf->max_size()) { + session->callback(session->connection, make_error_code::make_error_code(errc::message_size)); + return; + } } // Remove "\r\n" - chunked_stream.get(); - chunked_stream.get(); + session->response->content.get(); + session->response->content.get(); - if (length > 0) { - if (chunked_streambuf->size() > 0) { - std::ostream response_stream(&session->response->streambuf); - response_stream << chunked_streambuf.get(); - } - this->read_chunked(session, tmp_streambuf); - }else { + if(length > 0) + this->read_chunked(session, tmp_streambuf); + else { if(tmp_streambuf->size() > 0) { std::ostream response_stream(&session->response->streambuf); response_stream << tmp_streambuf.get(); @@ -610,13 +597,13 @@ namespace SimpleWeb { if((2 + length) > num_additional_bytes) { session->connection->set_timeout(); - asio::async_read(*session->connection->socket, *chunked_streambuf, asio::transfer_exactly(2 + length - num_additional_bytes), [this, session, chunked_streambuf, post_process](const error_code &ec, std::size_t /*bytes_transferred*/) { + asio::async_read(*session->connection->socket, session->response->streambuf, asio::transfer_exactly(2 + length - num_additional_bytes), [this, session, post_process](const error_code &ec, size_t /*bytes_transferred*/) { session->connection->cancel_timeout(); auto lock = session->connection->handler_runner->continue_lock(); if(!lock) return; if(!ec) { - if(chunked_streambuf->size() == chunked_streambuf->max_size()) { + if(session->response->streambuf.size() == session->response->streambuf.max_size()) { session->callback(session->connection, make_error_code::make_error_code(errc::message_size)); return; }