From 05a2d1f0e0ce6ea78282dc6bc7ec6cc3987a7403 Mon Sep 17 00:00:00 2001 From: Aliaksandr Kalenik Date: Thu, 23 Mar 2023 03:14:17 +0300 Subject: [PATCH] LibWeb/WebDriver: Wait for more data to arrive if request is incomplete Currently significant portion of requests coming to WebDriver server fails with error while parsing json body because requests are parsed when they are not complete yet. This change solves this by waiting for more data to arrive if HTTP request parser found that there is not enough data yet to parse the whole request. In the future we would probably want to move this logic to LibHTTP because this problem is relevant for any HTTP server. --- Userland/Libraries/LibWeb/WebDriver/Client.cpp | 18 +++++++++++++++--- Userland/Libraries/LibWeb/WebDriver/Client.h | 1 + 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/Userland/Libraries/LibWeb/WebDriver/Client.cpp b/Userland/Libraries/LibWeb/WebDriver/Client.cpp index 3724c77606..45bbf4e9f0 100644 --- a/Userland/Libraries/LibWeb/WebDriver/Client.cpp +++ b/Userland/Libraries/LibWeb/WebDriver/Client.cpp @@ -211,20 +211,32 @@ ErrorOr Client::on_ready_to_read() { // FIXME: All this should be moved to LibHTTP and be made spec compliant. auto buffer = TRY(ByteBuffer::create_uninitialized(m_socket->buffer_size())); - StringBuilder builder; for (;;) { if (!TRY(m_socket->can_read_without_blocking())) break; auto data = TRY(m_socket->read_some(buffer)); - TRY(builder.try_append(StringView { data })); + TRY(m_remaining_request.try_append(StringView { data })); if (m_socket->is_eof()) break; } - m_request = TRY(HTTP::HttpRequest::from_raw_request(TRY(builder.to_byte_buffer()))); + if (m_remaining_request.is_empty()) + return {}; + + auto maybe_parsed_request = HTTP::HttpRequest::from_raw_request(TRY(m_remaining_request.to_byte_buffer())); + if (maybe_parsed_request.is_error()) { + if (maybe_parsed_request.error() == HTTP::HttpRequest::ParseError::RequestIncomplete) { + // If request is not complete we need to wait for more data to arrive + return {}; + } + return maybe_parsed_request.error(); + } + + m_remaining_request.clear(); + m_request = maybe_parsed_request.value(); auto body = TRY(read_body_as_json()); TRY(handle_request(move(body))); diff --git a/Userland/Libraries/LibWeb/WebDriver/Client.h b/Userland/Libraries/LibWeb/WebDriver/Client.h index f6c1f07225..8c5889ef4f 100644 --- a/Userland/Libraries/LibWeb/WebDriver/Client.h +++ b/Userland/Libraries/LibWeb/WebDriver/Client.h @@ -121,6 +121,7 @@ private: NonnullOwnPtr m_socket; Optional m_request; + StringBuilder m_remaining_request; }; }