LibWeb: Remove exception throwing from Fetch

These were only here to manage OOMs, but there's not really any way to
recover from small OOMs in Fetch especially with its async nature.
This commit is contained in:
Luke Wilde 2025-09-30 17:15:55 +01:00 committed by Alexander Kalenik
parent baa9b6cc34
commit 167de08c81
Notes: github-actions[bot] 2025-11-07 03:09:49 +00:00
22 changed files with 96 additions and 111 deletions

View file

@ -3015,7 +3015,7 @@ void Document::update_readiness(HTML::DocumentReadyState readiness_value)
auto navigable = this->navigable(); auto navigable = this->navigable();
if (navigable && navigable->is_traversable()) { if (navigable && navigable->is_traversable()) {
if (!is_decoded_svg()) { if (!is_decoded_svg()) {
HTML::HTMLLinkElement::load_fallback_favicon_if_needed(*this).release_value_but_fixme_should_propagate_errors(); HTML::HTMLLinkElement::load_fallback_favicon_if_needed(*this);
} }
navigable->traversable_navigable()->page().client().page_did_finish_loading(url()); navigable->traversable_navigable()->page().client().page_did_finish_loading(url());
} else { } else {

View file

@ -116,7 +116,7 @@ GC::Ref<WebIDL::Promise> fetch(JS::VM& vm, RequestInfo const& input, RequestInit
// 5. Resolve p with responseObject. // 5. Resolve p with responseObject.
WebIDL::resolve_promise(relevant_realm, promise_capability, response_object); WebIDL::resolve_promise(relevant_realm, promise_capability, response_object);
}; };
controller_holder->set_controller(MUST(Fetching::fetch( controller_holder->set_controller(Fetching::fetch(
realm, realm,
request, request,
Infrastructure::FetchAlgorithms::create(vm, Infrastructure::FetchAlgorithms::create(vm,
@ -127,7 +127,7 @@ GC::Ref<WebIDL::Promise> fetch(JS::VM& vm, RequestInfo const& input, RequestInit
.process_response = move(process_response), .process_response = move(process_response),
.process_response_end_of_body = {}, .process_response_end_of_body = {},
.process_response_consume_body = {}, .process_response_consume_body = {},
})))); })));
// 11. Add the following abort steps to requestObjects signal: // 11. Add the following abort steps to requestObjects signal:
(void)request_object->signal()->add_abort_algorithm([locally_aborted, request, controller_holder, promise_capability, request_object, response_object, &relevant_realm] { (void)request_object->signal()->add_abort_algorithm([locally_aborted, request, controller_holder, promise_capability, request_object, response_object, &relevant_realm] {

View file

@ -80,7 +80,7 @@ bool g_http_cache_enabled = false;
}) })
// https://fetch.spec.whatwg.org/#concept-fetch // https://fetch.spec.whatwg.org/#concept-fetch
WebIDL::ExceptionOr<GC::Ref<Infrastructure::FetchController>> fetch(JS::Realm& realm, Infrastructure::Request& request, Infrastructure::FetchAlgorithms const& algorithms, UseParallelQueue use_parallel_queue) GC::Ref<Infrastructure::FetchController> fetch(JS::Realm& realm, Infrastructure::Request& request, Infrastructure::FetchAlgorithms const& algorithms, UseParallelQueue use_parallel_queue)
{ {
dbgln_if(WEB_FETCH_DEBUG, "Fetch: Running 'fetch' with: request @ {}", &request); dbgln_if(WEB_FETCH_DEBUG, "Fetch: Running 'fetch' with: request @ {}", &request);
@ -240,7 +240,7 @@ WebIDL::ExceptionOr<GC::Ref<Infrastructure::FetchController>> fetch(JS::Realm& r
} }
// 15. Run main fetch given fetchParams. // 15. Run main fetch given fetchParams.
(void)TRY(main_fetch(realm, fetch_params)); (void)main_fetch(realm, fetch_params);
// 16. Return fetchParamss controller. // 16. Return fetchParamss controller.
return fetch_params->controller(); return fetch_params->controller();
@ -295,7 +295,7 @@ void populate_request_from_client(JS::Realm const& realm, Infrastructure::Reques
} }
// https://fetch.spec.whatwg.org/#concept-main-fetch // https://fetch.spec.whatwg.org/#concept-main-fetch
WebIDL::ExceptionOr<GC::Ptr<PendingResponse>> main_fetch(JS::Realm& realm, Infrastructure::FetchParams const& fetch_params, Recursive recursive) GC::Ptr<PendingResponse> main_fetch(JS::Realm& realm, Infrastructure::FetchParams const& fetch_params, Recursive recursive)
{ {
dbgln_if(WEB_FETCH_DEBUG, "Fetch: Running 'main fetch' with: fetch_params @ {}", &fetch_params); dbgln_if(WEB_FETCH_DEBUG, "Fetch: Running 'main fetch' with: fetch_params @ {}", &fetch_params);
@ -364,7 +364,7 @@ WebIDL::ExceptionOr<GC::Ptr<PendingResponse>> main_fetch(JS::Realm& realm, Infra
request->current_url().set_scheme("https"_string); request->current_url().set_scheme("https"_string);
} }
auto get_response = GC::create_function(vm.heap(), [&realm, &vm, &fetch_params, request]() -> WebIDL::ExceptionOr<GC::Ref<PendingResponse>> { auto get_response = GC::create_function(vm.heap(), [&realm, &vm, &fetch_params, request]() -> GC::Ref<PendingResponse> {
dbgln_if(WEB_FETCH_DEBUG, "Fetch: Running 'main fetch' get_response() function"); dbgln_if(WEB_FETCH_DEBUG, "Fetch: Running 'main fetch' get_response() function");
auto const* origin = request->origin().get_pointer<URL::Origin>(); auto const* origin = request->origin().get_pointer<URL::Origin>();
@ -443,7 +443,7 @@ WebIDL::ExceptionOr<GC::Ptr<PendingResponse>> main_fetch(JS::Realm& realm, Infra
auto returned_pending_response = PendingResponse::create(vm, request); auto returned_pending_response = PendingResponse::create(vm, request);
// 2. Let corsWithPreflightResponse be the result of running HTTP fetch given fetchParams and true. // 2. Let corsWithPreflightResponse be the result of running HTTP fetch given fetchParams and true.
auto cors_with_preflight_response = TRY(http_fetch(realm, fetch_params, MakeCORSPreflight::Yes)); auto cors_with_preflight_response = http_fetch(realm, fetch_params, MakeCORSPreflight::Yes);
cors_with_preflight_response->when_loaded([returned_pending_response](GC::Ref<Infrastructure::Response> cors_with_preflight_response) { cors_with_preflight_response->when_loaded([returned_pending_response](GC::Ref<Infrastructure::Response> cors_with_preflight_response) {
dbgln_if(WEB_FETCH_DEBUG, "Fetch: Running 'main fetch' cors_with_preflight_response load callback"); dbgln_if(WEB_FETCH_DEBUG, "Fetch: Running 'main fetch' cors_with_preflight_response load callback");
// 3. If corsWithPreflightResponse is a network error, then clear cache entries using request. // 3. If corsWithPreflightResponse is a network error, then clear cache entries using request.
@ -470,7 +470,7 @@ WebIDL::ExceptionOr<GC::Ptr<PendingResponse>> main_fetch(JS::Realm& realm, Infra
// 12. If response is null, then set response to the result of running the steps corresponding to the first // 12. If response is null, then set response to the result of running the steps corresponding to the first
// matching statement: // matching statement:
auto pending_response = !response auto pending_response = !response
? TRY(get_response->function()()) ? get_response->function()()
: PendingResponse::create(vm, request, *response); : PendingResponse::create(vm, request, *response);
// 13. If recursive is true, then return response. // 13. If recursive is true, then return response.
@ -483,10 +483,7 @@ WebIDL::ExceptionOr<GC::Ptr<PendingResponse>> main_fetch(JS::Realm& realm, Infra
// matching statement: // matching statement:
auto pending_response = PendingResponse::create(vm, request, Infrastructure::Response::create(vm)); auto pending_response = PendingResponse::create(vm, request, Infrastructure::Response::create(vm));
if (!response) { if (!response) {
auto pending_response_or_error = get_response->function()(); pending_response = get_response->function()();
if (pending_response_or_error.is_error())
return;
pending_response = pending_response_or_error.release_value();
} }
pending_response->when_loaded([&realm, &vm, &fetch_params, request, response, response_was_null = !response](GC::Ref<Infrastructure::Response> resolved_response) mutable { pending_response->when_loaded([&realm, &vm, &fetch_params, request, response, response_was_null = !response](GC::Ref<Infrastructure::Response> resolved_response) mutable {
dbgln_if(WEB_FETCH_DEBUG, "Fetch: Running 'main fetch' pending_response load callback"); dbgln_if(WEB_FETCH_DEBUG, "Fetch: Running 'main fetch' pending_response load callback");
@ -825,7 +822,7 @@ void fetch_response_handover(JS::Realm& realm, Infrastructure::FetchParams const
} }
// https://fetch.spec.whatwg.org/#concept-scheme-fetch // https://fetch.spec.whatwg.org/#concept-scheme-fetch
WebIDL::ExceptionOr<GC::Ref<PendingResponse>> scheme_fetch(JS::Realm& realm, Infrastructure::FetchParams const& fetch_params) GC::Ref<PendingResponse> scheme_fetch(JS::Realm& realm, Infrastructure::FetchParams const& fetch_params)
{ {
dbgln_if(WEB_FETCH_DEBUG, "Fetch: Running 'scheme fetch' with: fetch_params @ {}", &fetch_params); dbgln_if(WEB_FETCH_DEBUG, "Fetch: Running 'scheme fetch' with: fetch_params @ {}", &fetch_params);
@ -858,7 +855,7 @@ WebIDL::ExceptionOr<GC::Ref<PendingResponse>> scheme_fetch(JS::Realm& realm, Inf
} }
// FIXME: This is actually wrong, see note above. // FIXME: This is actually wrong, see note above.
return TRY(nonstandard_resource_loader_file_or_http_network_fetch(realm, fetch_params)); return nonstandard_resource_loader_file_or_http_network_fetch(realm, fetch_params);
} }
// -> "blob" // -> "blob"
else if (request->current_url().scheme() == "blob"sv) { else if (request->current_url().scheme() == "blob"sv) {
@ -968,7 +965,7 @@ WebIDL::ExceptionOr<GC::Ref<PendingResponse>> scheme_fetch(JS::Realm& realm, Inf
} }
// 8. Let slicedBlob be the result of invoking slice blob given blob, rangeStart, rangeEnd + 1, and type. // 8. Let slicedBlob be the result of invoking slice blob given blob, rangeStart, rangeEnd + 1, and type.
auto sliced_blob = TRY(blob->slice(*range_start, *range_end + 1, type)); auto sliced_blob = MUST(blob->slice(*range_start, *range_end + 1, type));
// 9. Let slicedBodyWithType be the result of safely extracting slicedBlob. // 9. Let slicedBodyWithType be the result of safely extracting slicedBlob.
auto sliced_body_with_type = safely_extract_body(realm, sliced_blob->raw_bytes()); auto sliced_body_with_type = safely_extract_body(realm, sliced_blob->raw_bytes());
@ -1035,7 +1032,7 @@ WebIDL::ExceptionOr<GC::Ref<PendingResponse>> scheme_fetch(JS::Realm& realm, Inf
// For now, unfortunate as it is, file: URLs are left as an exercise for the reader. // For now, unfortunate as it is, file: URLs are left as an exercise for the reader.
// When in doubt, return a network error. // When in doubt, return a network error.
if (request->origin().has<URL::Origin>() && (request->origin().get<URL::Origin>().is_opaque() || request->origin().get<URL::Origin>().scheme() == "file"sv || request->origin().get<URL::Origin>().scheme() == "resource"sv)) if (request->origin().has<URL::Origin>() && (request->origin().get<URL::Origin>().is_opaque() || request->origin().get<URL::Origin>().scheme() == "file"sv || request->origin().get<URL::Origin>().scheme() == "resource"sv))
return TRY(nonstandard_resource_loader_file_or_http_network_fetch(realm, fetch_params)); return nonstandard_resource_loader_file_or_http_network_fetch(realm, fetch_params);
else else
return PendingResponse::create(vm, request, Infrastructure::Response::network_error(vm, "Request with 'file:' or 'resource:' URL blocked"_string)); return PendingResponse::create(vm, request, Infrastructure::Response::network_error(vm, "Request with 'file:' or 'resource:' URL blocked"_string));
} }
@ -1053,7 +1050,7 @@ WebIDL::ExceptionOr<GC::Ref<PendingResponse>> scheme_fetch(JS::Realm& realm, Inf
} }
// https://fetch.spec.whatwg.org/#concept-http-fetch // https://fetch.spec.whatwg.org/#concept-http-fetch
WebIDL::ExceptionOr<GC::Ref<PendingResponse>> http_fetch(JS::Realm& realm, Infrastructure::FetchParams const& fetch_params, MakeCORSPreflight make_cors_preflight) GC::Ref<PendingResponse> http_fetch(JS::Realm& realm, Infrastructure::FetchParams const& fetch_params, MakeCORSPreflight make_cors_preflight)
{ {
dbgln_if(WEB_FETCH_DEBUG, "Fetch: Running 'HTTP fetch' with: fetch_params @ {}, make_cors_preflight = {}", dbgln_if(WEB_FETCH_DEBUG, "Fetch: Running 'HTTP fetch' with: fetch_params @ {}, make_cors_preflight = {}",
&fetch_params, make_cors_preflight == MakeCORSPreflight::Yes ? "Yes"sv : "No"sv); &fetch_params, make_cors_preflight == MakeCORSPreflight::Yes ? "Yes"sv : "No"sv);
@ -1144,12 +1141,12 @@ WebIDL::ExceptionOr<GC::Ref<PendingResponse>> http_fetch(JS::Realm& realm, Infra
// FIXME: We currently have no cache, so there will always be no header-name cache entry. // FIXME: We currently have no cache, so there will always be no header-name cache entry.
|| !Infrastructure::get_cors_unsafe_header_names(request->header_list()).is_empty())) { || !Infrastructure::get_cors_unsafe_header_names(request->header_list()).is_empty())) {
// 1. Let preflightResponse be the result of running CORS-preflight fetch given request. // 1. Let preflightResponse be the result of running CORS-preflight fetch given request.
pending_preflight_response = TRY(cors_preflight_fetch(realm, request)); pending_preflight_response = cors_preflight_fetch(realm, request);
// NOTE: Step 2 is performed in pending_preflight_response's load callback below. // NOTE: Step 2 is performed in pending_preflight_response's load callback below.
} }
auto fetch_main_content = [request = GC::make_root(request), realm = GC::make_root(realm), fetch_params = GC::make_root(fetch_params)]() -> WebIDL::ExceptionOr<GC::Ref<PendingResponse>> { auto fetch_main_content = [request = GC::make_root(request), realm = GC::make_root(realm), fetch_params = GC::make_root(fetch_params)]() -> GC::Ref<PendingResponse> {
// 2. If requests redirect mode is "follow", then set requests service-workers mode to "none". // 2. If requests redirect mode is "follow", then set requests service-workers mode to "none".
// NOTE: Redirects coming from the network (as opposed to from a service worker) are not to be exposed to a // NOTE: Redirects coming from the network (as opposed to from a service worker) are not to be exposed to a
// service worker. // service worker.
@ -1171,14 +1168,14 @@ WebIDL::ExceptionOr<GC::Ref<PendingResponse>> http_fetch(JS::Realm& realm, Infra
return; return;
} }
auto pending_main_content_response = TRY_OR_IGNORE(fetch_main_content()); auto pending_main_content_response = fetch_main_content();
pending_main_content_response->when_loaded([pending_actual_response](GC::Ref<Infrastructure::Response> main_content_response) { pending_main_content_response->when_loaded([pending_actual_response](GC::Ref<Infrastructure::Response> main_content_response) {
dbgln_if(WEB_FETCH_DEBUG, "Fetch: Running 'HTTP fetch' pending_main_content_response load callback"); dbgln_if(WEB_FETCH_DEBUG, "Fetch: Running 'HTTP fetch' pending_main_content_response load callback");
pending_actual_response->resolve(main_content_response); pending_actual_response->resolve(main_content_response);
}); });
}); });
} else { } else {
pending_actual_response = TRY(fetch_main_content()); pending_actual_response = fetch_main_content();
} }
} else { } else {
pending_actual_response = PendingResponse::create(vm, request, Infrastructure::Response::create(vm)); pending_actual_response = PendingResponse::create(vm, request, Infrastructure::Response::create(vm));
@ -1249,7 +1246,7 @@ WebIDL::ExceptionOr<GC::Ref<PendingResponse>> http_fetch(JS::Realm& realm, Infra
// -> "follow" // -> "follow"
case Infrastructure::Request::RedirectMode::Follow: case Infrastructure::Request::RedirectMode::Follow:
// 1. Set response to the result of running HTTP-redirect fetch given fetchParams and response. // 1. Set response to the result of running HTTP-redirect fetch given fetchParams and response.
inner_pending_response = TRY_OR_IGNORE(http_redirect_fetch(realm, fetch_params, *response)); inner_pending_response = http_redirect_fetch(realm, fetch_params, *response);
break; break;
default: default:
VERIFY_NOT_REACHED(); VERIFY_NOT_REACHED();
@ -1272,7 +1269,7 @@ WebIDL::ExceptionOr<GC::Ref<PendingResponse>> http_fetch(JS::Realm& realm, Infra
} }
// https://fetch.spec.whatwg.org/#concept-http-redirect-fetch // https://fetch.spec.whatwg.org/#concept-http-redirect-fetch
WebIDL::ExceptionOr<GC::Ptr<PendingResponse>> http_redirect_fetch(JS::Realm& realm, Infrastructure::FetchParams const& fetch_params, Infrastructure::Response& response) GC::Ptr<PendingResponse> http_redirect_fetch(JS::Realm& realm, Infrastructure::FetchParams const& fetch_params, Infrastructure::Response& response)
{ {
dbgln_if(WEB_FETCH_DEBUG, "Fetch: Running 'HTTP-redirect fetch' with: fetch_params @ {}, response = {}", &fetch_params, &response); dbgln_if(WEB_FETCH_DEBUG, "Fetch: Running 'HTTP-redirect fetch' with: fetch_params @ {}, response = {}", &fetch_params, &response);
@ -1696,7 +1693,7 @@ static RefPtr<CachePartition> determine_the_http_cache_partition(Infrastructure:
} }
// https://fetch.spec.whatwg.org/#concept-http-network-or-cache-fetch // https://fetch.spec.whatwg.org/#concept-http-network-or-cache-fetch
WebIDL::ExceptionOr<GC::Ref<PendingResponse>> http_network_or_cache_fetch(JS::Realm& realm, Infrastructure::FetchParams const& fetch_params, IsAuthenticationFetch is_authentication_fetch, IsNewConnectionFetch is_new_connection_fetch) GC::Ref<PendingResponse> http_network_or_cache_fetch(JS::Realm& realm, Infrastructure::FetchParams const& fetch_params, IsAuthenticationFetch is_authentication_fetch, IsNewConnectionFetch is_new_connection_fetch)
{ {
dbgln_if(WEB_FETCH_DEBUG, "Fetch: Running 'HTTP-network-or-cache fetch' with: fetch_params @ {}, is_authentication_fetch = {}, is_new_connection_fetch = {}", dbgln_if(WEB_FETCH_DEBUG, "Fetch: Running 'HTTP-network-or-cache fetch' with: fetch_params @ {}, is_authentication_fetch = {}, is_new_connection_fetch = {}",
&fetch_params, is_authentication_fetch == IsAuthenticationFetch::Yes ? "Yes"sv : "No"sv, is_new_connection_fetch == IsNewConnectionFetch::Yes ? "Yes"sv : "No"sv); &fetch_params, is_authentication_fetch == IsAuthenticationFetch::Yes ? "Yes"sv : "No"sv, is_new_connection_fetch == IsNewConnectionFetch::Yes ? "Yes"sv : "No"sv);
@ -1852,7 +1849,7 @@ WebIDL::ExceptionOr<GC::Ref<PendingResponse>> http_network_or_cache_fetch(JS::Re
if (http_request->referrer().has<URL::URL>()) { if (http_request->referrer().has<URL::URL>()) {
// 1. Let referrerValue be httpRequests referrer, serialized and isomorphic encoded. // 1. Let referrerValue be httpRequests referrer, serialized and isomorphic encoded.
auto referrer_string = http_request->referrer().get<URL::URL>().serialize(); auto referrer_string = http_request->referrer().get<URL::URL>().serialize();
auto referrer_value = TRY_OR_THROW_OOM(vm, ByteBuffer::copy(referrer_string.bytes())); auto referrer_value = MUST(ByteBuffer::copy(referrer_string.bytes()));
// 2. Append (`Referer`, referrerValue) to httpRequests header list. // 2. Append (`Referer`, referrerValue) to httpRequests header list.
auto header = Infrastructure::Header { auto header = Infrastructure::Header {
@ -1981,7 +1978,7 @@ WebIDL::ExceptionOr<GC::Ref<PendingResponse>> http_network_or_cache_fetch(JS::Re
else if (http_request->current_url().includes_credentials() && is_authentication_fetch == IsAuthenticationFetch::Yes) { else if (http_request->current_url().includes_credentials() && is_authentication_fetch == IsAuthenticationFetch::Yes) {
auto const& url = http_request->current_url(); auto const& url = http_request->current_url();
auto payload = MUST(String::formatted("{}:{}", URL::percent_decode(url.username()), URL::percent_decode(url.password()))); auto payload = MUST(String::formatted("{}:{}", URL::percent_decode(url.username()), URL::percent_decode(url.password())));
authorization_value = TRY_OR_THROW_OOM(vm, encode_base64(payload.bytes())); authorization_value = MUST(encode_base64(payload.bytes()));
} }
// 4. If authorizationValue is non-null, then append (`Authorization`, authorizationValue) to // 4. If authorizationValue is non-null, then append (`Authorization`, authorizationValue) to
@ -2087,7 +2084,7 @@ WebIDL::ExceptionOr<GC::Ref<PendingResponse>> http_network_or_cache_fetch(JS::Re
// 2. Let forwardResponse be the result of running HTTP-network fetch given httpFetchParams, includeCredentials, // 2. Let forwardResponse be the result of running HTTP-network fetch given httpFetchParams, includeCredentials,
// and isNewConnectionFetch. // and isNewConnectionFetch.
pending_forward_response = TRY(nonstandard_resource_loader_file_or_http_network_fetch(realm, *http_fetch_params, include_credentials, is_new_connection_fetch)); pending_forward_response = nonstandard_resource_loader_file_or_http_network_fetch(realm, *http_fetch_params, include_credentials, is_new_connection_fetch);
} else { } else {
pending_forward_response = PendingResponse::create(vm, request, Infrastructure::Response::create(vm)); pending_forward_response = PendingResponse::create(vm, request, Infrastructure::Response::create(vm));
} }
@ -2205,7 +2202,7 @@ WebIDL::ExceptionOr<GC::Ref<PendingResponse>> http_network_or_cache_fetch(JS::Re
} }
// 4. Set response to the result of running HTTP-network-or-cache fetch given fetchParams and true. // 4. Set response to the result of running HTTP-network-or-cache fetch given fetchParams and true.
inner_pending_response = TRY_OR_IGNORE(http_network_or_cache_fetch(realm, fetch_params, IsAuthenticationFetch::Yes)); inner_pending_response = http_network_or_cache_fetch(realm, fetch_params, IsAuthenticationFetch::Yes);
} }
inner_pending_response->when_loaded([&realm, &vm, &fetch_params, request, returned_pending_response, is_authentication_fetch, is_new_connection_fetch](GC::Ref<Infrastructure::Response> response) { inner_pending_response->when_loaded([&realm, &vm, &fetch_params, request, returned_pending_response, is_authentication_fetch, is_new_connection_fetch](GC::Ref<Infrastructure::Response> response) {
@ -2255,7 +2252,7 @@ WebIDL::ExceptionOr<GC::Ref<PendingResponse>> http_network_or_cache_fetch(JS::Re
} }
// 2. Set response to the result of running HTTP-network-or-cache fetch given fetchParams, // 2. Set response to the result of running HTTP-network-or-cache fetch given fetchParams,
// isAuthenticationFetch, and true. // isAuthenticationFetch, and true.
inner_pending_response = TRY_OR_IGNORE(http_network_or_cache_fetch(realm, fetch_params, is_authentication_fetch, IsNewConnectionFetch::Yes)); inner_pending_response = http_network_or_cache_fetch(realm, fetch_params, is_authentication_fetch, IsNewConnectionFetch::Yes);
} }
inner_pending_response->when_loaded([returned_pending_response, is_authentication_fetch](GC::Ref<Infrastructure::Response> response) { inner_pending_response->when_loaded([returned_pending_response, is_authentication_fetch](GC::Ref<Infrastructure::Response> response) {
@ -2301,7 +2298,7 @@ static void log_response(auto const& status_code, auto const& headers, auto cons
// https://fetch.spec.whatwg.org/#concept-http-network-fetch // https://fetch.spec.whatwg.org/#concept-http-network-fetch
// Drop-in replacement for 'HTTP-network fetch', but obviously non-standard :^) // Drop-in replacement for 'HTTP-network fetch', but obviously non-standard :^)
// It also handles file:// URLs since those can also go through ResourceLoader. // It also handles file:// URLs since those can also go through ResourceLoader.
WebIDL::ExceptionOr<GC::Ref<PendingResponse>> nonstandard_resource_loader_file_or_http_network_fetch(JS::Realm& realm, Infrastructure::FetchParams const& fetch_params, IncludeCredentials include_credentials, IsNewConnectionFetch is_new_connection_fetch) GC::Ref<PendingResponse> nonstandard_resource_loader_file_or_http_network_fetch(JS::Realm& realm, Infrastructure::FetchParams const& fetch_params, IncludeCredentials include_credentials, IsNewConnectionFetch is_new_connection_fetch)
{ {
dbgln_if(WEB_FETCH_DEBUG, "Fetch: Running 'non-standard HTTP-network fetch' with: fetch_params @ {}", &fetch_params); dbgln_if(WEB_FETCH_DEBUG, "Fetch: Running 'non-standard HTTP-network fetch' with: fetch_params @ {}", &fetch_params);
@ -2329,18 +2326,15 @@ WebIDL::ExceptionOr<GC::Ref<PendingResponse>> nonstandard_resource_loader_file_o
load_request.set_header(ByteString::copy(header.name), ByteString::copy(header.value)); load_request.set_header(ByteString::copy(header.name), ByteString::copy(header.value));
if (auto const* body = request->body().get_pointer<GC::Ref<Infrastructure::Body>>()) { if (auto const* body = request->body().get_pointer<GC::Ref<Infrastructure::Body>>()) {
TRY((*body)->source().visit( (*body)->source().visit(
[&](ByteBuffer const& byte_buffer) -> WebIDL::ExceptionOr<void> { [&](ByteBuffer const& byte_buffer) {
load_request.set_body(TRY_OR_THROW_OOM(vm, ByteBuffer::copy(byte_buffer))); load_request.set_body(MUST(ByteBuffer::copy(byte_buffer)));
return {};
}, },
[&](GC::Root<FileAPI::Blob> const& blob_handle) -> WebIDL::ExceptionOr<void> { [&](GC::Root<FileAPI::Blob> const& blob_handle) {
load_request.set_body(TRY_OR_THROW_OOM(vm, ByteBuffer::copy(blob_handle->raw_bytes()))); load_request.set_body(MUST(ByteBuffer::copy(blob_handle->raw_bytes())));
return {};
}, },
[](Empty) -> WebIDL::ExceptionOr<void> { [](Empty) {
return {}; });
}));
} }
auto pending_response = PendingResponse::create(vm, request); auto pending_response = PendingResponse::create(vm, request);
@ -2528,7 +2522,7 @@ WebIDL::ExceptionOr<GC::Ref<PendingResponse>> nonstandard_resource_loader_file_o
} }
// https://fetch.spec.whatwg.org/#cors-preflight-fetch-0 // https://fetch.spec.whatwg.org/#cors-preflight-fetch-0
WebIDL::ExceptionOr<GC::Ref<PendingResponse>> cors_preflight_fetch(JS::Realm& realm, Infrastructure::Request& request) GC::Ref<PendingResponse> cors_preflight_fetch(JS::Realm& realm, Infrastructure::Request& request)
{ {
dbgln_if(WEB_FETCH_DEBUG, "Fetch: Running 'CORS-preflight fetch' with request @ {}", &request); dbgln_if(WEB_FETCH_DEBUG, "Fetch: Running 'CORS-preflight fetch' with request @ {}", &request);
@ -2538,7 +2532,7 @@ WebIDL::ExceptionOr<GC::Ref<PendingResponse>> cors_preflight_fetch(JS::Realm& re
// requests initiator, destination is requests destination, origin is requests origin, referrer is requests referrer, // requests initiator, destination is requests destination, origin is requests origin, referrer is requests referrer,
// referrer policy is requests referrer policy, mode is "cors", and response tainting is "cors". // referrer policy is requests referrer policy, mode is "cors", and response tainting is "cors".
auto preflight = Fetch::Infrastructure::Request::create(vm); auto preflight = Fetch::Infrastructure::Request::create(vm);
preflight->set_method(TRY_OR_THROW_OOM(vm, ByteBuffer::copy("OPTIONS"sv.bytes()))); preflight->set_method(MUST(ByteBuffer::copy("OPTIONS"sv.bytes())));
preflight->set_url_list(request.url_list()); preflight->set_url_list(request.url_list());
preflight->set_initiator(request.initiator()); preflight->set_initiator(request.initiator());
preflight->set_destination(request.destination()); preflight->set_destination(request.destination());
@ -2569,14 +2563,14 @@ WebIDL::ExceptionOr<GC::Ref<PendingResponse>> cors_preflight_fetch(JS::Realm& re
bool first = true; bool first = true;
for (auto const& header : headers) { for (auto const& header : headers) {
if (!first) if (!first)
TRY_OR_THROW_OOM(vm, value.try_append(',')); value.append(',');
TRY_OR_THROW_OOM(vm, value.try_append(header)); value.append(header);
first = false; first = false;
} }
// 2. Append (`Access-Control-Request-Headers`, value) to preflights header list. // 2. Append (`Access-Control-Request-Headers`, value) to preflights header list.
temp_header = Infrastructure::Header { temp_header = Infrastructure::Header {
.name = TRY_OR_THROW_OOM(vm, ByteBuffer::copy("Access-Control-Request-Headers"sv.bytes())), .name = MUST(ByteBuffer::copy("Access-Control-Request-Headers"sv.bytes())),
.value = move(value), .value = move(value),
}; };
preflight->header_list()->append(move(temp_header)); preflight->header_list()->append(move(temp_header));
@ -2589,7 +2583,7 @@ WebIDL::ExceptionOr<GC::Ref<PendingResponse>> cors_preflight_fetch(JS::Realm& re
auto returned_pending_response = PendingResponse::create(vm, request); auto returned_pending_response = PendingResponse::create(vm, request);
auto preflight_response = TRY(http_network_or_cache_fetch(realm, fetch_params)); auto preflight_response = http_network_or_cache_fetch(realm, fetch_params);
preflight_response->when_loaded([&vm, &request, returned_pending_response](GC::Ref<Infrastructure::Response> response) { preflight_response->when_loaded([&vm, &request, returned_pending_response](GC::Ref<Infrastructure::Response> response) {
dbgln_if(WEB_FETCH_DEBUG, "Fetch: Running 'CORS-preflight fetch' preflight_response load callback"); dbgln_if(WEB_FETCH_DEBUG, "Fetch: Running 'CORS-preflight fetch' preflight_response load callback");

View file

@ -39,16 +39,16 @@ constexpr auto keepalive_maximum_size = 64 * KiB;
ENUMERATE_BOOL_PARAMS ENUMERATE_BOOL_PARAMS
#undef __ENUMERATE_BOOL_PARAM #undef __ENUMERATE_BOOL_PARAM
WEB_API WebIDL::ExceptionOr<GC::Ref<Infrastructure::FetchController>> fetch(JS::Realm&, Infrastructure::Request&, Infrastructure::FetchAlgorithms const&, UseParallelQueue use_parallel_queue = UseParallelQueue::No); WEB_API GC::Ref<Infrastructure::FetchController> fetch(JS::Realm&, Infrastructure::Request&, Infrastructure::FetchAlgorithms const&, UseParallelQueue use_parallel_queue = UseParallelQueue::No);
WebIDL::ExceptionOr<GC::Ptr<PendingResponse>> main_fetch(JS::Realm&, Infrastructure::FetchParams const&, Recursive recursive = Recursive::No); GC::Ptr<PendingResponse> main_fetch(JS::Realm&, Infrastructure::FetchParams const&, Recursive recursive = Recursive::No);
void populate_request_from_client(JS::Realm const&, Infrastructure::Request&); void populate_request_from_client(JS::Realm const&, Infrastructure::Request&);
void fetch_response_handover(JS::Realm&, Infrastructure::FetchParams const&, Infrastructure::Response&); void fetch_response_handover(JS::Realm&, Infrastructure::FetchParams const&, Infrastructure::Response&);
WebIDL::ExceptionOr<GC::Ref<PendingResponse>> scheme_fetch(JS::Realm&, Infrastructure::FetchParams const&); GC::Ref<PendingResponse> scheme_fetch(JS::Realm&, Infrastructure::FetchParams const&);
WebIDL::ExceptionOr<GC::Ref<PendingResponse>> http_fetch(JS::Realm&, Infrastructure::FetchParams const&, MakeCORSPreflight make_cors_preflight = MakeCORSPreflight::No); GC::Ref<PendingResponse> http_fetch(JS::Realm&, Infrastructure::FetchParams const&, MakeCORSPreflight make_cors_preflight = MakeCORSPreflight::No);
WebIDL::ExceptionOr<GC::Ptr<PendingResponse>> http_redirect_fetch(JS::Realm&, Infrastructure::FetchParams const&, Infrastructure::Response&); GC::Ptr<PendingResponse> http_redirect_fetch(JS::Realm&, Infrastructure::FetchParams const&, Infrastructure::Response&);
WebIDL::ExceptionOr<GC::Ref<PendingResponse>> http_network_or_cache_fetch(JS::Realm&, Infrastructure::FetchParams const&, IsAuthenticationFetch is_authentication_fetch = IsAuthenticationFetch::No, IsNewConnectionFetch is_new_connection_fetch = IsNewConnectionFetch::No); GC::Ref<PendingResponse> http_network_or_cache_fetch(JS::Realm&, Infrastructure::FetchParams const&, IsAuthenticationFetch is_authentication_fetch = IsAuthenticationFetch::No, IsNewConnectionFetch is_new_connection_fetch = IsNewConnectionFetch::No);
WebIDL::ExceptionOr<GC::Ref<PendingResponse>> nonstandard_resource_loader_file_or_http_network_fetch(JS::Realm&, Infrastructure::FetchParams const&, IncludeCredentials include_credentials = IncludeCredentials::No, IsNewConnectionFetch is_new_connection_fetch = IsNewConnectionFetch::No); GC::Ref<PendingResponse> nonstandard_resource_loader_file_or_http_network_fetch(JS::Realm&, Infrastructure::FetchParams const&, IncludeCredentials include_credentials = IncludeCredentials::No, IsNewConnectionFetch is_new_connection_fetch = IsNewConnectionFetch::No);
WebIDL::ExceptionOr<GC::Ref<PendingResponse>> cors_preflight_fetch(JS::Realm&, Infrastructure::Request&); GC::Ref<PendingResponse> cors_preflight_fetch(JS::Realm&, Infrastructure::Request&);
void set_sec_fetch_dest_header(Infrastructure::Request&); void set_sec_fetch_dest_header(Infrastructure::Request&);
void set_sec_fetch_mode_header(Infrastructure::Request&); void set_sec_fetch_mode_header(Infrastructure::Request&);
void set_sec_fetch_site_header(Infrastructure::Request&); void set_sec_fetch_site_header(Infrastructure::Request&);

View file

@ -158,7 +158,7 @@ WebIDL::ExceptionOr<GC::Ref<EventSource>> EventSource::construct_impl(JS::Realm&
}; };
event_source->m_fetch_algorithms = Fetch::Infrastructure::FetchAlgorithms::create(vm, move(fetch_algorithms_input)); event_source->m_fetch_algorithms = Fetch::Infrastructure::FetchAlgorithms::create(vm, move(fetch_algorithms_input));
event_source->m_fetch_controller = TRY(Fetch::Fetching::fetch(realm, request, *event_source->m_fetch_algorithms)); event_source->m_fetch_controller = Fetch::Fetching::fetch(realm, request, *event_source->m_fetch_algorithms);
// 16. Return ev. // 16. Return ev.
return event_source; return event_source;
@ -328,7 +328,7 @@ void EventSource::reestablish_the_connection()
} }
// 4. Fetch request and process the response obtained in this fashion, if any, as described earlier in this section. // 4. Fetch request and process the response obtained in this fashion, if any, as described earlier in this section.
m_fetch_controller = Fetch::Fetching::fetch(realm(), request, *m_fetch_algorithms).release_value_but_fixme_should_propagate_errors(); m_fetch_controller = Fetch::Fetching::fetch(realm(), request, *m_fetch_algorithms);
})); }));
} }

View file

@ -449,7 +449,7 @@ void HTMLLinkElement::default_fetch_and_process_linked_resource()
if (m_fetch_controller) if (m_fetch_controller)
m_fetch_controller->abort(realm(), {}); m_fetch_controller->abort(realm(), {});
m_fetch_controller = MUST(Fetch::Fetching::fetch(realm(), *request, Fetch::Infrastructure::FetchAlgorithms::create(vm(), move(fetch_algorithms_input)))); m_fetch_controller = Fetch::Fetching::fetch(realm(), *request, Fetch::Infrastructure::FetchAlgorithms::create(vm(), move(fetch_algorithms_input)));
} }
// https://html.spec.whatwg.org/multipage/links.html#link-type-dns-prefetch:fetch-and-process-the-linked-resource-2 // https://html.spec.whatwg.org/multipage/links.html#link-type-dns-prefetch:fetch-and-process-the-linked-resource-2
@ -730,7 +730,7 @@ void HTMLLinkElement::preload(LinkProcessingOptions& options, GC::Ptr<GC::Functi
process_response->function()(response); process_response->function()(response);
}; };
m_fetch_controller = MUST(Fetch::Fetching::fetch(realm, *request, Fetch::Infrastructure::FetchAlgorithms::create(vm, move(fetch_algorithms_input)))); m_fetch_controller = Fetch::Fetching::fetch(realm, *request, Fetch::Infrastructure::FetchAlgorithms::create(vm, move(fetch_algorithms_input)));
// 12. Let commit be the following steps given a Document document: // 12. Let commit be the following steps given a Document document:
auto commit = GC::Function<void(DOM::Document&)>::create(realm.heap(), [entry, report_timing](DOM::Document& document) { auto commit = GC::Function<void(DOM::Document&)>::create(realm.heap(), [entry, report_timing](DOM::Document& document) {
@ -933,7 +933,7 @@ bool HTMLLinkElement::load_favicon_and_use_if_window_is_active()
} }
// https://html.spec.whatwg.org/multipage/links.html#rel-icon:the-link-element-3 // https://html.spec.whatwg.org/multipage/links.html#rel-icon:the-link-element-3
WebIDL::ExceptionOr<void> HTMLLinkElement::load_fallback_favicon_if_needed(GC::Ref<DOM::Document> document) void HTMLLinkElement::load_fallback_favicon_if_needed(GC::Ref<DOM::Document> document)
{ {
auto& realm = document->realm(); auto& realm = document->realm();
auto& vm = realm.vm(); auto& vm = realm.vm();
@ -941,9 +941,9 @@ WebIDL::ExceptionOr<void> HTMLLinkElement::load_fallback_favicon_if_needed(GC::R
// In the absence of a link with the icon keyword, for Document objects whose URL's scheme is an HTTP(S) scheme, // In the absence of a link with the icon keyword, for Document objects whose URL's scheme is an HTTP(S) scheme,
// user agents may instead run these steps in parallel: // user agents may instead run these steps in parallel:
if (document->has_active_favicon()) if (document->has_active_favicon())
return {}; return;
if (!document->url().scheme().is_one_of("http"sv, "https"sv)) if (!document->url().scheme().is_one_of("http"sv, "https"sv))
return {}; return;
// 1. Let request be a new request whose URL is the URL record obtained by resolving the URL "/favicon.ico" against // 1. Let request be a new request whose URL is the URL record obtained by resolving the URL "/favicon.ico" against
// the Document object's URL, client is the Document object's relevant settings object, destination is "image", // the Document object's URL, client is the Document object's relevant settings object, destination is "image",
@ -978,8 +978,7 @@ WebIDL::ExceptionOr<void> HTMLLinkElement::load_fallback_favicon_if_needed(GC::R
body->fully_read(realm, process_body, process_body_error, global); body->fully_read(realm, process_body, process_body_error, global);
}; };
TRY(Fetch::Fetching::fetch(realm, request, Fetch::Infrastructure::FetchAlgorithms::create(vm, move(fetch_algorithms_input)))); Fetch::Fetching::fetch(realm, request, Fetch::Infrastructure::FetchAlgorithms::create(vm, move(fetch_algorithms_input)));
return {};
} }
bool HTMLLinkElement::should_fetch_and_process_resource_type() const bool HTMLLinkElement::should_fetch_and_process_resource_type() const

View file

@ -38,7 +38,7 @@ public:
bool has_loaded_icon() const; bool has_loaded_icon() const;
bool load_favicon_and_use_if_window_is_active(); bool load_favicon_and_use_if_window_is_active();
static WebIDL::ExceptionOr<void> load_fallback_favicon_if_needed(GC::Ref<DOM::Document>); static void load_fallback_favicon_if_needed(GC::Ref<DOM::Document>);
void set_parser_document(Badge<HTMLParser>, GC::Ref<DOM::Document> document) { m_parser_document = document; } void set_parser_document(Badge<HTMLParser>, GC::Ref<DOM::Document> document) { m_parser_document = document; }
void set_was_enabled_when_created_by_parser(Badge<HTMLParser>, bool was_enabled_when_created_by_parser) { m_was_enabled_when_created_by_parser = was_enabled_when_created_by_parser; } void set_was_enabled_when_created_by_parser(Badge<HTMLParser>, bool was_enabled_when_created_by_parser) { m_was_enabled_when_created_by_parser = was_enabled_when_created_by_parser; }

View file

@ -1098,7 +1098,7 @@ WebIDL::ExceptionOr<void> HTMLMediaElement::fetch_resource(URL::URL const& url_r
response->body()->fully_read(realm, update_media, empty_algorithm, GC::Ref { global }); response->body()->fully_read(realm, update_media, empty_algorithm, GC::Ref { global });
}; };
m_fetch_controller = TRY(Fetch::Fetching::fetch(realm, request, Fetch::Infrastructure::FetchAlgorithms::create(vm, move(fetch_algorithms_input)))); m_fetch_controller = Fetch::Fetching::fetch(realm, request, Fetch::Infrastructure::FetchAlgorithms::create(vm, move(fetch_algorithms_input)));
break; break;
} }

View file

@ -315,11 +315,7 @@ void HTMLObjectElement::queue_element_task_to_run_object_representation_steps()
}; };
// 5. Fetch request. // 5. Fetch request.
auto result = Fetch::Fetching::fetch(realm, request, Fetch::Infrastructure::FetchAlgorithms::create(vm, move(fetch_algorithms_input))); (void)Fetch::Fetching::fetch(realm, request, Fetch::Infrastructure::FetchAlgorithms::create(vm, move(fetch_algorithms_input)));
if (result.is_error()) {
resource_did_fail();
return;
}
// Fetching the resource must delay the load event of the element's node document until the task that is // Fetching the resource must delay the load event of the element's node document until the task that is
// queued by the networking task source once the resource has been fetched (defined next) has been run. // queued by the networking task source once the resource has been fetched (defined next) has been run.

View file

@ -439,7 +439,7 @@ void HTMLScriptElement::prepare_script()
// -> "classic" // -> "classic"
if (m_script_type == ScriptType::Classic) { if (m_script_type == ScriptType::Classic) {
// Fetch a classic script given url, settings object, options, classic script CORS setting, encoding, and onComplete. // Fetch a classic script given url, settings object, options, classic script CORS setting, encoding, and onComplete.
fetch_classic_script(*this, *url, settings_object, move(options), classic_script_cors_setting, encoding.release_value(), on_complete).release_value_but_fixme_should_propagate_errors(); fetch_classic_script(*this, *url, settings_object, move(options), classic_script_cors_setting, encoding.release_value(), on_complete);
} }
// -> "module" // -> "module"
else if (m_script_type == ScriptType::Module) { else if (m_script_type == ScriptType::Module) {

View file

@ -247,7 +247,7 @@ void HTMLTrackElement::start_the_track_processing_model_parallel_steps()
// 4. Fetch request. // 4. Fetch request.
m_fetch_algorithms = Fetch::Infrastructure::FetchAlgorithms::create(vm(), move(fetch_algorithms_input)); m_fetch_algorithms = Fetch::Infrastructure::FetchAlgorithms::create(vm(), move(fetch_algorithms_input));
m_fetch_controller = MUST(Fetch::Fetching::fetch(realm, request, *m_fetch_algorithms)); m_fetch_controller = Fetch::Fetching::fetch(realm, request, *m_fetch_algorithms);
} else { } else {
track_failed_to_load(); track_failed_to_load();
return; return;

View file

@ -182,7 +182,7 @@ WebIDL::ExceptionOr<void> HTMLVideoElement::determine_element_poster_frame(Optio
response->body()->fully_read(realm, on_image_data_read, empty_algorithm, GC::Ref { global }); response->body()->fully_read(realm, on_image_data_read, empty_algorithm, GC::Ref { global });
}; };
m_fetch_controller = TRY(Fetch::Fetching::fetch(realm, request, Fetch::Infrastructure::FetchAlgorithms::create(vm, move(fetch_algorithms_input)))); m_fetch_controller = Fetch::Fetching::fetch(realm, request, Fetch::Infrastructure::FetchAlgorithms::create(vm, move(fetch_algorithms_input)));
return {}; return {};
} }

View file

@ -834,7 +834,7 @@ static GC::Ref<NavigationParams> create_navigation_params_from_a_srcdoc_resource
} }
// https://html.spec.whatwg.org/multipage/browsing-the-web.html#create-navigation-params-by-fetching // https://html.spec.whatwg.org/multipage/browsing-the-web.html#create-navigation-params-by-fetching
static WebIDL::ExceptionOr<Navigable::NavigationParamsVariant> create_navigation_params_by_fetching(GC::Ptr<SessionHistoryEntry> entry, GC::Ptr<Navigable> navigable, SourceSnapshotParams const& source_snapshot_params, TargetSnapshotParams const& target_snapshot_params, ContentSecurityPolicy::Directives::Directive::NavigationType csp_navigation_type, UserNavigationInvolvement user_involvement, Optional<String> navigation_id) static Navigable::NavigationParamsVariant create_navigation_params_by_fetching(GC::Ptr<SessionHistoryEntry> entry, GC::Ptr<Navigable> navigable, SourceSnapshotParams const& source_snapshot_params, TargetSnapshotParams const& target_snapshot_params, ContentSecurityPolicy::Directives::Directive::NavigationType csp_navigation_type, UserNavigationInvolvement user_involvement, Optional<String> navigation_id)
{ {
auto& vm = navigable->vm(); auto& vm = navigable->vm();
VERIFY(navigable->active_window()); VERIFY(navigable->active_window());
@ -892,7 +892,7 @@ static WebIDL::ExceptionOr<Navigable::NavigationParamsVariant> create_navigation
// 6. If documentResource is a POST resource: // 6. If documentResource is a POST resource:
if (auto* post_resource = document_resource.get_pointer<POSTResource>()) { if (auto* post_resource = document_resource.get_pointer<POSTResource>()) {
// 1. Set request's method to `POST`. // 1. Set request's method to `POST`.
request->set_method(TRY_OR_THROW_OOM(vm, ByteBuffer::copy("POST"sv.bytes()))); request->set_method(MUST(ByteBuffer::copy("POST"sv.bytes())));
// 2. Set request's body to documentResource's request body. // 2. Set request's body to documentResource's request body.
request->set_body(document_resource.get<POSTResource>().request_body.value()); request->set_body(document_resource.get<POSTResource>().request_body.value());
@ -1068,7 +1068,7 @@ static WebIDL::ExceptionOr<Navigable::NavigationParamsVariant> create_navigation
response_holder->set_response(fetch_response); response_holder->set_response(fetch_response);
}; };
fetch_controller = TRY(Fetch::Fetching::fetch( fetch_controller = Fetch::Fetching::fetch(
realm, realm,
request, request,
Fetch::Infrastructure::FetchAlgorithms::create(vm, Fetch::Infrastructure::FetchAlgorithms::create(vm,
@ -1080,7 +1080,7 @@ static WebIDL::ExceptionOr<Navigable::NavigationParamsVariant> create_navigation
.process_response_end_of_body = {}, .process_response_end_of_body = {},
.process_response_consume_body = {}, .process_response_consume_body = {},
}), }),
Fetch::Fetching::UseParallelQueue::Yes)); Fetch::Fetching::UseParallelQueue::Yes);
} }
// 6. Otherwise, process the next manual redirect for fetchController. // 6. Otherwise, process the next manual redirect for fetchController.
else { else {
@ -1213,7 +1213,7 @@ static WebIDL::ExceptionOr<Navigable::NavigationParamsVariant> create_navigation
if (response_holder->response()->is_network_error()) { if (response_holder->response()->is_network_error()) {
// AD-HOC: We pass the error message if we have one in NullWithError // AD-HOC: We pass the error message if we have one in NullWithError
if (response_holder->response()->network_error_message().has_value()) if (response_holder->response()->network_error_message().has_value())
return response_holder->response()->network_error_message().value(); return response_holder->response()->network_error_message();
else else
return Navigable::NullOrError {}; return Navigable::NullOrError {};
} else if (location_url.is_error() || (location_url.value().has_value() && Fetch::Infrastructure::is_fetch_scheme(location_url.value().value().scheme()))) } else if (location_url.is_error() || (location_url.value().has_value() && Fetch::Infrastructure::is_fetch_scheme(location_url.value().value().scheme())))
@ -1271,7 +1271,7 @@ static WebIDL::ExceptionOr<Navigable::NavigationParamsVariant> create_navigation
} }
// https://html.spec.whatwg.org/multipage/browsing-the-web.html#populating-a-session-history-entry // https://html.spec.whatwg.org/multipage/browsing-the-web.html#populating-a-session-history-entry
WebIDL::ExceptionOr<void> Navigable::populate_session_history_entry_document( void Navigable::populate_session_history_entry_document(
GC::Ptr<SessionHistoryEntry> entry, GC::Ptr<SessionHistoryEntry> entry,
SourceSnapshotParams const& source_snapshot_params, SourceSnapshotParams const& source_snapshot_params,
TargetSnapshotParams const& target_snapshot_params, TargetSnapshotParams const& target_snapshot_params,
@ -1284,7 +1284,7 @@ WebIDL::ExceptionOr<void> Navigable::populate_session_history_entry_document(
{ {
// AD-HOC: Not in the spec but subsequent steps will fail if the navigable doesn't have an active window. // AD-HOC: Not in the spec but subsequent steps will fail if the navigable doesn't have an active window.
if (!active_window()) if (!active_window())
return {}; return;
// FIXME: 1. Assert: this is running in parallel. // FIXME: 1. Assert: this is running in parallel.
@ -1311,7 +1311,7 @@ WebIDL::ExceptionOr<void> Navigable::populate_session_history_entry_document(
// sourceSnapshotParams, targetSnapshotParams, cspNavigationType, userInvolvement, navigationId, and // sourceSnapshotParams, targetSnapshotParams, cspNavigationType, userInvolvement, navigationId, and
// navTimingType. // navTimingType.
else if (Fetch::Infrastructure::is_fetch_scheme(entry->url().scheme()) && (document_resource.has<Empty>() || allow_POST)) { else if (Fetch::Infrastructure::is_fetch_scheme(entry->url().scheme()) && (document_resource.has<Empty>() || allow_POST)) {
navigation_params = TRY(create_navigation_params_by_fetching(entry, this, source_snapshot_params, target_snapshot_params, csp_navigation_type, user_involvement, navigation_id)); navigation_params = create_navigation_params_by_fetching(entry, this, source_snapshot_params, target_snapshot_params, csp_navigation_type, user_involvement, navigation_id);
} }
// 3. Otherwise, if entry's URL's scheme is not a fetch scheme, then set navigationParams to a new non-fetch // 3. Otherwise, if entry's URL's scheme is not a fetch scheme, then set navigationParams to a new non-fetch
// scheme navigation params, with: // scheme navigation params, with:
@ -1337,7 +1337,7 @@ WebIDL::ExceptionOr<void> Navigable::populate_session_history_entry_document(
// AD-HOC: Not in the spec but subsequent steps will fail if the navigable doesn't have an active window. // AD-HOC: Not in the spec but subsequent steps will fail if the navigable doesn't have an active window.
if (!active_window()) if (!active_window())
return {}; return;
// 5. Queue a global task on the navigation and traversal task source, given navigable's active window, to run these steps: // 5. Queue a global task on the navigation and traversal task source, given navigable's active window, to run these steps:
queue_global_task(Task::Source::NavigationAndTraversal, *active_window(), GC::create_function(heap(), [this, entry, navigation_params = move(navigation_params), navigation_id, user_involvement, completion_steps, csp_navigation_type]() mutable { queue_global_task(Task::Source::NavigationAndTraversal, *active_window(), GC::create_function(heap(), [this, entry, navigation_params = move(navigation_params), navigation_id, user_involvement, completion_steps, csp_navigation_type]() mutable {
@ -1474,8 +1474,6 @@ WebIDL::ExceptionOr<void> Navigable::populate_session_history_entry_document(
if (completion_steps) if (completion_steps)
completion_steps->function()(); completion_steps->function()();
})); }));
return {};
} }
WebIDL::ExceptionOr<void> Navigable::navigate(NavigateParams params) WebIDL::ExceptionOr<void> Navigable::navigate(NavigateParams params)
@ -1837,7 +1835,7 @@ void Navigable::begin_navigation(NavigateParams params)
} }
finalize_a_cross_document_navigation(*this, to_history_handling_behavior(history_handling), user_involvement, history_entry); finalize_a_cross_document_navigation(*this, to_history_handling_behavior(history_handling), user_involvement, history_entry);
})); }));
})).release_value_but_fixme_should_propagate_errors(); }));
})); }));
} }

View file

@ -118,7 +118,7 @@ public:
Variant<Empty, Traversal, String> ongoing_navigation() const { return m_ongoing_navigation; } Variant<Empty, Traversal, String> ongoing_navigation() const { return m_ongoing_navigation; }
void set_ongoing_navigation(Variant<Empty, Traversal, String> ongoing_navigation); void set_ongoing_navigation(Variant<Empty, Traversal, String> ongoing_navigation);
WebIDL::ExceptionOr<void> populate_session_history_entry_document( void populate_session_history_entry_document(
GC::Ptr<SessionHistoryEntry> entry, GC::Ptr<SessionHistoryEntry> entry,
SourceSnapshotParams const& source_snapshot_params, SourceSnapshotParams const& source_snapshot_params,
TargetSnapshotParams const& target_snapshot_params, TargetSnapshotParams const& target_snapshot_params,

View file

@ -325,7 +325,7 @@ String resolve_a_module_integrity_metadata(URL::URL const& url, EnvironmentSetti
} }
// https://html.spec.whatwg.org/multipage/webappapis.html#fetch-a-classic-script // https://html.spec.whatwg.org/multipage/webappapis.html#fetch-a-classic-script
WebIDL::ExceptionOr<void> fetch_classic_script(GC::Ref<HTMLScriptElement> element, URL::URL const& url, EnvironmentSettingsObject& settings_object, ScriptFetchOptions options, CORSSettingAttribute cors_setting, String character_encoding, OnFetchScriptComplete on_complete) void fetch_classic_script(GC::Ref<HTMLScriptElement> element, URL::URL const& url, EnvironmentSettingsObject& settings_object, ScriptFetchOptions options, CORSSettingAttribute cors_setting, String character_encoding, OnFetchScriptComplete on_complete)
{ {
auto& realm = element->realm(); auto& realm = element->realm();
auto& vm = realm.vm(); auto& vm = realm.vm();
@ -385,8 +385,7 @@ WebIDL::ExceptionOr<void> fetch_classic_script(GC::Ref<HTMLScriptElement> elemen
on_complete->function()(script); on_complete->function()(script);
}; };
TRY(Fetch::Fetching::fetch(element->realm(), request, Fetch::Infrastructure::FetchAlgorithms::create(vm, move(fetch_algorithms_input)))); Fetch::Fetching::fetch(element->realm(), request, Fetch::Infrastructure::FetchAlgorithms::create(vm, move(fetch_algorithms_input)));
return {};
} }
// https://html.spec.whatwg.org/multipage/webappapis.html#fetch-a-classic-worker-script // https://html.spec.whatwg.org/multipage/webappapis.html#fetch-a-classic-worker-script
@ -464,7 +463,7 @@ WebIDL::ExceptionOr<void> fetch_classic_worker_script(URL::URL const& url, Envir
else { else {
Fetch::Infrastructure::FetchAlgorithms::Input fetch_algorithms_input {}; Fetch::Infrastructure::FetchAlgorithms::Input fetch_algorithms_input {};
fetch_algorithms_input.process_response_consume_body = move(process_response_consume_body); fetch_algorithms_input.process_response_consume_body = move(process_response_consume_body);
TRY(Fetch::Fetching::fetch(realm, request, Fetch::Infrastructure::FetchAlgorithms::create(vm, move(fetch_algorithms_input)))); Fetch::Fetching::fetch(realm, request, Fetch::Infrastructure::FetchAlgorithms::create(vm, move(fetch_algorithms_input)));
} }
return {}; return {};
} }
@ -507,7 +506,7 @@ WebIDL::ExceptionOr<GC::Ref<ClassicScript>> fetch_a_classic_worker_imported_scri
else { else {
Fetch::Infrastructure::FetchAlgorithms::Input fetch_algorithms_input {}; Fetch::Infrastructure::FetchAlgorithms::Input fetch_algorithms_input {};
fetch_algorithms_input.process_response_consume_body = move(process_response_consume_body); fetch_algorithms_input.process_response_consume_body = move(process_response_consume_body);
TRY(Fetch::Fetching::fetch(realm, request, Fetch::Infrastructure::FetchAlgorithms::create(vm, move(fetch_algorithms_input)))); Fetch::Fetching::fetch(realm, request, Fetch::Infrastructure::FetchAlgorithms::create(vm, move(fetch_algorithms_input)));
} }
// 5. Pause until response is not null. // 5. Pause until response is not null.
@ -728,7 +727,7 @@ void fetch_single_module_script(JS::Realm& realm,
} else { } else {
Fetch::Infrastructure::FetchAlgorithms::Input fetch_algorithms_input {}; Fetch::Infrastructure::FetchAlgorithms::Input fetch_algorithms_input {};
fetch_algorithms_input.process_response_consume_body = move(process_response_consume_body); fetch_algorithms_input.process_response_consume_body = move(process_response_consume_body);
Fetch::Fetching::fetch(realm, request, Fetch::Infrastructure::FetchAlgorithms::create(realm.vm(), move(fetch_algorithms_input))).release_value_but_fixme_should_propagate_errors(); Fetch::Fetching::fetch(realm, request, Fetch::Infrastructure::FetchAlgorithms::create(realm.vm(), move(fetch_algorithms_input)));
} }
} }

