mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 12:38:12 +00:00
LibWeb: Update workarounds for fetching CORS cross-origin responses
Now that the processResponseConsumeBody algorithm receives the internal response body of the fetched object, we do not need to go out of our way to read its body from outside of fetch. However, several elements do still need to manually inspect the internal response for other data, such as response headers and status. Note that HTMLScriptElement already does the new workaround as a proper spec step.
This commit is contained in:
parent
6406a561ef
commit
8ff8309202
4 changed files with 65 additions and 164 deletions
|
@ -279,72 +279,30 @@ void HTMLLinkElement::default_fetch_and_process_linked_resource()
|
|||
}
|
||||
|
||||
// 7. Fetch request with processResponseConsumeBody set to the following steps given response response and null, failure, or a byte sequence bodyBytes:
|
||||
Fetch::Fetching::fetch(
|
||||
realm(), *request,
|
||||
Fetch::Infrastructure::FetchAlgorithms::create(vm(),
|
||||
{ .process_request_body_chunk_length = {},
|
||||
.process_request_end_of_body = {},
|
||||
.process_early_hints_response = {},
|
||||
.process_response = {},
|
||||
.process_response_end_of_body = {},
|
||||
.process_response_consume_body = [this, hr = options](auto response, auto body_bytes) {
|
||||
// 1. Let success be true.
|
||||
bool success = true;
|
||||
Fetch::Infrastructure::FetchAlgorithms::Input fetch_algorithms_input {};
|
||||
fetch_algorithms_input.process_response_consume_body = [this, hr = options](auto response, auto body_bytes) {
|
||||
// FIXME: If the response is CORS cross-origin, we must use its internal response to query any of its data. See:
|
||||
// https://github.com/whatwg/html/issues/9355
|
||||
response = response->unsafe_response();
|
||||
|
||||
// 2. If either of the following conditions are met:
|
||||
// - bodyBytes is null or failure; or
|
||||
// - response's status is not an ok status,
|
||||
// then set success to false.
|
||||
// NOTE: content-specific errors, e.g., CSS parse errors or PNG decoding errors, do not affect success.
|
||||
if (body_bytes.template has<Empty>()) {
|
||||
// CORS cross-origin responses in the No CORS request mode provide an opaque filtered response, which is the original response
|
||||
// with certain attributes removed/changed.
|
||||
// 1. Let success be true.
|
||||
bool success = true;
|
||||
|
||||
// The relevant effect it has is setting the body to `null`, which means `body_bytes` has `Empty` here. This effectively
|
||||
// disables cross-origin linked resources (e.g. stylesheets).
|
||||
// 2. If either of the following conditions are met:
|
||||
// - bodyBytes is null or failure; or
|
||||
// - response's status is not an ok status,
|
||||
if (body_bytes.template has<Empty>() || body_bytes.template has<Fetch::Infrastructure::FetchAlgorithms::ConsumeBodyFailureTag>() || !Fetch::Infrastructure::is_ok_status(response->status())) {
|
||||
// then set success to false.
|
||||
success = false;
|
||||
}
|
||||
|
||||
// However, the web actually depends on this, especially for stylesheets retrieved from a cross-origin CDN. For example,
|
||||
// Shopify websites request stylesheets from `cdn.shopify.com` and Substack websites request stylesheets from `substackcdn.com`.
|
||||
// FIXME: 3. Otherwise, wait for the link resource's critical subresources to finish loading.
|
||||
|
||||
// This makes this a specification bug, as this code was written from it.
|
||||
// 4. Process the linked resource given el, success, response, and bodyBytes.
|
||||
process_linked_resource(success, response, body_bytes);
|
||||
};
|
||||
|
||||
// The workaround is to read the actual body from the unfiltered response and then call `process_linked_resource` from there.
|
||||
|
||||
// This _should_ be safe to do, as linked resource fetches do not include credentials (i.e. cookies and the Authorization
|
||||
// header), so it cannot provide personalized responses.
|
||||
|
||||
// FIXME: Replace this workaround with a proper fix that has landed in the specification.
|
||||
// See: https://github.com/whatwg/html/issues/9066
|
||||
if (is<Fetch::Infrastructure::OpaqueFilteredResponse>(response.ptr())) {
|
||||
auto unsafe_response = static_cast<Fetch::Infrastructure::OpaqueFilteredResponse const&>(*response).internal_response();
|
||||
if (unsafe_response->body().has_value()) {
|
||||
// NOTE: `this` and `unsafe_response` are protected by `fully_read` using JS::SafeFunction.
|
||||
auto process_body = [this, unsafe_response](ByteBuffer bytes) {
|
||||
process_linked_resource(true, unsafe_response, bytes);
|
||||
};
|
||||
|
||||
// NOTE: `this` and `unsafe_response` are protected by `fully_read` using JS::SafeFunction.
|
||||
auto process_body_error = [this, unsafe_response](auto) {
|
||||
process_linked_resource(false, unsafe_response, Fetch::Infrastructure::FetchAlgorithms::ConsumeBodyFailureTag {});
|
||||
};
|
||||
|
||||
unsafe_response->body()->fully_read(realm(), move(process_body), move(process_body_error), JS::NonnullGCPtr { realm().global_object() }).release_value_but_fixme_should_propagate_errors();
|
||||
return;
|
||||
} else {
|
||||
success = false;
|
||||
}
|
||||
} else {
|
||||
success = false;
|
||||
}
|
||||
} else if (body_bytes.template has<Fetch::Infrastructure::FetchAlgorithms::ConsumeBodyFailureTag>() || !Fetch::Infrastructure::is_ok_status(response->status())) {
|
||||
success = false;
|
||||
}
|
||||
// FIXME: 3. Otherwise, wait for the link resource's critical subresources to finish loading.
|
||||
|
||||
// 4. Process the linked resource given el, success, response, and bodyBytes.
|
||||
process_linked_resource(success, response, body_bytes);
|
||||
} }))
|
||||
.release_value_but_fixme_should_propagate_errors();
|
||||
Fetch::Fetching::fetch(realm(), *request, Fetch::Infrastructure::FetchAlgorithms::create(vm(), move(fetch_algorithms_input))).release_value_but_fixme_should_propagate_errors();
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/links.html#link-type-stylesheet:process-the-linked-resource
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue