LibWeb+RequestServer: Attach HTTP cookie headers from RequestServer

We currently attach HTTP cookie headers from LibWeb within Fetch. This
has the downside that the cookie IPC, and the infrastructure around it,
are all synchronous. This blocks the WebContent process entirely while
the cookie is being retrieved, for every request on a page.

We now attach cookie headers from RequestServer. The state machine in
RequestServer::Request allows us to easily do this work asynchronously.
We can also skip this work entirely when the response is served from
disk cache.

Note that we will continue to parse cookies in the WebContent process.
If something goes awry during parsing. we limit the damage to that
process, instead of the UI or RequestServer.

Also note that WebSocket requests still have cookie headers attached
attached from LibWeb. This will be handled in a future patch.

In the future, we may want to introduce a memory cache for cookies in
RequestServer to avoid IPC altogether as able.
This commit is contained in:
Timothy Flynn
2026-02-07 14:06:22 -05:00
committed by Andreas Kling
parent a4ba51fff5
commit e6c008a269
Notes: github-actions[bot] 2026-02-10 11:22:24 +00:00
15 changed files with 124 additions and 39 deletions

View File

@@ -13,4 +13,4 @@ set(GENERATED_SOURCES
)
ladybird_lib(LibRequests requests)
target_link_libraries(LibRequests PRIVATE LibCore LibHTTP LibIPC)
target_link_libraries(LibRequests PRIVATE LibCore LibHTTP LibIPC LibURL)

View File

@@ -32,12 +32,12 @@ void RequestClient::die()
m_pending_cache_size_estimations.clear();
}
RefPtr<Request> RequestClient::start_request(ByteString const& method, URL::URL const& url, Optional<HTTP::HeaderList const&> request_headers, ReadonlyBytes request_body, HTTP::CacheMode cache_mode, Core::ProxyData const& proxy_data)
RefPtr<Request> RequestClient::start_request(ByteString const& method, URL::URL const& url, Optional<HTTP::HeaderList const&> request_headers, ReadonlyBytes request_body, HTTP::CacheMode cache_mode, HTTP::Cookie::IncludeCredentials include_credentials, Core::ProxyData const& proxy_data)
{
auto request_id = m_next_request_id++;
auto headers = request_headers.map([](auto const& headers) { return headers.headers().span(); }).value_or({});
IPCProxy::async_start_request(request_id, method, url, headers, request_body, cache_mode, proxy_data);
IPCProxy::async_start_request(request_id, method, url, headers, request_body, cache_mode, include_credentials, proxy_data);
auto request = Request::create_from_id({}, *this, request_id);
m_requests.set(request_id, request);
return request;
@@ -109,6 +109,16 @@ void RequestClient::headers_became_available(u64 request_id, Vector<HTTP::Header
warnln("Received headers for non-existent request {}", request_id);
}
void RequestClient::retrieve_http_cookie(int client_id, u64 request_id, URL::URL url)
{
String cookie;
if (on_retrieve_http_cookie)
cookie = on_retrieve_http_cookie(url);
async_retrieved_http_cookie(client_id, request_id, cookie);
}
void RequestClient::certificate_requested(u64 request_id)
{
if (auto request = m_requests.get(request_id); request.has_value())

View File

@@ -8,6 +8,7 @@
#include <AK/HashMap.h>
#include <LibHTTP/Cache/CacheMode.h>
#include <LibHTTP/Cookie/IncludeCredentials.h>
#include <LibHTTP/HeaderList.h>
#include <LibIPC/ConnectionToServer.h>
#include <LibRequests/CacheSizes.h>
@@ -32,7 +33,7 @@ public:
explicit RequestClient(NonnullOwnPtr<IPC::Transport>);
virtual ~RequestClient() override;
RefPtr<Request> start_request(ByteString const& method, URL::URL const&, Optional<HTTP::HeaderList const&> request_headers = {}, ReadonlyBytes request_body = {}, HTTP::CacheMode = HTTP::CacheMode::Default, Core::ProxyData const& = {});
RefPtr<Request> start_request(ByteString const& method, URL::URL const&, Optional<HTTP::HeaderList const&> request_headers = {}, ReadonlyBytes request_body = {}, HTTP::CacheMode = HTTP::CacheMode::Default, HTTP::Cookie::IncludeCredentials = HTTP::Cookie::IncludeCredentials::Yes, Core::ProxyData const& = {});
bool stop_request(Badge<Request>, Request&);
void ensure_connection(URL::URL const&, RequestServer::CacheLevel);
@@ -42,6 +43,7 @@ public:
NonnullRefPtr<Core::Promise<CacheSizes>> estimate_cache_size_accessed_since(UnixDateTime since);
Function<String(URL::URL const&)> on_retrieve_http_cookie;
Function<void()> on_request_server_died;
private:
@@ -51,6 +53,8 @@ private:
virtual void request_finished(u64 request_id, u64, RequestTimingInfo, Optional<NetworkError>) override;
virtual void headers_became_available(u64 request_id, Vector<HTTP::Header>, Optional<u32>, Optional<String>) override;
virtual void retrieve_http_cookie(int client_id, u64 request_id, URL::URL url) override;
virtual void certificate_requested(u64 request_id) override;
virtual void websocket_connected(u64 websocket_id) override;

View File

@@ -14,7 +14,6 @@
#include <AK/ScopeGuard.h>
#include <LibHTTP/Cache/MemoryCache.h>
#include <LibHTTP/Cache/Utilities.h>
#include <LibHTTP/Cookie/Cookie.h>
#include <LibHTTP/Method.h>
#include <LibJS/Runtime/Completion.h>
#include <LibRequests/Request.h>
@@ -1724,20 +1723,10 @@ GC::Ref<PendingResponse> http_network_or_cache_fetch(JS::Realm& realm, Infrastru
if (include_credentials == HTTP::Cookie::IncludeCredentials::Yes) {
// 1. If the user agent is not configured to block cookies for httpRequest (see section 7 of [COOKIES]),
// then:
if (true) {
// 1. Let cookies be the result of running the "cookie-string" algorithm (see section 5.4 of [COOKIES])
// with the user agents cookie store and httpRequests current URL.
auto cookies = ([&] {
auto& page = Bindings::principal_host_defined_page(HTML::principal_realm(realm));
return page.client().page_did_request_cookie(http_request->current_url(), HTTP::Cookie::Source::Http).cookie;
})();
// 2. If cookies is not the empty string, then append (`Cookie`, cookies) to httpRequests header list.
if (!cookies.is_empty()) {
auto header = HTTP::Header::isomorphic_encode("Cookie"sv, cookies);
http_request->header_list()->append(move(header));
}
}
// 1. Let cookies be the result of running the "cookie-string" algorithm (see section 5.4 of [COOKIES])
// with the user agents cookie store and httpRequests current URL.
// 2. If cookies is not the empty string, then append (`Cookie`, cookies) to httpRequests header list.
// NB: HTTP cookies are attached by RequestServer.
// 2. If httpRequests header list does not contain `Authorization`, then:
if (!http_request->header_list()->contains("Authorization"sv)) {
@@ -2053,7 +2042,7 @@ GC::Ref<PendingResponse> nonstandard_resource_loader_file_or_http_network_fetch(
load_request.set_page(page);
load_request.set_method(request->method());
load_request.set_cache_mode(request->cache_mode());
load_request.set_store_set_cookie_headers(include_credentials == HTTP::Cookie::IncludeCredentials::Yes);
load_request.set_include_credentials(include_credentials);
load_request.set_initiator_type(request->initiator_type());
if (auto const* body = request->body().get_pointer<GC::Ref<Infrastructure::Body>>()) {

View File

@@ -10,6 +10,7 @@
#include <AK/Time.h>
#include <LibCore/ElapsedTimer.h>
#include <LibHTTP/Cache/CacheMode.h>
#include <LibHTTP/Cookie/IncludeCredentials.h>
#include <LibHTTP/HeaderList.h>
#include <LibURL/URL.h>
#include <LibWeb/Export.h>
@@ -38,8 +39,8 @@ public:
HTTP::CacheMode cache_mode() const { return m_cache_mode; }
void set_cache_mode(HTTP::CacheMode cache_mode) { m_cache_mode = cache_mode; }
bool store_set_cookie_headers() const { return m_store_set_cookie_headers; }
void set_store_set_cookie_headers(bool store_set_cookie_headers) { m_store_set_cookie_headers = store_set_cookie_headers; }
HTTP::Cookie::IncludeCredentials include_credentials() const { return m_include_credentials; }
void set_include_credentials(HTTP::Cookie::IncludeCredentials include_credentials) { m_include_credentials = include_credentials; }
Optional<Fetch::Infrastructure::Request::InitiatorType> const& initiator_type() const { return m_initiator_type; }
void set_initiator_type(Optional<Fetch::Infrastructure::Request::InitiatorType> initiator_type) { m_initiator_type = move(initiator_type); }
@@ -60,7 +61,7 @@ private:
Core::ElapsedTimer m_load_timer;
GC::Root<Page> m_page;
HTTP::CacheMode m_cache_mode { HTTP::CacheMode::Default };
bool m_store_set_cookie_headers { true };
HTTP::Cookie::IncludeCredentials m_include_credentials { HTTP::Cookie::IncludeCredentials::Yes };
Optional<Fetch::Infrastructure::Request::InitiatorType> m_initiator_type;
};

View File

@@ -471,7 +471,7 @@ RefPtr<Requests::Request> ResourceLoader::start_network_request(LoadRequest cons
return nullptr;
}
auto protocol_request = m_request_client->start_request(request.method(), request.url().value(), request.headers(), request.body(), request.cache_mode(), proxy);
auto protocol_request = m_request_client->start_request(request.method(), request.url().value(), request.headers(), request.body(), request.cache_mode(), request.include_credentials(), proxy);
if (!protocol_request) {
log_failure(request, "Failed to initiate load"sv);
return nullptr;
@@ -501,7 +501,7 @@ void ResourceLoader::handle_network_response_headers(LoadRequest const& request,
if (!request.page())
return;
if (request.store_set_cookie_headers()) {
if (request.include_credentials() == HTTP::Cookie::IncludeCredentials::Yes) {
// From https://fetch.spec.whatwg.org/#concept-http-network-fetch:
// 15. If includeCredentials is true, then the user agent should parse and store response
// `Set-Cookie` headers given request and response.

View File

@@ -410,6 +410,10 @@ ErrorOr<void> Application::launch_request_server()
{
m_request_server_client = TRY(launch_request_server_process());
m_request_server_client->on_retrieve_http_cookie = [this](URL::URL const& url) {
return m_cookie_jar->get_cookie(url, HTTP::Cookie::Source::Http);
};
m_request_server_client->on_request_server_died = [this]() {
m_request_server_client = nullptr;

View File

@@ -8,10 +8,8 @@
#include <LibHTTP/HeaderList.h>
#include <LibRequests/Request.h>
#include <LibRequests/RequestClient.h>
#include <LibTextCodec/Encoder.h>
#include <LibWeb/Loader/UserAgent.h>
#include <LibWebView/Application.h>
#include <LibWebView/CookieJar.h>
#include <LibWebView/FileDownloader.h>
namespace WebView {
@@ -33,7 +31,6 @@ void FileDownloader::download_file(URL::URL const& url, LexicalPath destination)
// FIXME: What other request headers should be set? Perhaps we want to use exactly the same request headers used to
// originally fetch the image in WebContent.
auto request_headers = HTTP::HeaderList::create();
request_headers->set({ "Cookie"sv, TextCodec::isomorphic_encode(Application::cookie_jar().get_cookie(url, HTTP::Cookie::Source::Http)) });
request_headers->set({ "User-Agent"sv, Web::default_user_agent });
auto request = Application::request_server_client().start_request("GET"sv, url, *request_headers);

View File

@@ -24,6 +24,7 @@
namespace RequestServer {
static HashMap<int, NonnullRefPtr<ConnectionFromClient>>* g_connections;
static ConnectionFromClient* g_primary_connection = nullptr;
static IDAllocator s_client_ids;
Optional<HTTP::DiskCache> g_disk_cache;
@@ -68,6 +69,19 @@ ConnectionFromClient::~ConnectionFromClient()
m_curl_multi = nullptr;
}
Optional<ConnectionFromClient&> ConnectionFromClient::primary_connection()
{
if (g_primary_connection)
return *g_primary_connection;
return {};
}
void ConnectionFromClient::mark_as_primary_connection()
{
VERIFY(g_primary_connection == nullptr);
g_primary_connection = this;
}
void ConnectionFromClient::request_complete(Badge<Request>, Request const& request)
{
Core::deferred_invoke([weak_self = make_weak_ptr<ConnectionFromClient>(), request_id = request.request_id(), type = request.type()] {
@@ -82,6 +96,9 @@ void ConnectionFromClient::request_complete(Badge<Request>, Request const& reque
void ConnectionFromClient::die()
{
if (g_primary_connection == this)
g_primary_connection = nullptr;
auto client_id = this->client_id();
g_connections->remove(client_id);
s_client_ids.deallocate(client_id);
@@ -192,21 +209,21 @@ void ConnectionFromClient::set_use_system_dns()
m_resolver->dns.reset_connection();
}
void ConnectionFromClient::start_request(u64 request_id, ByteString method, URL::URL url, Vector<HTTP::Header> request_headers, ByteBuffer request_body, HTTP::CacheMode cache_mode, Core::ProxyData proxy_data)
void ConnectionFromClient::start_request(u64 request_id, ByteString method, URL::URL url, Vector<HTTP::Header> request_headers, ByteBuffer request_body, HTTP::CacheMode cache_mode, HTTP::Cookie::IncludeCredentials include_credentials, Core::ProxyData proxy_data)
{
dbgln_if(REQUESTSERVER_DEBUG, "RequestServer: start_request({}, {})", request_id, url);
auto request = Request::fetch(request_id, g_disk_cache, cache_mode, *this, m_curl_multi, m_resolver, move(url), move(method), HTTP::HeaderList::create(move(request_headers)), move(request_body), m_alt_svc_cache_path, proxy_data);
auto request = Request::fetch(request_id, g_disk_cache, cache_mode, *this, m_curl_multi, m_resolver, move(url), move(method), HTTP::HeaderList::create(move(request_headers)), move(request_body), include_credentials, m_alt_svc_cache_path, proxy_data);
m_active_requests.set(request_id, move(request));
}
void ConnectionFromClient::start_revalidation_request(Badge<Request>, ByteString method, URL::URL url, NonnullRefPtr<HTTP::HeaderList> request_headers, ByteBuffer request_body, Core::ProxyData proxy_data)
void ConnectionFromClient::start_revalidation_request(Badge<Request>, ByteString method, URL::URL url, NonnullRefPtr<HTTP::HeaderList> request_headers, ByteBuffer request_body, HTTP::Cookie::IncludeCredentials include_credentials, Core::ProxyData proxy_data)
{
auto request_id = m_next_revalidation_request_id++;
dbgln_if(REQUESTSERVER_DEBUG, "RequestServer: start_revalidation_request({}, {})", request_id, url);
auto request = Request::revalidate(request_id, g_disk_cache, *this, m_curl_multi, m_resolver, move(url), move(method), move(request_headers), move(request_body), m_alt_svc_cache_path, proxy_data);
auto request = Request::revalidate(request_id, g_disk_cache, *this, m_curl_multi, m_resolver, move(url), move(method), move(request_headers), move(request_body), include_credentials, m_alt_svc_cache_path, proxy_data);
m_active_revalidation_requests.set(request_id, move(request));
}
@@ -321,6 +338,14 @@ void ConnectionFromClient::ensure_connection(u64 request_id, URL::URL url, ::Req
m_active_requests.set(request_id, move(request));
}
void ConnectionFromClient::retrieved_http_cookie(int client_id, u64 request_id, String cookie)
{
if (auto connection = g_connections->get(client_id); connection.has_value()) {
if (auto request = (*connection)->m_active_requests.get(request_id); request.has_value())
(*request)->notify_retrieved_http_cookie({}, cookie);
}
}
void ConnectionFromClient::estimate_cache_size_accessed_since(u64 cache_size_estimation_id, UnixDateTime since)
{
Requests::CacheSizes sizes;

View File

@@ -28,7 +28,10 @@ public:
static void set_connections(HashMap<int, NonnullRefPtr<ConnectionFromClient>>&);
void start_revalidation_request(Badge<Request>, ByteString method, URL::URL, NonnullRefPtr<HTTP::HeaderList> request_headers, ByteBuffer request_body, Core::ProxyData proxy_data);
static Optional<ConnectionFromClient&> primary_connection();
void mark_as_primary_connection();
void start_revalidation_request(Badge<Request>, ByteString method, URL::URL, NonnullRefPtr<HTTP::HeaderList> request_headers, ByteBuffer request_body, HTTP::Cookie::IncludeCredentials, Core::ProxyData proxy_data);
void request_complete(Badge<Request>, Request const&);
private:
@@ -41,11 +44,13 @@ private:
virtual Messages::RequestServer::IsSupportedProtocolResponse is_supported_protocol(ByteString) override;
virtual void set_dns_server(ByteString host_or_address, u16 port, bool use_tls, bool validate_dnssec_locally) override;
virtual void set_use_system_dns() override;
virtual void start_request(u64 request_id, ByteString, URL::URL, Vector<HTTP::Header>, ByteBuffer, HTTP::CacheMode, Core::ProxyData) override;
virtual void start_request(u64 request_id, ByteString, URL::URL, Vector<HTTP::Header>, ByteBuffer, HTTP::CacheMode, HTTP::Cookie::IncludeCredentials, Core::ProxyData) override;
virtual Messages::RequestServer::StopRequestResponse stop_request(u64 request_id) override;
virtual Messages::RequestServer::SetCertificateResponse set_certificate(u64 request_id, ByteString, ByteString) override;
virtual void ensure_connection(u64 request_id, URL::URL url, ::RequestServer::CacheLevel cache_level) override;
virtual void retrieved_http_cookie(int client_id, u64 request_id, String cookie) override;
virtual void estimate_cache_size_accessed_since(u64 cache_size_estimation_id, UnixDateTime since) override;
virtual void remove_cache_entries_accessed_since(UnixDateTime since) override;

View File

@@ -36,10 +36,11 @@ NonnullOwnPtr<Request> Request::fetch(
ByteString method,
NonnullRefPtr<HTTP::HeaderList> request_headers,
ByteBuffer request_body,
HTTP::Cookie::IncludeCredentials include_credentials,
ByteString alt_svc_cache_path,
Core::ProxyData proxy_data)
{
auto request = adopt_own(*new Request { request_id, Type::Fetch, disk_cache, cache_mode, client, curl_multi, resolver, move(url), move(method), move(request_headers), move(request_body), move(alt_svc_cache_path), proxy_data });
auto request = adopt_own(*new Request { request_id, Type::Fetch, disk_cache, cache_mode, client, curl_multi, resolver, move(url), move(method), move(request_headers), move(request_body), include_credentials, move(alt_svc_cache_path), proxy_data });
request->process();
return request;
@@ -77,10 +78,11 @@ NonnullOwnPtr<Request> Request::revalidate(
ByteString method,
NonnullRefPtr<HTTP::HeaderList> request_headers,
ByteBuffer request_body,
HTTP::Cookie::IncludeCredentials include_credentials,
ByteString alt_svc_cache_path,
Core::ProxyData proxy_data)
{
auto request = adopt_own(*new Request { request_id, Type::BackgroundRevalidation, disk_cache, HTTP::CacheMode::Default, client, curl_multi, resolver, move(url), move(method), move(request_headers), move(request_body), move(alt_svc_cache_path), proxy_data });
auto request = adopt_own(*new Request { request_id, Type::BackgroundRevalidation, disk_cache, HTTP::CacheMode::Default, client, curl_multi, resolver, move(url), move(method), move(request_headers), move(request_body), include_credentials, move(alt_svc_cache_path), proxy_data });
request->process();
return request;
@@ -98,6 +100,7 @@ Request::Request(
ByteString method,
NonnullRefPtr<HTTP::HeaderList> request_headers,
ByteBuffer request_body,
HTTP::Cookie::IncludeCredentials include_credentials,
ByteString alt_svc_cache_path,
Core::ProxyData proxy_data)
: m_request_id(request_id)
@@ -111,6 +114,7 @@ Request::Request(
, m_method(move(method))
, m_request_headers(move(request_headers))
, m_request_body(move(request_body))
, m_include_credentials(include_credentials)
, m_alt_svc_cache_path(move(alt_svc_cache_path))
, m_proxy_data(proxy_data)
, m_response_headers(HTTP::HeaderList::create())
@@ -164,6 +168,16 @@ void Request::notify_request_unblocked(Badge<HTTP::DiskCache>)
transition_to_state(State::Init);
}
void Request::notify_retrieved_http_cookie(Badge<ConnectionFromClient>, StringView cookie)
{
if (!cookie.is_empty()) {
auto header = HTTP::Header::isomorphic_encode("Cookie"sv, cookie);
m_request_headers->append(move(header));
}
transition_to_state(State::Fetch);
}
void Request::notify_fetch_complete(Badge<ConnectionFromClient>, int result_code)
{
if (is_revalidation_request()) {
@@ -216,6 +230,9 @@ void Request::process()
case State::DNSLookup:
handle_dns_lookup_state();
break;
case State::RetrieveCookie:
handle_retrieve_cookie_state();
break;
case State::Connect:
handle_connect_state();
break;
@@ -255,7 +272,7 @@ void Request::handle_initial_state()
if (m_cache_entry_reader.has_value()) {
if (m_cache_entry_reader->revalidation_type() == HTTP::CacheEntryReader::RevalidationType::StaleWhileRevalidate)
m_client.start_revalidation_request({}, m_method, m_url, m_request_headers, m_request_body, m_proxy_data);
m_client.start_revalidation_request({}, m_method, m_url, m_request_headers, m_request_body, m_include_credentials, m_proxy_data);
if (is_revalidation_request())
transition_to_state(State::DNSLookup);
@@ -430,13 +447,28 @@ void Request::handle_dns_lookup_state()
transition_to_state(State::Error);
} else if (m_type == Type::Fetch || m_type == Type::BackgroundRevalidation) {
m_dns_result = move(dns_result);
transition_to_state(State::Fetch);
transition_to_state(State::RetrieveCookie);
} else {
transition_to_state(State::Complete);
}
});
}
void Request::handle_retrieve_cookie_state()
{
if (m_include_credentials == HTTP::Cookie::IncludeCredentials::No) {
transition_to_state(State::Fetch);
return;
}
if (auto connection = ConnectionFromClient::primary_connection(); connection.has_value()) {
connection->async_retrieve_http_cookie(m_client.client_id(), m_request_id, m_url);
} else {
m_network_error = Requests::NetworkError::RequestServerDied;
transition_to_state(State::Error);
}
}
void Request::handle_connect_state()
{
m_curl_easy_handle = curl_easy_init();

View File

@@ -15,6 +15,7 @@
#include <LibDNS/Resolver.h>
#include <LibHTTP/Cache/CacheMode.h>
#include <LibHTTP/Cache/CacheRequest.h>
#include <LibHTTP/Cookie/IncludeCredentials.h>
#include <LibHTTP/HeaderList.h>
#include <LibRequests/NetworkError.h>
#include <LibRequests/RequestTimingInfo.h>
@@ -40,6 +41,7 @@ public:
ByteString method,
NonnullRefPtr<HTTP::HeaderList> request_headers,
ByteBuffer request_body,
HTTP::Cookie::IncludeCredentials include_credentials,
ByteString alt_svc_cache_path,
Core::ProxyData proxy_data);
@@ -61,6 +63,7 @@ public:
ByteString method,
NonnullRefPtr<HTTP::HeaderList> request_headers,
ByteBuffer request_body,
HTTP::Cookie::IncludeCredentials include_credentials,
ByteString alt_svc_cache_path,
Core::ProxyData proxy_data);
@@ -74,8 +77,10 @@ public:
u64 request_id() const { return m_request_id; }
Type type() const { return m_type; }
URL::URL const& url() const { return m_url; }
virtual void notify_request_unblocked(Badge<HTTP::DiskCache>) override;
void notify_retrieved_http_cookie(Badge<ConnectionFromClient>, StringView cookie);
void notify_fetch_complete(Badge<ConnectionFromClient>, int result_code);
private:
@@ -86,6 +91,7 @@ private:
FailedCacheOnly, // An only-if-cached request failed to find a cache entry.
ServeSubstitution, // Serve content from a local file substitution.
DNSLookup, // Resolve the URL's host.
RetrieveCookie, // Retrieve cookies from the UI process.
Connect, // Issue a network request to connect to the URL.
Fetch, // Issue a network request to fetch the URL.
Complete, // Finalize the request with the client.
@@ -107,6 +113,8 @@ private:
return "ServeSubstitution"sv;
case State::DNSLookup:
return "DNSLookup"sv;
case State::RetrieveCookie:
return "RetrieveCookie"sv;
case State::Connect:
return "Connect"sv;
case State::Fetch:
@@ -131,6 +139,7 @@ private:
ByteString method,
NonnullRefPtr<HTTP::HeaderList> request_headers,
ByteBuffer request_body,
HTTP::Cookie::IncludeCredentials include_credentials,
ByteString alt_svc_cache_path,
Core::ProxyData proxy_data);
@@ -149,6 +158,7 @@ private:
void handle_failed_cache_only_state();
void handle_serve_substitution_state();
void handle_dns_lookup_state();
void handle_retrieve_cookie_state();
void handle_connect_state();
void handle_fetch_state();
void handle_complete_state();
@@ -192,6 +202,8 @@ private:
NonnullRefPtr<HTTP::HeaderList> m_request_headers;
ByteBuffer m_request_body;
HTTP::Cookie::IncludeCredentials m_include_credentials { HTTP::Cookie::IncludeCredentials::Yes };
ByteString m_alt_svc_cache_path;
Core::ProxyData m_proxy_data;

View File

@@ -10,6 +10,8 @@ endpoint RequestClient
request_finished(u64 request_id, u64 total_size, Requests::RequestTimingInfo timing_info, Optional<Requests::NetworkError> network_error) =|
headers_became_available(u64 request_id, Vector<HTTP::Header> response_headers, Optional<u32> status_code, Optional<String> reason_phrase) =|
retrieve_http_cookie(int client_id, u64 request_id, URL::URL url) =|
// Websocket API
// FIXME: See if this can be merged with the regular APIs
websocket_connected(u64 websocket_id) =|

View File

@@ -1,5 +1,6 @@
#include <LibCore/Proxy.h>
#include <LibHTTP/Cache/CacheMode.h>
#include <LibHTTP/Cookie/IncludeCredentials.h>
#include <LibHTTP/Header.h>
#include <LibURL/URL.h>
#include <RequestServer/CacheLevel.h>
@@ -17,12 +18,14 @@ endpoint RequestServer
// Test if a specific protocol is supported, e.g "http"
is_supported_protocol(ByteString protocol) => (bool supported)
start_request(u64 request_id, ByteString method, URL::URL url, Vector<HTTP::Header> request_headers, ByteBuffer request_body, HTTP::CacheMode cache_mode, Core::ProxyData proxy_data) =|
start_request(u64 request_id, ByteString method, URL::URL url, Vector<HTTP::Header> request_headers, ByteBuffer request_body, HTTP::CacheMode cache_mode, HTTP::Cookie::IncludeCredentials include_credentials, Core::ProxyData proxy_data) =|
stop_request(u64 request_id) => (bool success)
set_certificate(u64 request_id, ByteString certificate, ByteString key) => (bool success)
ensure_connection(u64 request_id, URL::URL url, ::RequestServer::CacheLevel cache_level) =|
retrieved_http_cookie(int client_id, u64 request_id, String cookie) =|
estimate_cache_size_accessed_since(u64 cache_size_estimation_id, UnixDateTime since) =|
remove_cache_entries_accessed_since(UnixDateTime since) =|

View File

@@ -112,6 +112,7 @@ ErrorOr<int> ladybird_main(Main::Arguments arguments)
RequestServer::ConnectionFromClient::set_connections(connections);
auto client = TRY(IPC::take_over_accepted_client_from_system_server<RequestServer::ConnectionFromClient>());
client->mark_as_primary_connection();
return event_loop.exec();
}