mirror of
https://github.com/RGBCube/serenity
synced 2025-06-01 11:48:13 +00:00
LibWeb: Support for Access-Control-Expose-Headers in Fetch
This adds the headers named in Access-Control-Expose-Headers to the response's CORS-exposed header-name list which allows those headers to be accessed from JS.
This commit is contained in:
parent
15440b156f
commit
3a1f510af0
3 changed files with 36 additions and 7 deletions
|
@ -393,13 +393,23 @@ WebIDL::ExceptionOr<Optional<JS::NonnullGCPtr<PendingResponse>>> main_fetch(JS::
|
||||||
if (!response->is_network_error() && !is<Infrastructure::FilteredResponse>(*response)) {
|
if (!response->is_network_error() && !is<Infrastructure::FilteredResponse>(*response)) {
|
||||||
// 1. If request’s response tainting is "cors", then:
|
// 1. If request’s response tainting is "cors", then:
|
||||||
if (request->response_tainting() == Infrastructure::Request::ResponseTainting::CORS) {
|
if (request->response_tainting() == Infrastructure::Request::ResponseTainting::CORS) {
|
||||||
// FIXME: 1. Let headerNames be the result of extracting header list values given
|
// 1. Let headerNames be the result of extracting header list values given
|
||||||
// `Access-Control-Expose-Headers` and response’s header list.
|
// `Access-Control-Expose-Headers` and response’s header list.
|
||||||
// FIXME: 2. If request’s credentials mode is not "include" and headerNames contains `*`, then set
|
auto header_names_or_failure = TRY_OR_IGNORE(Infrastructure::extract_header_list_values("Access-Control-Expose-Headers"sv.bytes(), response->header_list()));
|
||||||
|
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
|
// response’s CORS-exposed header-name list to all unique header names in response’s header
|
||||||
// list.
|
// list.
|
||||||
// FIXME: 3. Otherwise, if headerNames is not null or failure, then set response’s CORS-exposed
|
if (request->credentials_mode() != Infrastructure::Request::CredentialsMode::Include && header_names.contains_slow("*"sv.bytes())) {
|
||||||
|
auto unique_header_names = TRY_OR_IGNORE(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.
|
// header-name list to headerNames.
|
||||||
|
else if (!header_names.is_empty()) {
|
||||||
|
response->set_cors_exposed_header_name_list(move(header_names));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. Set response to the following filtered response with response as its internal response, depending
|
// 2. Set response to the following filtered response with response as its internal response, depending
|
||||||
|
|
|
@ -53,6 +53,23 @@ JS::NonnullGCPtr<HeaderList> HeaderList::create(JS::VM& vm)
|
||||||
return vm.heap().allocate_without_realm<HeaderList>();
|
return vm.heap().allocate_without_realm<HeaderList>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Non-standard
|
||||||
|
ErrorOr<Vector<ByteBuffer>> HeaderList::unique_names() const
|
||||||
|
{
|
||||||
|
Vector<ByteBuffer> header_names_set;
|
||||||
|
HashTable<ReadonlyBytes, CaseInsensitiveBytesTraits<u8 const>> header_names_seen;
|
||||||
|
|
||||||
|
for (auto const& header : *this) {
|
||||||
|
if (header_names_seen.contains(header.name))
|
||||||
|
continue;
|
||||||
|
auto bytes = TRY(ByteBuffer::copy(header.name));
|
||||||
|
TRY(header_names_seen.try_set(header.name));
|
||||||
|
TRY(header_names_set.try_append(move(bytes)));
|
||||||
|
}
|
||||||
|
|
||||||
|
return header_names_set;
|
||||||
|
}
|
||||||
|
|
||||||
// https://fetch.spec.whatwg.org/#header-list-contains
|
// https://fetch.spec.whatwg.org/#header-list-contains
|
||||||
bool HeaderList::contains(ReadonlyBytes name) const
|
bool HeaderList::contains(ReadonlyBytes name) const
|
||||||
{
|
{
|
||||||
|
|
|
@ -61,6 +61,8 @@ public:
|
||||||
[[nodiscard]] ErrorOr<ExtractLengthResult> extract_length() const;
|
[[nodiscard]] ErrorOr<ExtractLengthResult> extract_length() const;
|
||||||
|
|
||||||
[[nodiscard]] ErrorOr<Optional<MimeSniff::MimeType>> extract_mime_type() const;
|
[[nodiscard]] ErrorOr<Optional<MimeSniff::MimeType>> extract_mime_type() const;
|
||||||
|
|
||||||
|
ErrorOr<Vector<ByteBuffer>> unique_names() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RangeHeaderValue {
|
struct RangeHeaderValue {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue