LibHTTP+RequestServer: Add support for synthetic disk-cache entries

This exposes the operation through RequestServer.ipc and RequestClient
so the client can create the stub before accessing a content-keyed
side-data file.
This commit is contained in:
Ali Mohammad Pur 2026-05-11 15:57:16 +02:00 committed by Ali Mohammad Pur
parent 248b7e4515
commit ab6eac02ff
7 changed files with 43 additions and 0 deletions

View file

@ -223,6 +223,25 @@ Variant<Optional<CacheEntryReader&>, DiskCache::CacheHasOpenEntry> DiskCache::op
return Optional<CacheEntryReader&> { *cache_entry_pointer };
}
ErrorOr<bool> DiskCache::create_synthetic_entry(URL::URL const& url, StringView method)
{
auto request_headers = HeaderList::create();
if (!is_cacheable(method, *request_headers))
return false;
auto serialized_url = serialize_url_for_cache_storage(url);
auto cache_key = create_cache_key(serialized_url, method, m_partitioned_cache_key);
constexpr u64 synthetic_vary_key = 0;
if (m_index.has_entry(cache_key, synthetic_vary_key))
return true;
auto response_headers = HeaderList::create();
auto now = UnixDateTime::now();
TRY(m_index.create_entry(cache_key, synthetic_vary_key, serialized_url, request_headers, response_headers, 0, now, now));
return true;
}
ErrorOr<bool> DiskCache::store_associated_data(URL::URL const& url, StringView method, HeaderList const& request_headers, Optional<u64> vary_key, CacheEntryAssociatedData associated_data, ReadonlyBytes data)
{
if (!is_cacheable(method, request_headers))

View file

@ -58,6 +58,9 @@ public:
ErrorOr<Optional<ByteBuffer>> retrieve_associated_data(URL::URL const&, StringView method, HeaderList const& request_headers, Optional<u64> vary_key, CacheEntryAssociatedData);
ErrorOr<Optional<CacheEntryBodyFile>> retrieve_associated_data_file(URL::URL const&, StringView method, HeaderList const& request_headers, Optional<u64> vary_key, CacheEntryAssociatedData);
// Ensure an index row exists for url+method so the shelf has something to attach to even if there are no real HTTP requests in flight.
ErrorOr<bool> create_synthetic_entry(URL::URL const&, StringView method);
void remove_entries_exceeding_cache_limit();
void set_maximum_disk_cache_size(u64 maximum_disk_cache_size);

View file

@ -102,6 +102,11 @@ ErrorOr<Optional<Core::AnonymousBuffer>> RequestClient::retrieve_cache_associate
return IPCProxy::retrieve_cache_associated_data(url, method, headers, vary_key, associated_data);
}
ErrorOr<bool> RequestClient::create_synthetic_cache_entry(URL::URL const& url, ByteString const& method)
{
return IPCProxy::create_synthetic_cache_entry(url, method);
}
bool RequestClient::stop_request(Badge<Request>, Request& request)
{
if (!m_requests.contains(request.id()))

View file

@ -46,6 +46,7 @@ public:
NonnullRefPtr<Core::Promise<CacheSizes>> estimate_cache_size_accessed_since(UnixDateTime since);
ErrorOr<bool> store_cache_associated_data(URL::URL const&, ByteString const& method, Optional<HTTP::HeaderList const&> request_headers, Optional<u64> vary_key, HTTP::CacheEntryAssociatedData, ReadonlyBytes);
ErrorOr<Optional<Core::AnonymousBuffer>> retrieve_cache_associated_data(URL::URL const&, ByteString const& method, Optional<HTTP::HeaderList const&> request_headers, Optional<u64> vary_key, HTTP::CacheEntryAssociatedData);
ErrorOr<bool> create_synthetic_cache_entry(URL::URL const&, ByteString const& method);
Function<String(URL::URL const&)> on_retrieve_http_cookie;
Function<void()> on_request_server_died;

View file

@ -491,6 +491,19 @@ Messages::RequestServer::RetrieveCacheAssociatedDataResponse ConnectionFromClien
return Optional<Core::AnonymousBuffer> { buffer.release_value() };
}
Messages::RequestServer::CreateSyntheticCacheEntryResponse ConnectionFromClient::create_synthetic_cache_entry(URL::URL url, ByteString method)
{
if (!m_disk_cache.has_value())
return false;
auto result = m_disk_cache->create_synthetic_entry(url, method);
if (result.is_error()) {
dbgln("Failed to create synthetic cache entry for {}: {}", url, result.error());
return false;
}
return result.value();
}
void ConnectionFromClient::websocket_connect(u64 websocket_id, URL::URL url, ByteString origin, Vector<ByteString> protocols, Vector<ByteString> extensions, Vector<HTTP::Header> additional_request_headers)
{
auto host = url.serialized_host().to_byte_string();

View file

@ -68,6 +68,7 @@ private:
virtual void remove_cache_entries_accessed_since(UnixDateTime since) override;
virtual Messages::RequestServer::StoreCacheAssociatedDataResponse store_cache_associated_data(URL::URL, ByteString method, Vector<HTTP::Header> request_headers, Optional<u64> vary_key, HTTP::CacheEntryAssociatedData, Core::AnonymousBuffer) override;
virtual Messages::RequestServer::RetrieveCacheAssociatedDataResponse retrieve_cache_associated_data(URL::URL, ByteString method, Vector<HTTP::Header> request_headers, Optional<u64> vary_key, HTTP::CacheEntryAssociatedData) override;
virtual Messages::RequestServer::CreateSyntheticCacheEntryResponse create_synthetic_cache_entry(URL::URL, ByteString method) override;
virtual void websocket_connect(u64 websocket_id, URL::URL, ByteString, Vector<ByteString>, Vector<ByteString>, Vector<HTTP::Header>) override;
virtual void websocket_send(u64 websocket_id, bool, ByteBuffer) override;

View file

@ -37,6 +37,7 @@ endpoint RequestServer
remove_cache_entries_accessed_since(UnixDateTime since) =|
store_cache_associated_data(URL::URL url, ByteString method, Vector<HTTP::Header> request_headers, Optional<u64> vary_key, HTTP::CacheEntryAssociatedData associated_data, Core::AnonymousBuffer data) => (bool stored)
retrieve_cache_associated_data(URL::URL url, ByteString method, Vector<HTTP::Header> request_headers, Optional<u64> vary_key, HTTP::CacheEntryAssociatedData associated_data) => (Optional<Core::AnonymousBuffer> data)
create_synthetic_cache_entry(URL::URL url, ByteString method) => (bool created)
// Websocket Connection API
websocket_connect(u64 websocket_id, URL::URL url, ByteString origin, Vector<ByteString> protocols, Vector<ByteString> extensions, Vector<HTTP::Header> additional_request_headers) =|