/* * Copyright (c) 2022-2023, Linus Groh * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #include #include #include #include #include #include #include #include #include #include namespace Web::Fetch::Infrastructure { // https://fetch.spec.whatwg.org/#concept-header // A header is a tuple that consists of a name (a header name) and value (a header value). struct Header { ByteBuffer name; ByteBuffer value; static ErrorOr
from_string_pair(StringView, StringView); }; // https://fetch.spec.whatwg.org/#concept-header-list // A header list is a list of zero or more headers. It is initially the empty list. class HeaderList final : public JS::Cell , Vector
{ JS_CELL(HeaderList, JS::Cell); public: using Vector::begin; using Vector::clear; using Vector::end; using Vector::is_empty; [[nodiscard]] static JS::NonnullGCPtr create(JS::VM&); [[nodiscard]] bool contains(ReadonlyBytes) const; [[nodiscard]] ErrorOr> get(ReadonlyBytes) const; [[nodiscard]] ErrorOr>> get_decode_and_split(ReadonlyBytes) const; [[nodiscard]] ErrorOr append(Header); void delete_(ReadonlyBytes name); [[nodiscard]] ErrorOr set(Header); [[nodiscard]] ErrorOr combine(Header); [[nodiscard]] ErrorOr> sort_and_combine() const; struct ExtractLengthFailure { }; using ExtractLengthResult = Variant; [[nodiscard]] ErrorOr extract_length() const; [[nodiscard]] ErrorOr> extract_mime_type() const; ErrorOr> unique_names() const; }; struct RangeHeaderValue { Optional start; Optional end; }; struct ExtractHeaderParseFailure { }; [[nodiscard]] StringView legacy_extract_an_encoding(Optional const& mime_type, StringView fallback_encoding); [[nodiscard]] ErrorOr>> get_decode_and_split_header_value(ReadonlyBytes); [[nodiscard]] ErrorOr> convert_header_names_to_a_sorted_lowercase_set(Span); [[nodiscard]] bool is_header_name(ReadonlyBytes); [[nodiscard]] bool is_header_value(ReadonlyBytes); [[nodiscard]] ErrorOr normalize_header_value(ReadonlyBytes); [[nodiscard]] bool is_cors_safelisted_request_header(Header const&); [[nodiscard]] bool is_cors_unsafe_request_header_byte(u8); [[nodiscard]] ErrorOr> get_cors_unsafe_header_names(HeaderList const&); [[nodiscard]] bool is_cors_non_wildcard_request_header_name(ReadonlyBytes); [[nodiscard]] bool is_privileged_no_cors_request_header_name(ReadonlyBytes); [[nodiscard]] bool is_cors_safelisted_response_header_name(ReadonlyBytes, Span); [[nodiscard]] bool is_no_cors_safelisted_request_header_name(ReadonlyBytes); [[nodiscard]] bool is_no_cors_safelisted_request_header(Header const&); [[nodiscard]] ErrorOr is_forbidden_request_header(Header const&); [[nodiscard]] bool is_forbidden_response_header_name(ReadonlyBytes); [[nodiscard]] bool is_request_body_header_name(ReadonlyBytes); [[nodiscard]] ErrorOr>> extract_header_values(Header const&); [[nodiscard]] ErrorOr, ExtractHeaderParseFailure, Empty>> extract_header_list_values(ReadonlyBytes, HeaderList const&); [[nodiscard]] Optional parse_single_range_header_value(ReadonlyBytes); [[nodiscard]] ErrorOr default_user_agent_value(); }