Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

async reading when not all data arrived #100

Merged
merged 1 commit into from
Jun 20, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 24 additions & 19 deletions CRUD/service/persistent_connection.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,14 @@
#include "reply.hpp"
#include "request.hpp"
#include "request_parser.hpp"

namespace http {
namespace server {


namespace http::server {

template<class> class connection_manager;


/// Result of data read.
enum data_read_result { complete, indeterminate };

/// Represents a single connection from a client.
template <typename request_handler_type>
class persistent_connection
Expand Down Expand Up @@ -85,12 +87,11 @@ class persistent_connection

if (result == request_parser::good) [[likely]]
{
ec = read_data_if(data, bytes_transferred);
if (!ec) [[likely]]
{
auto status = handle_request_if(data, bytes_transferred);
if (status == data_read_result::complete) {
request_handler_.handle_request(request_, reply_);
do_write();
}
do_write();
}
else if (result == request_parser::bad)
{
Expand Down Expand Up @@ -126,26 +127,34 @@ class persistent_connection
});
}

boost::system::error_code read_data_if(char * const data, std::size_t bytes_transferred) {
data_read_result handle_request_if(char * const data, std::size_t bytes_transferred) {
static constexpr auto is_content_length = [](const header &h) noexcept { return h.name == "content-length" ; };

boost::system::error_code ec{};
data_read_result completion_status{data_read_result::complete};
if (data != nullptr) {
auto itr = find_if(begin(request_.headers), end(request_.headers), is_content_length);

if (itr != end(request_.headers)) {
auto received_data_size = std::distance(data, buffer_.data() + bytes_transferred);
auto content_length_value = boost::lexical_cast<long>(itr->value);
request_.data = std::string(data, content_length_value);
request_.data = std::string(data, received_data_size);
if (received_data_size < content_length_value) {
completion_status = data_read_result::indeterminate;
request_.data.resize(content_length_value);
auto left_over_size = content_length_value - received_data_size;
auto end_data_ptr = request_.data.data() + received_data_size;
auto left_over_buffer = boost::asio::buffer(end_data_ptr, left_over_size);
boost::asio::read(socket_, left_over_buffer, ec);
boost::asio::async_read(socket_, left_over_buffer, boost::asio::transfer_exactly(left_over_size),
[this](boost::system::error_code ec, std::size_t) {
if (!ec) [[likely]] {
request_handler_.handle_request(request_, reply_);
}
do_write();
});
}
}
}
return ec;
return completion_status;
}

/// Socket for the persistent_connection.
Expand All @@ -170,9 +179,5 @@ class persistent_connection
reply reply_;

};


} // namespace server
} // namespace http

} // namespace http::server
#endif // HTTP_PERSISTENT_CONNECTION_HPP