diff options
author | Ali Mohammad Pur <ali.mpfard@gmail.com> | 2021-09-30 12:19:54 +0330 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-09-30 11:46:37 +0200 |
commit | b0a9c5673e7a8a100ddd827b780abe7d284802c1 (patch) | |
tree | 282c91f61d3f2f11f8661a193a27a8e4a7fc5ad8 /Userland/Libraries/LibHTTP | |
parent | d16131b100aaf74e2d69207aea2c8a586bec6f1e (diff) | |
download | serenity-b0a9c5673e7a8a100ddd827b780abe7d284802c1.zip |
LibHTTP: Respect the 'Connection: close' header on keep-alive jobs
If the server responds with this header, we _must_ close the connection,
as the server is allowed to ignore the socket and not respond to
anything past that response.
Fixes some RequestServer spins.
Diffstat (limited to 'Userland/Libraries/LibHTTP')
-rw-r--r-- | Userland/Libraries/LibHTTP/HttpJob.cpp | 12 | ||||
-rw-r--r-- | Userland/Libraries/LibHTTP/HttpJob.h | 2 | ||||
-rw-r--r-- | Userland/Libraries/LibHTTP/HttpsJob.cpp | 14 | ||||
-rw-r--r-- | Userland/Libraries/LibHTTP/HttpsJob.h | 2 | ||||
-rw-r--r-- | Userland/Libraries/LibHTTP/Job.cpp | 4 | ||||
-rw-r--r-- | Userland/Libraries/LibHTTP/Job.h | 2 |
6 files changed, 24 insertions, 12 deletions
diff --git a/Userland/Libraries/LibHTTP/HttpJob.cpp b/Userland/Libraries/LibHTTP/HttpJob.cpp index 58ab0e28d6..6e0115c341 100644 --- a/Userland/Libraries/LibHTTP/HttpJob.cpp +++ b/Userland/Libraries/LibHTTP/HttpJob.cpp @@ -43,13 +43,17 @@ void HttpJob::start(NonnullRefPtr<Core::Socket> socket) }; } -void HttpJob::shutdown() +void HttpJob::shutdown(ShutdownMode mode) { if (!m_socket) return; - m_socket->on_ready_to_read = nullptr; - m_socket->on_connected = nullptr; - m_socket = nullptr; + if (mode == ShutdownMode::CloseSocket) { + m_socket->close(); + } else { + m_socket->on_ready_to_read = nullptr; + m_socket->on_connected = nullptr; + m_socket = nullptr; + } } void HttpJob::register_on_ready_to_read(Function<void()> callback) diff --git a/Userland/Libraries/LibHTTP/HttpJob.h b/Userland/Libraries/LibHTTP/HttpJob.h index 16ccb3abfb..08acf9ef79 100644 --- a/Userland/Libraries/LibHTTP/HttpJob.h +++ b/Userland/Libraries/LibHTTP/HttpJob.h @@ -28,7 +28,7 @@ public: } virtual void start(NonnullRefPtr<Core::Socket>) override; - virtual void shutdown() override; + virtual void shutdown(ShutdownMode) override; Core::Socket const* socket() const { return m_socket; } URL url() const { return m_request.url(); } diff --git a/Userland/Libraries/LibHTTP/HttpsJob.cpp b/Userland/Libraries/LibHTTP/HttpsJob.cpp index abaeb662f6..cadfbea933 100644 --- a/Userland/Libraries/LibHTTP/HttpsJob.cpp +++ b/Userland/Libraries/LibHTTP/HttpsJob.cpp @@ -62,14 +62,18 @@ void HttpsJob::start(NonnullRefPtr<Core::Socket> socket) } } -void HttpsJob::shutdown() +void HttpsJob::shutdown(ShutdownMode mode) { if (!m_socket) return; - m_socket->on_tls_ready_to_read = nullptr; - m_socket->on_tls_connected = nullptr; - m_socket->set_on_tls_ready_to_write(nullptr); - m_socket = nullptr; + if (mode == ShutdownMode::CloseSocket) { + m_socket->close(); + } else { + m_socket->on_tls_ready_to_read = nullptr; + m_socket->on_tls_connected = nullptr; + m_socket->set_on_tls_ready_to_write(nullptr); + m_socket = nullptr; + } } void HttpsJob::set_certificate(String certificate, String private_key) diff --git a/Userland/Libraries/LibHTTP/HttpsJob.h b/Userland/Libraries/LibHTTP/HttpsJob.h index c7c20ea7e6..149861727a 100644 --- a/Userland/Libraries/LibHTTP/HttpsJob.h +++ b/Userland/Libraries/LibHTTP/HttpsJob.h @@ -29,7 +29,7 @@ public: } virtual void start(NonnullRefPtr<Core::Socket>) override; - virtual void shutdown() override; + virtual void shutdown(ShutdownMode) override; void set_certificate(String certificate, String key); Core::Socket const* socket() const { return m_socket; } diff --git a/Userland/Libraries/LibHTTP/Job.cpp b/Userland/Libraries/LibHTTP/Job.cpp index 97c4b317bd..8141a3e869 100644 --- a/Userland/Libraries/LibHTTP/Job.cpp +++ b/Userland/Libraries/LibHTTP/Job.cpp @@ -412,6 +412,10 @@ void Job::finish_up() m_has_scheduled_finish = true; auto response = HttpResponse::create(m_code, move(m_headers)); deferred_invoke([this, response = move(response)] { + // If the server responded with "Connection: close", close the connection + // as the server may or may not want to close the socket. + if (auto result = response->headers().get("Connection"sv); result.has_value() && result.value().equals_ignoring_case("close"sv)) + shutdown(ShutdownMode::CloseSocket); did_finish(response); }); } diff --git a/Userland/Libraries/LibHTTP/Job.h b/Userland/Libraries/LibHTTP/Job.h index 99a6e0607f..7eb85154df 100644 --- a/Userland/Libraries/LibHTTP/Job.h +++ b/Userland/Libraries/LibHTTP/Job.h @@ -22,7 +22,7 @@ public: virtual ~Job() override; virtual void start(NonnullRefPtr<Core::Socket>) override = 0; - virtual void shutdown() override = 0; + virtual void shutdown(ShutdownMode) override = 0; HttpResponse* response() { return static_cast<HttpResponse*>(Core::NetworkJob::response()); } const HttpResponse* response() const { return static_cast<const HttpResponse*>(Core::NetworkJob::response()); } |