Skip to content

Commit

Permalink
LibWeb/Fetch: Return a cloned cached response body
Browse files Browse the repository at this point in the history
Otherwise we will fully read from the cached response and invalidate
it's stream, invalidating it for the next time it is read from. Fixes
a crash when reloading linegoup.lol after two reloads.
  • Loading branch information
shannonbooth authored and awesomekling committed Dec 26, 2024
1 parent 7cd6ea6 commit 3913e9f
Showing 1 changed file with 3 additions and 3 deletions.
6 changes: 3 additions & 3 deletions Libraries/LibWeb/Fetch/Fetching/Fetching.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1351,7 +1351,7 @@ WebIDL::ExceptionOr<GC::Ptr<PendingResponse>> http_redirect_fetch(JS::Realm& rea
class CachePartition : public RefCounted<CachePartition> {
public:
// https://httpwg.org/specs/rfc9111.html#constructing.responses.from.caches
GC::Ptr<Infrastructure::Response> select_response(URL::URL const& url, ReadonlyBytes method, Vector<Infrastructure::Header> const& headers, Vector<GC::Ptr<Infrastructure::Response>>& initial_set_of_stored_responses) const
GC::Ptr<Infrastructure::Response> select_response(JS::Realm& realm, URL::URL const& url, ReadonlyBytes method, Vector<Infrastructure::Header> const& headers, Vector<GC::Ptr<Infrastructure::Response>>& initial_set_of_stored_responses) const
{
// When presented with a request, a cache MUST NOT reuse a stored response unless:

Expand Down Expand Up @@ -1383,7 +1383,7 @@ class CachePartition : public RefCounted<CachePartition> {

dbgln("\033[32;1mHTTP CACHE HIT!\033[0m {}", url);

return cached_response.ptr();
return cached_response->clone(realm);
}

void store_response(JS::Realm& realm, Infrastructure::Request const& http_request, Infrastructure::Response const& response)
Expand Down Expand Up @@ -1939,7 +1939,7 @@ WebIDL::ExceptionOr<GC::Ref<PendingResponse>> http_network_or_cache_fetch(JS::Re
// validation, as per the "Constructing Responses from Caches" chapter of HTTP Caching [HTTP-CACHING],
// if any.
// NOTE: As mandated by HTTP, this still takes the `Vary` header into account.
stored_response = http_cache->select_response(http_request->current_url(), http_request->method(), *http_request->header_list(), initial_set_of_stored_responses);
stored_response = http_cache->select_response(realm, http_request->current_url(), http_request->method(), *http_request->header_list(), initial_set_of_stored_responses);
// 2. If storedResponse is non-null, then:
if (stored_response) {
// 1. If cache mode is "default", storedResponse is a stale-while-revalidate response,
Expand Down

0 comments on commit 3913e9f

Please sign in to comment.