RequestServer: Support HTTP response write retries on Windows

The Windows RequestPipe implementation uses a non blocking local socket
pair, which means the non-fatal "resource is temporarily unavailable"
error that can occur in the non-blocking HTTP Response data writes can
be retried. This was seen often when loading https://ladybird.org.

While the EAGAIN errno is defined on Windows, WSAEWOULDBLOCK is the
error code returned in this scenario, so we were not detecting that we
could retry and treated the failed write attempt as a proper error.

We now detect WSAEWOULDBLOCK and convert it into the errno equivalent
EWOULDBLOCK. There is precedent for doing a similar conversion in the
Windows PosixSocketHelper::read() implementation.

Finally, we retry when we receive either EAGAIN or EWOULDBLOCK error
codes on all platforms. While POSIX allows these 2 error codes to have
the same value, which they do on Linux according to
https://www.man7.org/linux/man-pages/man3/errno.3.html, it is not
guarenteed. So we now ensure platforms that return EWOULDBLOCK with a
value different than EAGAIN also perform write retries.
This commit is contained in:
ayeteadoe 2025-11-18 14:17:53 -08:00 committed by Jelle Raaijmakers
parent fa262d2db5
commit 8348c55570
Notes: github-actions[bot] 2025-11-19 08:18:27 +00:00
2 changed files with 6 additions and 2 deletions

View file

@ -6,6 +6,7 @@
*/
#include <AK/Enumerate.h>
#include <AK/GenericShorthands.h>
#include <LibCore/Notifier.h>
#include <LibTextCodec/Decoder.h>
#include <RequestServer/CURL.h>
@ -614,7 +615,7 @@ ErrorOr<void> Request::write_queued_bytes_without_blocking()
auto result = m_client_request_pipe->write(bytes_to_send);
if (result.is_error()) {
if (result.error().code() != EAGAIN)
if (!first_is_one_of(result.error().code(), EAGAIN, EWOULDBLOCK))
return result.release_error();
m_client_writer_notifier->set_enabled(true);