mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-12-07 21:59:54 +00:00
LibWeb: Do not copy the result of HeaderList::extract_header_list_values
There's no need to copy the Vector out of this result every time we call it. We can move it out or access it directly.
This commit is contained in:
parent
44fbf6451e
commit
ed27eea091
Notes:
github-actions[bot]
2025-11-26 14:16:24 +00:00
Author: https://github.com/trflynn89
Commit: ed27eea091
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/6933
4 changed files with 45 additions and 39 deletions
|
|
@ -102,28 +102,30 @@ GC::Ref<PolicyList> Policy::parse_a_responses_content_security_policies(GC::Heap
|
|||
// 2. For each token returned by extracting header list values given Content-Security-Policy and response’s header
|
||||
// list:
|
||||
auto enforce_policy_tokens_or_failure = response->header_list()->extract_header_list_values("Content-Security-Policy"sv.bytes());
|
||||
auto enforce_policy_tokens = enforce_policy_tokens_or_failure.has<Vector<ByteBuffer>>() ? enforce_policy_tokens_or_failure.get<Vector<ByteBuffer>>() : Vector<ByteBuffer> {};
|
||||
for (auto const& enforce_policy_token : enforce_policy_tokens) {
|
||||
// 1. Let policy be the result of parsing token, with a source of "header", and a disposition of "enforce".
|
||||
auto policy = parse_a_serialized_csp(heap, enforce_policy_token, Policy::Source::Header, Policy::Disposition::Enforce);
|
||||
|
||||
// 2. If policy’s directive set is not empty, append policy to policies.
|
||||
if (!policy->m_directives.is_empty()) {
|
||||
policies.append(policy);
|
||||
if (auto const* enforce_policy_tokens = enforce_policy_tokens_or_failure.get_pointer<Vector<ByteBuffer>>()) {
|
||||
for (auto const& enforce_policy_token : *enforce_policy_tokens) {
|
||||
// 1. Let policy be the result of parsing token, with a source of "header", and a disposition of "enforce".
|
||||
auto policy = parse_a_serialized_csp(heap, enforce_policy_token, Policy::Source::Header, Policy::Disposition::Enforce);
|
||||
|
||||
// 2. If policy’s directive set is not empty, append policy to policies.
|
||||
if (!policy->m_directives.is_empty())
|
||||
policies.append(policy);
|
||||
}
|
||||
}
|
||||
|
||||
// 3. For each token returned by extracting header list values given Content-Security-Policy-Report-Only and
|
||||
// response’s header list:
|
||||
auto report_policy_tokens_or_failure = response->header_list()->extract_header_list_values("Content-Security-Policy-Report-Only"sv.bytes());
|
||||
auto report_policy_tokens = report_policy_tokens_or_failure.has<Vector<ByteBuffer>>() ? report_policy_tokens_or_failure.get<Vector<ByteBuffer>>() : Vector<ByteBuffer> {};
|
||||
for (auto const& report_policy_token : report_policy_tokens) {
|
||||
// 1. Let policy be the result of parsing token, with a source of "header", and a disposition of "report".
|
||||
auto policy = parse_a_serialized_csp(heap, report_policy_token, Policy::Source::Header, Policy::Disposition::Report);
|
||||
|
||||
// 2. If policy’s directive set is not empty, append policy to policies.
|
||||
if (!policy->m_directives.is_empty()) {
|
||||
policies.append(policy);
|
||||
if (auto const* report_policy_tokens = enforce_policy_tokens_or_failure.get_pointer<Vector<ByteBuffer>>()) {
|
||||
for (auto const& report_policy_token : *report_policy_tokens) {
|
||||
// 1. Let policy be the result of parsing token, with a source of "header", and a disposition of "report".
|
||||
auto policy = parse_a_serialized_csp(heap, report_policy_token, Policy::Source::Header, Policy::Disposition::Report);
|
||||
|
||||
// 2. If policy’s directive set is not empty, append policy to policies.
|
||||
if (!policy->m_directives.is_empty())
|
||||
policies.append(policy);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -496,19 +496,20 @@ GC::Ptr<PendingResponse> main_fetch(JS::Realm& realm, Infrastructure::FetchParam
|
|||
// 1. Let headerNames be the result of extracting header list values given
|
||||
// `Access-Control-Expose-Headers` and response’s header list.
|
||||
auto header_names_or_failure = response->header_list()->extract_header_list_values("Access-Control-Expose-Headers"sv.bytes());
|
||||
auto header_names = header_names_or_failure.has<Vector<ByteBuffer>>() ? header_names_or_failure.get<Vector<ByteBuffer>>() : Vector<ByteBuffer> {};
|
||||
|
||||
// 2. If request’s credentials mode is not "include" and headerNames contains `*`, then set
|
||||
// response’s CORS-exposed header-name list to all unique header names in response’s header
|
||||
// list.
|
||||
if (request->credentials_mode() != Infrastructure::Request::CredentialsMode::Include && header_names.contains_slow("*"sv.bytes())) {
|
||||
auto unique_header_names = response->header_list()->unique_names();
|
||||
response->set_cors_exposed_header_name_list(move(unique_header_names));
|
||||
}
|
||||
// 3. Otherwise, if headerNames is not null or failure, then set response’s CORS-exposed
|
||||
// header-name list to headerNames.
|
||||
else if (!header_names.is_empty()) {
|
||||
response->set_cors_exposed_header_name_list(move(header_names));
|
||||
if (auto* header_names = header_names_or_failure.get_pointer<Vector<ByteBuffer>>()) {
|
||||
// 2. If request’s credentials mode is not "include" and headerNames contains `*`, then set
|
||||
// response’s CORS-exposed header-name list to all unique header names in response’s header
|
||||
// list.
|
||||
if (request->credentials_mode() != Infrastructure::Request::CredentialsMode::Include && header_names->contains_slow("*"sv.bytes())) {
|
||||
auto unique_header_names = response->header_list()->unique_names();
|
||||
response->set_cors_exposed_header_name_list(move(unique_header_names));
|
||||
}
|
||||
// 3. Otherwise, if headerNames is not null or failure, then set response’s CORS-exposed
|
||||
// header-name list to headerNames.
|
||||
else if (!header_names->is_empty()) {
|
||||
response->set_cors_exposed_header_name_list(move(*header_names));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2531,10 +2532,14 @@ GC::Ref<PendingResponse> cors_preflight_fetch(JS::Realm& realm, Infrastructure::
|
|||
}
|
||||
|
||||
// NOTE: We treat "methods_or_failure" being `Empty` as empty Vector here.
|
||||
auto methods = methods_or_failure.has<Vector<ByteBuffer>>() ? methods_or_failure.get<Vector<ByteBuffer>>() : Vector<ByteBuffer> {};
|
||||
auto methods = methods_or_failure.visit(
|
||||
[](Vector<ByteBuffer>& methods) { return move(methods); },
|
||||
[](auto) -> Vector<ByteBuffer> { return {}; });
|
||||
|
||||
// NOTE: We treat "header_names_or_failure" being `Empty` as empty Vector here.
|
||||
auto header_names = header_names_or_failure.has<Vector<ByteBuffer>>() ? header_names_or_failure.get<Vector<ByteBuffer>>() : Vector<ByteBuffer> {};
|
||||
auto header_names = header_names_or_failure.visit(
|
||||
[](Vector<ByteBuffer>& header_names) { return move(header_names); },
|
||||
[](auto) -> Vector<ByteBuffer> { return {}; });
|
||||
|
||||
// 4. If methods is null and request’s use-CORS-preflight flag is set, then set methods to a new list containing request’s method.
|
||||
// NOTE: This ensures that a CORS-preflight fetch that happened due to request’s use-CORS-preflight flag being set is cached.
|
||||
|
|
|
|||
|
|
@ -126,15 +126,13 @@ ErrorOr<Optional<URL::URL>> Response::location_url(Optional<String> const& reque
|
|||
|
||||
// 2. Let location be the result of extracting header list values given `Location` and response’s header list.
|
||||
auto location_values_or_failure = m_header_list->extract_header_list_values("Location"sv.bytes());
|
||||
if (location_values_or_failure.has<Infrastructure::HeaderList::ExtractHeaderParseFailure>() || location_values_or_failure.has<Empty>())
|
||||
return Optional<URL::URL> {};
|
||||
auto const* location_values = location_values_or_failure.get_pointer<Vector<ByteBuffer>>();
|
||||
|
||||
auto const& location_values = location_values_or_failure.get<Vector<ByteBuffer>>();
|
||||
if (location_values.size() != 1)
|
||||
return Optional<URL::URL> {};
|
||||
if (!location_values || location_values->size() != 1)
|
||||
return OptionalNone {};
|
||||
|
||||
// 3. If location is a header value, then set location to the result of parsing location with response’s URL.
|
||||
auto location = DOMURL::parse(location_values.first(), url());
|
||||
auto location = DOMURL::parse(location_values->first(), url());
|
||||
if (!location.has_value())
|
||||
return Error::from_string_literal("Invalid 'Location' header URL");
|
||||
|
||||
|
|
|
|||
|
|
@ -23,16 +23,17 @@ ReferrerPolicy parse_a_referrer_policy_from_a_referrer_policy_header(Fetch::Infr
|
|||
{
|
||||
// 1. Let policy-tokens be the result of extracting header list values given `Referrer-Policy` and response’s header list.
|
||||
auto policy_tokens_or_failure = response.header_list()->extract_header_list_values("Referrer-Policy"sv.bytes());
|
||||
auto policy_tokens = policy_tokens_or_failure.has<Vector<ByteBuffer>>() ? policy_tokens_or_failure.get<Vector<ByteBuffer>>() : Vector<ByteBuffer> {};
|
||||
|
||||
// 2. Let policy be the empty string.
|
||||
auto policy = ReferrerPolicy::EmptyString;
|
||||
|
||||
// 3. For each token in policy-tokens, if token is a referrer policy and token is not the empty string, then set policy to token.
|
||||
for (auto token : policy_tokens) {
|
||||
auto referrer_policy = from_string(token);
|
||||
if (referrer_policy.has_value() && referrer_policy.value() != ReferrerPolicy::EmptyString)
|
||||
policy = referrer_policy.release_value();
|
||||
if (auto const* policy_tokens = policy_tokens_or_failure.get_pointer<Vector<ByteBuffer>>()) {
|
||||
for (auto const& token : *policy_tokens) {
|
||||
auto referrer_policy = from_string(token);
|
||||
if (referrer_policy.has_value() && referrer_policy.value() != ReferrerPolicy::EmptyString)
|
||||
policy = referrer_policy.release_value();
|
||||
}
|
||||
}
|
||||
|
||||
// 4. Return policy.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue