mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-09-29 20:59:00 +00:00
RequestServer: Implement preconnect for CreateConnection cache level
This commit is contained in:
parent
feba8e6218
commit
fc53422e1c
Notes:
github-actions[bot]
2024-11-03 19:03:56 +00:00
Author: https://github.com/rmg-x
Commit: fc53422e1c
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/2131
Reviewed-by: https://github.com/alimpfard
1 changed files with 61 additions and 15 deletions
|
@ -26,6 +26,7 @@ namespace RequestServer {
|
||||||
ByteString g_default_certificate_path;
|
ByteString g_default_certificate_path;
|
||||||
static HashMap<int, RefPtr<ConnectionFromClient>> s_connections;
|
static HashMap<int, RefPtr<ConnectionFromClient>> s_connections;
|
||||||
static IDAllocator s_client_ids;
|
static IDAllocator s_client_ids;
|
||||||
|
static long s_connect_timeout_seconds = 90L;
|
||||||
|
|
||||||
struct ConnectionFromClient::ActiveRequest {
|
struct ConnectionFromClient::ActiveRequest {
|
||||||
CURLM* multi { nullptr };
|
CURLM* multi { nullptr };
|
||||||
|
@ -36,6 +37,7 @@ struct ConnectionFromClient::ActiveRequest {
|
||||||
int writer_fd { 0 };
|
int writer_fd { 0 };
|
||||||
HTTP::HeaderMap headers;
|
HTTP::HeaderMap headers;
|
||||||
bool got_all_headers { false };
|
bool got_all_headers { false };
|
||||||
|
bool is_connect_only { false };
|
||||||
size_t downloaded_so_far { 0 };
|
size_t downloaded_so_far { 0 };
|
||||||
String url;
|
String url;
|
||||||
Optional<String> reason_phrase;
|
Optional<String> reason_phrase;
|
||||||
|
@ -52,7 +54,9 @@ struct ConnectionFromClient::ActiveRequest {
|
||||||
|
|
||||||
~ActiveRequest()
|
~ActiveRequest()
|
||||||
{
|
{
|
||||||
|
if (writer_fd > 0)
|
||||||
MUST(Core::System::close(writer_fd));
|
MUST(Core::System::close(writer_fd));
|
||||||
|
|
||||||
auto result = curl_multi_remove_handle(multi, easy);
|
auto result = curl_multi_remove_handle(multi, easy);
|
||||||
VERIFY(result == CURLM_OK);
|
VERIFY(result == CURLM_OK);
|
||||||
curl_easy_cleanup(easy);
|
curl_easy_cleanup(easy);
|
||||||
|
@ -308,7 +312,7 @@ void ConnectionFromClient::start_request(i32 request_id, ByteString const& metho
|
||||||
set_option(CURLOPT_ACCEPT_ENCODING, "gzip, deflate, br");
|
set_option(CURLOPT_ACCEPT_ENCODING, "gzip, deflate, br");
|
||||||
set_option(CURLOPT_URL, url.to_string().value().to_byte_string().characters());
|
set_option(CURLOPT_URL, url.to_string().value().to_byte_string().characters());
|
||||||
set_option(CURLOPT_PORT, url.port_or_default());
|
set_option(CURLOPT_PORT, url.port_or_default());
|
||||||
set_option(CURLOPT_CONNECTTIMEOUT, 90L);
|
set_option(CURLOPT_CONNECTTIMEOUT, s_connect_timeout_seconds);
|
||||||
|
|
||||||
if (method == "GET"sv) {
|
if (method == "GET"sv) {
|
||||||
set_option(CURLOPT_HTTPGET, 1L);
|
set_option(CURLOPT_HTTPGET, 1L);
|
||||||
|
@ -379,6 +383,8 @@ void ConnectionFromClient::check_active_requests()
|
||||||
ActiveRequest* request = nullptr;
|
ActiveRequest* request = nullptr;
|
||||||
auto result = curl_easy_getinfo(msg->easy_handle, CURLINFO_PRIVATE, &request);
|
auto result = curl_easy_getinfo(msg->easy_handle, CURLINFO_PRIVATE, &request);
|
||||||
VERIFY(result == CURLE_OK);
|
VERIFY(result == CURLE_OK);
|
||||||
|
|
||||||
|
if (!request->is_connect_only) {
|
||||||
request->flush_headers_if_needed();
|
request->flush_headers_if_needed();
|
||||||
|
|
||||||
auto result_code = msg->data.result;
|
auto result_code = msg->data.result;
|
||||||
|
@ -395,6 +401,7 @@ void ConnectionFromClient::check_active_requests()
|
||||||
}
|
}
|
||||||
|
|
||||||
async_request_finished(request->request_id, request->downloaded_so_far, network_error);
|
async_request_finished(request->request_id, request->downloaded_so_far, network_error);
|
||||||
|
}
|
||||||
|
|
||||||
m_active_requests.remove(request->request_id);
|
m_active_requests.remove(request->request_id);
|
||||||
}
|
}
|
||||||
|
@ -443,8 +450,47 @@ void ConnectionFromClient::ensure_connection(URL::URL const& url, ::RequestServe
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
(void)cache_level;
|
auto const url_string_value = url.to_string().value();
|
||||||
dbgln("FIXME: EnsureConnection: Pre-connect to {}", url);
|
|
||||||
|
if (cache_level == CacheLevel::CreateConnection) {
|
||||||
|
auto* easy = curl_easy_init();
|
||||||
|
if (!easy) {
|
||||||
|
dbgln("EnsureConnection: Failed to initialize curl easy handle");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto set_option = [easy](auto option, auto value) {
|
||||||
|
auto result = curl_easy_setopt(easy, option, value);
|
||||||
|
if (result != CURLE_OK) {
|
||||||
|
dbgln("EnsureConnection: Failed to set curl option: {}", curl_easy_strerror(result));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
auto connect_only_request_id = get_random<i32>();
|
||||||
|
|
||||||
|
auto request = make<ActiveRequest>(*this, m_curl_multi, easy, connect_only_request_id, 0);
|
||||||
|
request->url = url_string_value;
|
||||||
|
request->is_connect_only = true;
|
||||||
|
|
||||||
|
set_option(CURLOPT_PRIVATE, request.ptr());
|
||||||
|
set_option(CURLOPT_URL, url_string_value.to_byte_string().characters());
|
||||||
|
set_option(CURLOPT_PORT, url.port_or_default());
|
||||||
|
set_option(CURLOPT_CONNECTTIMEOUT, s_connect_timeout_seconds);
|
||||||
|
set_option(CURLOPT_CONNECT_ONLY, 1L);
|
||||||
|
|
||||||
|
auto const result = curl_multi_add_handle(m_curl_multi, easy);
|
||||||
|
VERIFY(result == CURLM_OK);
|
||||||
|
|
||||||
|
m_active_requests.set(connect_only_request_id, move(request));
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cache_level == CacheLevel::ResolveOnly) {
|
||||||
|
dbgln("FIXME: EnsureConnection: Implement ResolveOnly cache level");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConnectionFromClient::websocket_connect(i64 websocket_id, URL::URL const& url, ByteString const& origin, Vector<ByteString> const& protocols, Vector<ByteString> const& extensions, HTTP::HeaderMap const& additional_request_headers)
|
void ConnectionFromClient::websocket_connect(i64 websocket_id, URL::URL const& url, ByteString const& origin, Vector<ByteString> const& protocols, Vector<ByteString> const& extensions, HTTP::HeaderMap const& additional_request_headers)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue