summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibHTTP
diff options
context:
space:
mode:
authorAli Mohammad Pur <ali.mpfard@gmail.com>2021-09-30 12:19:54 +0330
committerAndreas Kling <kling@serenityos.org>2021-09-30 11:46:37 +0200
commitb0a9c5673e7a8a100ddd827b780abe7d284802c1 (patch)
tree282c91f61d3f2f11f8661a193a27a8e4a7fc5ad8 /Userland/Libraries/LibHTTP
parentd16131b100aaf74e2d69207aea2c8a586bec6f1e (diff)
downloadserenity-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.cpp12
-rw-r--r--Userland/Libraries/LibHTTP/HttpJob.h2
-rw-r--r--Userland/Libraries/LibHTTP/HttpsJob.cpp14
-rw-r--r--Userland/Libraries/LibHTTP/HttpsJob.h2
-rw-r--r--Userland/Libraries/LibHTTP/Job.cpp4
-rw-r--r--Userland/Libraries/LibHTTP/Job.h2
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()); }