diff --git a/Userland/Libraries/LibCore/Socket.cpp b/Userland/Libraries/LibCore/Socket.cpp index dc28ed58a59..418f3a8c7a0 100644 --- a/Userland/Libraries/LibCore/Socket.cpp +++ b/Userland/Libraries/LibCore/Socket.cpp @@ -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); diff --git a/Userland/Libraries/LibCore/Socket.h b/Userland/Libraries/LibCore/Socket.h index 58823b7fbdb..359e8a56c8e 100644 --- a/Userland/Libraries/LibCore/Socket.h +++ b/Userland/Libraries/LibCore/Socket.h @@ -43,6 +43,7 @@ public: int destination_port() const { return m_destination_port; } Function on_connected; + Function on_error; Function on_ready_to_read; protected: diff --git a/Userland/Libraries/LibHTTP/HttpJob.cpp b/Userland/Libraries/LibHTTP/HttpJob.cpp index d8c480c09a4..6e8d36de783 100644 --- a/Userland/Libraries/LibHTTP/HttpJob.cpp +++ b/Userland/Libraries/LibHTTP/HttpJob.cpp @@ -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&) {