View file

@ -89,7 +89,7 @@ WebIDL::ExceptionOr<Optional<URL::URL>> resolve_imports_match(ByteString const&
Optional<URL::URL> resolve_url_like_module_specifier(StringView specifier, URL::URL const& base_url); Optional<URL::URL> resolve_url_like_module_specifier(StringView specifier, URL::URL const& base_url);
ScriptFetchOptions get_descendant_script_fetch_options(ScriptFetchOptions const& original_options, URL::URL const& url, EnvironmentSettingsObject& settings_object); ScriptFetchOptions get_descendant_script_fetch_options(ScriptFetchOptions const& original_options, URL::URL const& url, EnvironmentSettingsObject& settings_object);
String resolve_a_module_integrity_metadata(URL::URL const& url, EnvironmentSettingsObject& settings_object); String resolve_a_module_integrity_metadata(URL::URL const& url, EnvironmentSettingsObject& settings_object);
WebIDL::ExceptionOr<void> fetch_classic_script(GC::Ref<HTMLScriptElement>, URL::URL const&, EnvironmentSettingsObject& settings_object, ScriptFetchOptions options, CORSSettingAttribute cors_setting, String character_encoding, OnFetchScriptComplete on_complete); void fetch_classic_script(GC::Ref<HTMLScriptElement>, URL::URL const&, EnvironmentSettingsObject& settings_object, ScriptFetchOptions options, CORSSettingAttribute cors_setting, String character_encoding, OnFetchScriptComplete on_complete);
WEB_API WebIDL::ExceptionOr<void> fetch_classic_worker_script(URL::URL const&, EnvironmentSettingsObject& fetch_client, Fetch::Infrastructure::Request::Destination, EnvironmentSettingsObject& settings_object, PerformTheFetchHook, OnFetchScriptComplete); WEB_API WebIDL::ExceptionOr<void> fetch_classic_worker_script(URL::URL const&, EnvironmentSettingsObject& fetch_client, Fetch::Infrastructure::Request::Destination, EnvironmentSettingsObject& settings_object, PerformTheFetchHook, OnFetchScriptComplete);
WebIDL::ExceptionOr<GC::Ref<ClassicScript>> fetch_a_classic_worker_imported_script(URL::URL const&, HTML::EnvironmentSettingsObject&, PerformTheFetchHook = nullptr); WebIDL::ExceptionOr<GC::Ref<ClassicScript>> fetch_a_classic_worker_imported_script(URL::URL const&, HTML::EnvironmentSettingsObject&, PerformTheFetchHook = nullptr);
WEB_API WebIDL::ExceptionOr<void> fetch_module_worker_script_graph(URL::URL const&, EnvironmentSettingsObject& fetch_client, Fetch::Infrastructure::Request::Destination, EnvironmentSettingsObject& settings_object, PerformTheFetchHook, OnFetchScriptComplete); WEB_API WebIDL::ExceptionOr<void> fetch_module_worker_script_graph(URL::URL const&, EnvironmentSettingsObject& fetch_client, Fetch::Infrastructure::Request::Destination, EnvironmentSettingsObject& settings_object, PerformTheFetchHook, OnFetchScriptComplete);

View file

@ -109,8 +109,7 @@ void SharedResourceRequest::fetch_resource(JS::Realm& realm, GC::Ref<Fetch::Infr
auto fetch_controller = Fetch::Fetching::fetch( auto fetch_controller = Fetch::Fetching::fetch(
realm, realm,
request, request,
Fetch::Infrastructure::FetchAlgorithms::create(realm.vm(), move(fetch_algorithms_input))) Fetch::Infrastructure::FetchAlgorithms::create(realm.vm(), move(fetch_algorithms_input)));
.release_value_but_fixme_should_propagate_errors();
set_fetch_controller(fetch_controller); set_fetch_controller(fetch_controller);
} }

View file

@ -652,12 +652,11 @@ TraversableNavigable::HistoryStepResult TraversableNavigable::apply_the_history_
// run afterDocumentPopulated. // run afterDocumentPopulated.
Platform::EventLoopPlugin::the().deferred_invoke(GC::create_function(this->heap(), [populated_target_entry, potentially_target_specific_source_snapshot_params, target_snapshot_params, this, allow_POST, navigable, after_document_populated = GC::create_function(this->heap(), move(after_document_populated)), user_involvement] { Platform::EventLoopPlugin::the().deferred_invoke(GC::create_function(this->heap(), [populated_target_entry, potentially_target_specific_source_snapshot_params, target_snapshot_params, this, allow_POST, navigable, after_document_populated = GC::create_function(this->heap(), move(after_document_populated)), user_involvement] {
navigable->populate_session_history_entry_document(populated_target_entry, *potentially_target_specific_source_snapshot_params, target_snapshot_params, user_involvement, {}, Navigable::NullOrError {}, ContentSecurityPolicy::Directives::Directive::NavigationType::Other, allow_POST, GC::create_function(this->heap(), [this, after_document_populated, populated_target_entry]() mutable { navigable->populate_session_history_entry_document(populated_target_entry, *potentially_target_specific_source_snapshot_params, target_snapshot_params, user_involvement, {}, Navigable::NullOrError {}, ContentSecurityPolicy::Directives::Directive::NavigationType::Other, allow_POST, GC::create_function(this->heap(), [this, after_document_populated, populated_target_entry]() mutable {
VERIFY(active_window()); VERIFY(active_window());
queue_global_task(Task::Source::NavigationAndTraversal, *active_window(), GC::create_function(this->heap(), [after_document_populated, populated_target_entry]() mutable { queue_global_task(Task::Source::NavigationAndTraversal, *active_window(), GC::create_function(this->heap(), [after_document_populated, populated_target_entry]() mutable {
after_document_populated->function()(true, populated_target_entry); after_document_populated->function()(true, populated_target_entry);
})); }));
})) }));
.release_value_but_fixme_should_propagate_errors();
})); }));
} }
// Otherwise, run afterDocumentPopulated immediately. // Otherwise, run afterDocumentPopulated immediately.

View file

@ -141,7 +141,7 @@ void SVGScriptElement::process_the_script_element()
response->body()->fully_read(realm, on_data_read, on_error, GC::Ref { global }); response->body()->fully_read(realm, on_data_read, on_error, GC::Ref { global });
}; };
auto fetch_promise = Fetch::Fetching::fetch(realm(), request, Fetch::Infrastructure::FetchAlgorithms::create(vm, move(fetch_algorithms_input))); (void)Fetch::Fetching::fetch(realm(), request, Fetch::Infrastructure::FetchAlgorithms::create(vm, move(fetch_algorithms_input)));
// Block until the resource has been fetched or determined invalid // Block until the resource has been fetched or determined invalid
HTML::main_thread_event_loop().spin_until(GC::create_function(heap(), [&] { return fetch_done; })); HTML::main_thread_event_loop().spin_until(GC::create_function(heap(), [&] { return fetch_done; }));

View file

@ -237,7 +237,7 @@ static void update(JS::VM& vm, GC::Ref<Job> job)
// 4. If the isTopLevel flag is unset, then return the result of fetching request. // 4. If the isTopLevel flag is unset, then return the result of fetching request.
// FIXME: Needs spec issue, this wording is confusing and contradicts the way perform the fetch hook is used in `run a worker` // FIXME: Needs spec issue, this wording is confusing and contradicts the way perform the fetch hook is used in `run a worker`
if (top_level == HTML::TopLevelModule::No) { if (top_level == HTML::TopLevelModule::No) {
TRY(Web::Fetch::Fetching::fetch(realm, request, Web::Fetch::Infrastructure::FetchAlgorithms::create(vm, move(fetch_algorithms_input)))); Web::Fetch::Fetching::fetch(realm, request, Web::Fetch::Infrastructure::FetchAlgorithms::create(vm, move(fetch_algorithms_input)));
return {}; return {};
} }
@ -376,7 +376,7 @@ static void update(JS::VM& vm, GC::Ref<Job> job)
process_response_completion_result = WebIDL::ExceptionOr<void> {}; process_response_completion_result = WebIDL::ExceptionOr<void> {};
}; };
auto fetch_controller = TRY(Web::Fetch::Fetching::fetch(realm, request, Web::Fetch::Infrastructure::FetchAlgorithms::create(vm, move(fetch_algorithms_input)))); auto fetch_controller = Web::Fetch::Fetching::fetch(realm, request, Web::Fetch::Infrastructure::FetchAlgorithms::create(vm, move(fetch_algorithms_input)));
// FIXME: This feels.. uncomfortable but it should work to block the current task until the fetch has progressed past our processResponse hook or aborted // FIXME: This feels.. uncomfortable but it should work to block the current task until the fetch has progressed past our processResponse hook or aborted
auto& event_loop = job->client ? job->client->responsible_event_loop() : HTML::main_thread_event_loop(); auto& event_loop = job->client ? job->client->responsible_event_loop() : HTML::main_thread_event_loop();
@ -455,6 +455,7 @@ static void update(JS::VM& vm, GC::Ref<Job> job)
// FIXME: Credentials mode // FIXME: Credentials mode
// FIXME: Use a 'stub' service worker ESO as the fetch "environment" // FIXME: Use a 'stub' service worker ESO as the fetch "environment"
(void)HTML::fetch_module_worker_script_graph(job->script_url, *job->client, Fetch::Infrastructure::Request::Destination::ServiceWorker, *job->client, perform_the_fetch_hook, on_fetch_complete); (void)HTML::fetch_module_worker_script_graph(job->script_url, *job->client, Fetch::Infrastructure::Request::Destination::ServiceWorker, *job->client, perform_the_fetch_hook, on_fetch_complete);
break;
} }
} }

