summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibGemini
diff options
context:
space:
mode:
authorAli Mohammad Pur <ali.mpfard@gmail.com>2021-09-18 03:48:22 +0430
committerAli Mohammad Pur <Ali.mpfard@gmail.com>2021-09-19 21:10:23 +0430
commit65f7e45a75c44fd0af7af6b8373999358b2ca81c (patch)
treeada960a6cfce11ce97e1706945a027c5bccfd702 /Userland/Libraries/LibGemini
parentc5d7eb86189e0fbd9f6a9da1afe29b6a9ab533a4 (diff)
downloadserenity-65f7e45a75c44fd0af7af6b8373999358b2ca81c.zip
RequestServer+LibHTTP+LibGemini: Cache connections to the same host
This makes connections (particularly TLS-based ones) do the handshaking stuff only once. Currently the cache is configured to keep at most two connections evenly balanced in queue size, and with a grace period of 10s after the last queued job has finished (after which the connection will be dropped).
Diffstat (limited to 'Userland/Libraries/LibGemini')
-rw-r--r--Userland/Libraries/LibGemini/GeminiJob.cpp30
-rw-r--r--Userland/Libraries/LibGemini/GeminiJob.h5
-rw-r--r--Userland/Libraries/LibGemini/Job.h2
3 files changed, 22 insertions, 15 deletions
diff --git a/Userland/Libraries/LibGemini/GeminiJob.cpp b/Userland/Libraries/LibGemini/GeminiJob.cpp
index 6ab80ae571..340d470644 100644
--- a/Userland/Libraries/LibGemini/GeminiJob.cpp
+++ b/Userland/Libraries/LibGemini/GeminiJob.cpp
@@ -14,15 +14,11 @@
namespace Gemini {
-void GeminiJob::start()
+void GeminiJob::start(NonnullRefPtr<Core::Socket> socket)
{
VERIFY(!m_socket);
- m_socket = TLS::TLSv12::construct(this);
- m_socket->set_root_certificates(m_override_ca_certificates ? *m_override_ca_certificates : DefaultRootCACertificates::the().certificates());
- m_socket->on_tls_connected = [this] {
- dbgln_if(GEMINIJOB_DEBUG, "GeminiJob: on_connected callback");
- on_socket_connected();
- };
+ VERIFY(is<TLS::TLSv12>(*socket));
+ m_socket = static_ptr_cast<TLS::TLSv12>(socket);
m_socket->on_tls_error = [this](TLS::AlertDescription error) {
if (error == TLS::AlertDescription::HandshakeFailure) {
deferred_invoke([this] {
@@ -45,11 +41,20 @@ void GeminiJob::start()
if (on_certificate_requested)
on_certificate_requested(*this);
};
- bool success = ((TLS::TLSv12&)*m_socket).connect(m_request.url().host(), m_request.url().port_or_default());
- if (!success) {
- deferred_invoke([this] {
- return did_fail(Core::NetworkJob::Error::ConnectionFailed);
- });
+
+ if (m_socket->is_established()) {
+ deferred_invoke([this] { on_socket_connected(); });
+ } else {
+ m_socket->set_root_certificates(m_override_ca_certificates ? *m_override_ca_certificates : DefaultRootCACertificates::the().certificates());
+ m_socket->on_tls_connected = [this] {
+ on_socket_connected();
+ };
+ bool success = ((TLS::TLSv12&)*m_socket).connect(m_request.url().host(), m_request.url().port_or_default());
+ if (!success) {
+ deferred_invoke([this] {
+ return did_fail(Core::NetworkJob::Error::ConnectionFailed);
+ });
+ }
}
}
@@ -59,7 +64,6 @@ void GeminiJob::shutdown()
return;
m_socket->on_tls_ready_to_read = nullptr;
m_socket->on_tls_connected = nullptr;
- remove_child(*m_socket);
m_socket = nullptr;
}
diff --git a/Userland/Libraries/LibGemini/GeminiJob.h b/Userland/Libraries/LibGemini/GeminiJob.h
index 2407d2cca5..20cc8afcf9 100644
--- a/Userland/Libraries/LibGemini/GeminiJob.h
+++ b/Userland/Libraries/LibGemini/GeminiJob.h
@@ -27,10 +27,13 @@ public:
{
}
- virtual void start() override;
+ virtual void start(NonnullRefPtr<Core::Socket>) override;
virtual void shutdown() override;
void set_certificate(String certificate, String key);
+ Core::Socket const* socket() const { return m_socket; }
+ URL url() const { return m_request.url(); }
+
Function<void(GeminiJob&)> on_certificate_requested;
protected:
diff --git a/Userland/Libraries/LibGemini/Job.h b/Userland/Libraries/LibGemini/Job.h
index 01eac13e11..5bc50216f7 100644
--- a/Userland/Libraries/LibGemini/Job.h
+++ b/Userland/Libraries/LibGemini/Job.h
@@ -19,7 +19,7 @@ public:
explicit Job(const GeminiRequest&, OutputStream&);
virtual ~Job() override;
- virtual void start() override = 0;
+ virtual void start(NonnullRefPtr<Core::Socket>) override = 0;
virtual void shutdown() override = 0;
GeminiResponse* response() { return static_cast<GeminiResponse*>(Core::NetworkJob::response()); }