LibWeb/Fetch: Implement logic to process a response from HTTP's cache

Co-Authored-By: Andrew Kaster <akaster@serenityos.org>
This commit is contained in:
Lucas CHOLLET 2024-05-21 20:16:45 -04:00 committed by Tim Flynn
parent fcbc6123bb
commit b30c361b08
Notes: sideshowbarker 2024-07-16 22:26:05 +09:00

View file

@ -1662,8 +1662,62 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<PendingResponse>> http_network_or_cache_fet
stored_response = Infrastructure::Response::create(vm);
stored_response->set_body(body);
// FIXME: Caching is not implemented yet.
VERIFY_NOT_REACHED();
// 1. If cache mode is "default", storedResponse is a stale-while-revalidate response,
// and httpRequests client is non-null, then:
if (http_request->cache_mode() == Infrastructure::Request::CacheMode::Default
&& stored_response->is_stale_while_revalidate()
&& http_request->client() != nullptr) {
// 1. Set response to storedResponse.
response = stored_response;
// 2. Set responses cache state to "local".
response->set_cache_state(Infrastructure::Response::CacheState::Local);
// 3. Let revalidateRequest be a clone of request.
auto revalidate_request = request->clone(realm);
// 4. Set revalidateRequests cache mode set to "no-cache".
revalidate_request->set_cache_mode(Infrastructure::Request::CacheMode::NoCache);
// 5. Set revalidateRequests prevent no-cache cache-control header modification flag.
revalidate_request->set_prevent_no_cache_cache_control_header_modification(true);
// 6. Set revalidateRequests service-workers mode set to "none".
revalidate_request->set_service_workers_mode(Infrastructure::Request::ServiceWorkersMode::None);
// 7. In parallel, run main fetch given a new fetch params whose request is revalidateRequest.
Platform::EventLoopPlugin::the().deferred_invoke([&vm, &realm, revalidate_request, fetch_params = JS::NonnullGCPtr(fetch_params)] {
(void)main_fetch(realm, Infrastructure::FetchParams::create(vm, revalidate_request, fetch_params->timing_info()));
});
}
// 2. Otherwise:
else {
// 1. If storedResponse is a stale response, then set the revalidatingFlag.
if (stored_response->is_stale())
revalidating_flag->set_value(true);
// 2. If the revalidatingFlag is set and httpRequests cache mode is neither "force-cache" nor "only-if-cached", then:
if (revalidating_flag->value()
&& http_request->cache_mode() != Infrastructure::Request::CacheMode::ForceCache
&& http_request->cache_mode() != Infrastructure::Request::CacheMode::OnlyIfCached) {
// 1. If storedResponses header list contains `ETag`, then append (`If-None-Match`, `ETag`'s value) to httpRequests header list.
if (auto etag = stored_response->header_list()->get("ETag"sv.bytes()); etag.has_value()) {
stored_response->header_list()->append(Infrastructure::Header::from_string_pair("If-None-Match"sv, *etag));
}
// 2. If storedResponses header list contains `Last-Modified`, then append (`If-Modified-Since`, `Last-Modified`'s value) to httpRequests header list.
if (auto last_modified = stored_response->header_list()->get("Last-Modified"sv.bytes()); last_modified.has_value()) {
stored_response->header_list()->append(Infrastructure::Header::from_string_pair("If-Modified-Since"sv, *last_modified));
}
}
// 3. Otherwise, set response to storedResponse and set responses cache state to "local".
else {
response = stored_response;
response->set_cache_state(Infrastructure::Response::CacheState::Local);
}
}
}
}
}