mirror of
https://github.com/RGBCube/serenity
synced 2025-06-01 11:48:13 +00:00
LibWeb: Parse header value lists for some CORS headers
This adds a simple and incomplete implementation for extracting some specific CORS headers that are used by fetch. This unifies the existing ad-hoc parsing that already existed for Access-Control-Allow-Headers and Access-Control-Allow-Methods, as well as adding Access-control-Expose-Headers.
This commit is contained in:
parent
3a1f510af0
commit
2ce416a676
2 changed files with 20 additions and 32 deletions
|
@ -1812,38 +1812,6 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<PendingResponse>> cors_preflight_fetch(JS::
|
||||||
// NOTE: We treat "header_names_or_failure" being `Empty` as empty Vector here.
|
// 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.has<Vector<ByteBuffer>>() ? header_names_or_failure.get<Vector<ByteBuffer>>() : Vector<ByteBuffer> {};
|
||||||
|
|
||||||
// FIXME: Remove this once extract_header_list_values validates the header and returns multiple values.
|
|
||||||
if (!methods.is_empty()) {
|
|
||||||
VERIFY(methods.size() == 1);
|
|
||||||
|
|
||||||
auto split_methods = StringView { methods.first() }.split_view(',');
|
|
||||||
Vector<ByteBuffer> trimmed_methods;
|
|
||||||
|
|
||||||
for (auto const& method : split_methods) {
|
|
||||||
auto trimmed_method = method.trim(" \t"sv);
|
|
||||||
auto trimmed_method_as_byte_buffer = TRY_OR_IGNORE(ByteBuffer::copy(trimmed_method.bytes()));
|
|
||||||
TRY_OR_IGNORE(trimmed_methods.try_append(move(trimmed_method_as_byte_buffer)));
|
|
||||||
}
|
|
||||||
|
|
||||||
methods = move(trimmed_methods);
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME: Remove this once extract_header_list_values validates the header and returns multiple values.
|
|
||||||
if (!header_names.is_empty()) {
|
|
||||||
VERIFY(header_names.size() == 1);
|
|
||||||
|
|
||||||
auto split_header_names = StringView { header_names.first() }.split_view(',');
|
|
||||||
Vector<ByteBuffer> trimmed_header_names;
|
|
||||||
|
|
||||||
for (auto const& header_name : split_header_names) {
|
|
||||||
auto trimmed_header_name = header_name.trim(" \t"sv);
|
|
||||||
auto trimmed_header_name_as_byte_buffer = TRY_OR_IGNORE(ByteBuffer::copy(trimmed_header_name.bytes()));
|
|
||||||
TRY_OR_IGNORE(trimmed_header_names.try_append(move(trimmed_header_name_as_byte_buffer)));
|
|
||||||
}
|
|
||||||
|
|
||||||
header_names = move(trimmed_header_names);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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.
|
// 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.
|
// NOTE: This ensures that a CORS-preflight fetch that happened due to request’s use-CORS-preflight flag being set is cached.
|
||||||
if (methods.is_empty() && request.use_cors_preflight())
|
if (methods.is_empty() && request.use_cors_preflight())
|
||||||
|
|
|
@ -776,6 +776,26 @@ ErrorOr<Optional<Vector<ByteBuffer>>> extract_header_values(Header const& header
|
||||||
{
|
{
|
||||||
// FIXME: 1. If parsing header’s value, per the ABNF for header’s name, fails, then return failure.
|
// FIXME: 1. If parsing header’s value, per the ABNF for header’s name, fails, then return failure.
|
||||||
// FIXME: 2. Return one or more values resulting from parsing header’s value, per the ABNF for header’s name.
|
// FIXME: 2. Return one or more values resulting from parsing header’s value, per the ABNF for header’s name.
|
||||||
|
|
||||||
|
// For now we only parse some headers that are of the ABNF list form "#something"
|
||||||
|
if (StringView { header.name }.is_one_of_ignoring_ascii_case(
|
||||||
|
"Access-Control-Request-Headers"sv,
|
||||||
|
"Access-Control-Expose-Headers"sv,
|
||||||
|
"Access-Control-Allow-Headers"sv,
|
||||||
|
"Access-Control-Allow-Methods"sv)
|
||||||
|
&& !header.value.is_empty()) {
|
||||||
|
auto split_values = StringView { header.value }.split_view(',');
|
||||||
|
Vector<ByteBuffer> trimmed_values;
|
||||||
|
|
||||||
|
for (auto const& value : split_values) {
|
||||||
|
auto trimmed_value = value.trim(" \t"sv);
|
||||||
|
auto trimmed_value_as_byte_buffer = TRY(ByteBuffer::copy(trimmed_value.bytes()));
|
||||||
|
TRY(trimmed_values.try_append(move(trimmed_value_as_byte_buffer)));
|
||||||
|
}
|
||||||
|
|
||||||
|
return trimmed_values;
|
||||||
|
}
|
||||||
|
|
||||||
// This always ignores the ABNF rules for now and returns the header value as a single list item.
|
// This always ignores the ABNF rules for now and returns the header value as a single list item.
|
||||||
return Vector { TRY(ByteBuffer::copy(header.value)) };
|
return Vector { TRY(ByteBuffer::copy(header.value)) };
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue