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

parser should have an interface to check if it needs input #99

Open
ashtum opened this issue Aug 14, 2024 · 2 comments
Open

parser should have an interface to check if it needs input #99

ashtum opened this issue Aug 14, 2024 · 2 comments

Comments

@ashtum
Copy link
Collaborator

ashtum commented Aug 14, 2024

If two or more HTTP responses are read into the parser buffer, and the parser::prepare() buffer returns a non-empty mutable buffer, then the subsequent async_read_some operation on the stream will block indefinitely, assuming all responses have already been delivered. For example:

context ctx;
response_parser::config cfg;
install_parser_service(ctx, cfg);
response_parser pr(ctx);
system::error_code ec;
pr.reset();
pr.start_head_response();
std::string in = 
    "HTTP/1.1 200 OK\r\n"
    "\r\n"
    "HTTP/1.1 200 OK\r\n"
    "\r\n";
auto n = buffers::buffer_copy(
    pr.prepare(),
    buffers::const_buffer(in.data(), in.size()));
BOOST_TEST(n == in.size());
pr.commit(n);
pr.parse(ec);
BOOST_TEST(! ec.failed());
BOOST_TEST(pr.got_header());
pr.start_head_response();
BOOST_TEST(buffers::buffer_size(pr.prepare()) > 0);

This happens because the leftover data in the buffer isn't fully parsed when parser::prepare() is called. As a result, we can't determine if the buffer contains a complete or a partial message. To prevent indefinite blocking, we should assume that any leftover data after parsing a message might indicate a complete message. Therefore, we should avoid initiating another read attempt if leftovers are present.

The flow would be as follows:

pr.start();
if (pr.need_data())
{
  // Prepare buffer and read from the stream
}
pr.parse();
@vinniefalco
Copy link
Member

You should show the smallest possible example code which uses the parser to extract two complete messages which are already stuffed into its input buffer

@ashtum
Copy link
Collaborator Author

ashtum commented Aug 15, 2024

You should show the smallest possible example code which uses the parser to extract two complete messages which are already stuffed into its input buffer

I've added the example to the first comment.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants