mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-04-21 03:55:24 +00:00
LibCore+LibHTTP: Check the status of the socket after EINPROGRESS
Previously the system would assume the socket was connected after the file descriptor became writeable. Just because the fd is signaled as ready for output does not necessarily indicate the socket is connected. Instead, we should check the status of the socket with SO_ERROR and handle successes/errors accordingly.
This commit is contained in:
parent
6743170f4e
commit
d456af1cd3
Notes:
sideshowbarker
2024-07-18 07:01:38 +09:00
Author: https://github.com/brapru Commit: https://github.com/SerenityOS/serenity/commit/d456af1cd31 Pull-request: https://github.com/SerenityOS/serenity/pull/9354 Issue: https://github.com/SerenityOS/serenity/issues/7966 Reviewed-by: https://github.com/alimpfard ✅
3 changed files with 30 additions and 6 deletions
|
@ -118,16 +118,33 @@ bool Socket::connect(const SocketAddress& address)
|
|||
bool Socket::common_connect(const struct sockaddr* addr, socklen_t addrlen)
|
||||
{
|
||||
auto connected = [this] {
|
||||
dbgln_if(CSOCKET_DEBUG, "{} connected!", *this);
|
||||
if (!m_connected) {
|
||||
int so_error;
|
||||
socklen_t so_error_len = sizeof(so_error);
|
||||
|
||||
int rc = getsockopt(fd(), SOL_SOCKET, SO_ERROR, &so_error, &so_error_len);
|
||||
if (rc < 0) {
|
||||
dbgln_if(CSOCKET_DEBUG, "Failed to check the status of SO_ERROR");
|
||||
m_connected = false;
|
||||
if (on_error)
|
||||
on_error();
|
||||
}
|
||||
|
||||
if (so_error == 0) {
|
||||
dbgln_if(CSOCKET_DEBUG, "{} connected!", *this);
|
||||
m_connected = true;
|
||||
ensure_read_notifier();
|
||||
if (m_notifier) {
|
||||
m_notifier->remove_from_parent();
|
||||
m_notifier = nullptr;
|
||||
}
|
||||
if (on_connected)
|
||||
on_connected();
|
||||
} else {
|
||||
dbgln_if(CSOCKET_DEBUG, "Failed to connect to {}", *this);
|
||||
m_connected = false;
|
||||
if (on_error)
|
||||
on_error();
|
||||
}
|
||||
|
||||
if (m_notifier) {
|
||||
m_notifier->remove_from_parent();
|
||||
m_notifier = nullptr;
|
||||
}
|
||||
};
|
||||
int rc = ::connect(fd(), addr, addrlen);
|
||||
|
|
|
@ -43,6 +43,7 @@ public:
|
|||
int destination_port() const { return m_destination_port; }
|
||||
|
||||
Function<void()> on_connected;
|
||||
Function<void()> on_error;
|
||||
Function<void()> on_ready_to_read;
|
||||
|
||||
protected:
|
||||
|
|
|
@ -20,6 +20,12 @@ void HttpJob::start()
|
|||
dbgln_if(CHTTPJOB_DEBUG, "HttpJob: on_connected callback");
|
||||
on_socket_connected();
|
||||
};
|
||||
m_socket->on_error = [this] {
|
||||
dbgln_if(CHTTPJOB_DEBUG, "HttpJob: on_error callback");
|
||||
deferred_invoke([this](auto&) {
|
||||
did_fail(Core::NetworkJob::Error::ConnectionFailed);
|
||||
});
|
||||
};
|
||||
bool success = m_socket->connect(m_request.url().host(), m_request.url().port());
|
||||
if (!success) {
|
||||
deferred_invoke([this](auto&) {
|
||||
|
|
Loading…
Add table
Reference in a new issue