1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 20:27:45 +00:00

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.
This commit is contained in:
Ali Mohammad Pur 2021-09-28 00:06:52 +03:30 committed by Andreas Kling
parent 6b2e4f896b
commit 3ec39fc62e
6 changed files with 54 additions and 0 deletions

View file

@ -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)
{

View file

@ -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);

View file

@ -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());
}
}

View file

@ -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;
};

View file

@ -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>

View file

@ -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) =|
}