View file

@ -849,7 +849,7 @@ WebIDL::ExceptionOr<void> XMLHttpRequest::send(Optional<DocumentOrXMLHttpRequest
}; };
// 10. Set thiss fetch controller to the result of fetching req with processRequestBodyChunkLength set to processRequestBodyChunkLength, processRequestEndOfBody set to processRequestEndOfBody, and processResponse set to processResponse. // 10. Set thiss fetch controller to the result of fetching req with processRequestBodyChunkLength set to processRequestBodyChunkLength, processRequestEndOfBody set to processRequestEndOfBody, and processResponse set to processResponse.
m_fetch_controller = TRY(Fetch::Fetching::fetch( m_fetch_controller = Fetch::Fetching::fetch(
realm, realm,
request, request,
Fetch::Infrastructure::FetchAlgorithms::create(vm, Fetch::Infrastructure::FetchAlgorithms::create(vm,
@ -860,7 +860,7 @@ WebIDL::ExceptionOr<void> XMLHttpRequest::send(Optional<DocumentOrXMLHttpRequest
.process_response = move(process_response), .process_response = move(process_response),
.process_response_end_of_body = {}, .process_response_end_of_body = {},
.process_response_consume_body = {}, .process_response_consume_body = {},
}))); }));
// 11. Let now be the present time. // 11. Let now be the present time.
// 12. Run these steps in parallel: // 12. Run these steps in parallel:
@ -905,7 +905,7 @@ WebIDL::ExceptionOr<void> XMLHttpRequest::send(Optional<DocumentOrXMLHttpRequest
}; };
// 3. Set thiss fetch controller to the result of fetching req with processResponseConsumeBody set to processResponseConsumeBody and useParallelQueue set to true. // 3. Set thiss fetch controller to the result of fetching req with processResponseConsumeBody set to processResponseConsumeBody and useParallelQueue set to true.
m_fetch_controller = TRY(Fetch::Fetching::fetch( m_fetch_controller = Fetch::Fetching::fetch(
realm, realm,
request, request,
Fetch::Infrastructure::FetchAlgorithms::create(vm, Fetch::Infrastructure::FetchAlgorithms::create(vm,
@ -917,7 +917,7 @@ WebIDL::ExceptionOr<void> XMLHttpRequest::send(Optional<DocumentOrXMLHttpRequest
.process_response_end_of_body = {}, .process_response_end_of_body = {},
.process_response_consume_body = move(process_response_consume_body), .process_response_consume_body = move(process_response_consume_body),
}), }),
Fetch::Fetching::UseParallelQueue::Yes)); Fetch::Fetching::UseParallelQueue::Yes);
// 4. Let now be the present time. // 4. Let now be the present time.
// 5. Pause until either processedResponse is true or thiss timeout is not 0 and thiss timeout milliseconds have passed since now. // 5. Pause until either processedResponse is true or thiss timeout is not 0 and thiss timeout milliseconds have passed since now.

View file

@ -105,7 +105,7 @@ void WorkerHost::run(GC::Ref<Web::Page> page, Web::HTML::TransferDataEncoder mes
// 1. If isTopLevel is false, fetch request with processResponseConsumeBody set to processCustomFetchResponse, and abort these steps. // 1. If isTopLevel is false, fetch request with processResponseConsumeBody set to processCustomFetchResponse, and abort these steps.
if (is_top_level == Web::HTML::TopLevelModule::No) { if (is_top_level == Web::HTML::TopLevelModule::No) {
fetch_algorithms_input.process_response_consume_body = move(process_custom_fetch_response); fetch_algorithms_input.process_response_consume_body = move(process_custom_fetch_response);
TRY(Web::Fetch::Fetching::fetch(realm, request, Web::Fetch::Infrastructure::FetchAlgorithms::create(vm, move(fetch_algorithms_input)))); Web::Fetch::Fetching::fetch(realm, request, Web::Fetch::Infrastructure::FetchAlgorithms::create(vm, move(fetch_algorithms_input)));
return {}; return {};
} }
@ -150,7 +150,7 @@ void WorkerHost::run(GC::Ref<Web::Page> page, Web::HTML::TransferDataEncoder mes
// 9. Run processCustomFetchResponse with response and bodyBytes. // 9. Run processCustomFetchResponse with response and bodyBytes.
process_custom_fetch_response_function->function()(response, body_bytes); process_custom_fetch_response_function->function()(response, body_bytes);
}; };
TRY(Web::Fetch::Fetching::fetch(realm, request, Web::Fetch::Infrastructure::FetchAlgorithms::create(vm, move(fetch_algorithms_input)))); Web::Fetch::Fetching::fetch(realm, request, Web::Fetch::Infrastructure::FetchAlgorithms::create(vm, move(fetch_algorithms_input)));
return {}; return {};
}; };
auto perform_fetch = Web::HTML::create_perform_the_fetch_hook(inside_settings->heap(), move(perform_fetch_function)); auto perform_fetch = Web::HTML::create_perform_the_fetch_hook(inside_settings->heap(), move(perform_fetch_function));