Skip to content

Commit

Permalink
LibWeb/Fetch: Implement logic to process a response from HTTP's cache
Browse files Browse the repository at this point in the history
Co-Authored-By: Andrew Kaster <akaster@serenityos.org>
  • Loading branch information
2 people authored and trflynn89 committed May 23, 2024
1 parent fcbc612 commit b30c361
Showing 1 changed file with 56 additions and 2 deletions.
58 changes: 56 additions & 2 deletions Userland/Libraries/LibWeb/Fetch/Fetching/Fetching.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 httpRequest’s 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 response’s 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 revalidateRequest’s cache mode set to "no-cache".
revalidate_request->set_cache_mode(Infrastructure::Request::CacheMode::NoCache);

// 5. Set revalidateRequest’s prevent no-cache cache-control header modification flag.
revalidate_request->set_prevent_no_cache_cache_control_header_modification(true);

// 6. Set revalidateRequest’s 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 httpRequest’s 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 storedResponse’s header list contains `ETag`, then append (`If-None-Match`, `ETag`'s value) to httpRequest’s 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 storedResponse’s header list contains `Last-Modified`, then append (`If-Modified-Since`, `Last-Modified`'s value) to httpRequest’s 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 response’s cache state to "local".
else {
response = stored_response;
response->set_cache_state(Infrastructure::Response::CacheState::Local);
}
}
}
}
}
Expand Down

0 comments on commit b30c361

Please sign in to comment.