summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAli Mohammad Pur <ali.mpfard@gmail.com>2021-09-28 00:06:52 +0330
committerAndreas Kling <kling@serenityos.org>2021-09-28 22:32:31 +0200
commit3ec39fc62e5f7a5dd3ce5251777b909220f6cec3 (patch)
treee37a48e5bc92fb45978b795168f351de117767fc
parent6b2e4f896be8a096fbd18f1c65c1266456de8808 (diff)
downloadserenity-3ec39fc62e5f7a5dd3ce5251777b909220f6cec3.zip
RequestServer+LibProtocol: Add an 'EnsureConnection' IPC endpoint
This will allow LibWeb (and other components) to request a connection to be premade and cached, to make subsequent loads faster.
-rw-r--r--Userland/Libraries/LibProtocol/RequestClient.cpp5
-rw-r--r--Userland/Libraries/LibProtocol/RequestClient.h2
-rw-r--r--Userland/Services/RequestServer/ClientConnection.cpp34
-rw-r--r--Userland/Services/RequestServer/ClientConnection.h1
-rw-r--r--Userland/Services/RequestServer/ConnectionCache.h9
-rw-r--r--Userland/Services/RequestServer/RequestServer.ipc3
6 files changed, 54 insertions, 0 deletions
diff --git a/Userland/Libraries/LibProtocol/RequestClient.cpp b/Userland/Libraries/LibProtocol/RequestClient.cpp
index 00a3f57c58..1449468334 100644
--- a/Userland/Libraries/LibProtocol/RequestClient.cpp
+++ b/Userland/Libraries/LibProtocol/RequestClient.cpp
@@ -15,6 +15,11 @@ RequestClient::RequestClient()
{
}
+void RequestClient::ensure_connection(URL const& url, ::RequestServer::CacheLevel cache_level)
+{
+ async_ensure_connection(url, cache_level);
+}
+
template<typename RequestHashMapTraits>
RefPtr<Request> RequestClient::start_request(String const& method, URL const& url, HashMap<String, String, RequestHashMapTraits> const& request_headers, ReadonlyBytes request_body)
{
diff --git a/Userland/Libraries/LibProtocol/RequestClient.h b/Userland/Libraries/LibProtocol/RequestClient.h
index 7ad2a2fe24..82248e9e3a 100644
--- a/Userland/Libraries/LibProtocol/RequestClient.h
+++ b/Userland/Libraries/LibProtocol/RequestClient.h
@@ -24,6 +24,8 @@ public:
template<typename RequestHashMapTraits = Traits<String>>
RefPtr<Request> start_request(String const& method, URL const&, HashMap<String, String, RequestHashMapTraits> const& request_headers = {}, ReadonlyBytes request_body = {});
+ void ensure_connection(URL const&, ::RequestServer::CacheLevel);
+
bool stop_request(Badge<Request>, Request&);
bool set_certificate(Badge<Request>, Request&, String, String);
diff --git a/Userland/Services/RequestServer/ClientConnection.cpp b/Userland/Services/RequestServer/ClientConnection.cpp
index fc9f61ce77..9061ffd16c 100644
--- a/Userland/Services/RequestServer/ClientConnection.cpp
+++ b/Userland/Services/RequestServer/ClientConnection.cpp
@@ -9,6 +9,7 @@
#include <RequestServer/Protocol.h>
#include <RequestServer/Request.h>
#include <RequestServer/RequestClientEndpoint.h>
+#include <netdb.h>
namespace RequestServer {
@@ -110,4 +111,37 @@ Messages::RequestServer::SetCertificateResponse ClientConnection::set_certificat
return success;
}
+void ClientConnection::ensure_connection(URL const& url, ::RequestServer::CacheLevel const& cache_level)
+{
+ if (!url.is_valid()) {
+ dbgln("EnsureConnection: Invalid URL requested: '{}'", url);
+ return;
+ }
+
+ if (cache_level == CacheLevel::ResolveOnly) {
+ return Core::deferred_invoke([host = url.host()] {
+ dbgln("EnsureConnection: DNS-preload for {}", host);
+ (void)gethostbyname(host.characters());
+ });
+ }
+
+ struct {
+ URL const& m_url;
+ void start(NonnullRefPtr<Core::Socket> socket) { socket->connect(m_url.host(), m_url.port_or_default()); }
+ } job { url };
+
+ dbgln("EnsureConnection: Pre-connect to {}", url);
+ auto do_preconnect = [&](auto& cache) {
+ auto& connection = ConnectionCache::get_or_create_connection(cache, url, job);
+ connection.removal_timer->start();
+ };
+
+ if (url.scheme() == "http"sv)
+ do_preconnect(ConnectionCache::g_tcp_connection_cache);
+ else if (url.scheme() == "https"sv)
+ do_preconnect(ConnectionCache::g_tls_connection_cache);
+ else
+ dbgln("EnsureConnection: Invalid URL scheme: '{}'", url.scheme());
+}
+
}
diff --git a/Userland/Services/RequestServer/ClientConnection.h b/Userland/Services/RequestServer/ClientConnection.h
index b01c207672..2822bd7227 100644
--- a/Userland/Services/RequestServer/ClientConnection.h
+++ b/Userland/Services/RequestServer/ClientConnection.h
@@ -34,6 +34,7 @@ private:
virtual Messages::RequestServer::StartRequestResponse start_request(String const&, URL const&, IPC::Dictionary const&, ByteBuffer const&) override;
virtual Messages::RequestServer::StopRequestResponse stop_request(i32) override;
virtual Messages::RequestServer::SetCertificateResponse set_certificate(i32, String const&, String const&) override;
+ virtual void ensure_connection(URL const& url, ::RequestServer::CacheLevel const& cache_level) override;
HashMap<i32, OwnPtr<Request>> m_requests;
};
diff --git a/Userland/Services/RequestServer/ConnectionCache.h b/Userland/Services/RequestServer/ConnectionCache.h
index d9bbc0975c..2875709d32 100644
--- a/Userland/Services/RequestServer/ConnectionCache.h
+++ b/Userland/Services/RequestServer/ConnectionCache.h
@@ -13,6 +13,15 @@
#include <LibCore/Timer.h>
#include <LibTLS/TLSv12.h>
+namespace RequestServer {
+
+enum class CacheLevel {
+ ResolveOnly,
+ CreateConnection,
+};
+
+}
+
namespace RequestServer::ConnectionCache {
template<typename Socket>
diff --git a/Userland/Services/RequestServer/RequestServer.ipc b/Userland/Services/RequestServer/RequestServer.ipc
index cc4219418f..b02be37eb6 100644
--- a/Userland/Services/RequestServer/RequestServer.ipc
+++ b/Userland/Services/RequestServer/RequestServer.ipc
@@ -1,4 +1,5 @@
#include <AK/URL.h>
+#include <RequestServer/ConnectionCache.h>
endpoint RequestServer
{
@@ -8,4 +9,6 @@ endpoint RequestServer
start_request(String method, URL url, IPC::Dictionary request_headers, ByteBuffer request_body) => (i32 request_id, Optional<IPC::File> response_fd)
stop_request(i32 request_id) => (bool success)
set_certificate(i32 request_id, String certificate, String key) => (bool success)
+
+ ensure_connection(URL url, ::RequestServer::CacheLevel cache_level) =|
}