LibURL: Clarify whether an Origin is opaque

Origins are immutable and we know on construction whether an Origin is
opaque. This also removes an implicit reliance on Host's Empty state.
This commit is contained in:
Sam Atkins 2024-11-27 14:16:31 +00:00 committed by Andreas Kling
commit 8b984c0c57
Notes: github-actions[bot] 2024-11-30 11:24:16 +00:00
4 changed files with 40 additions and 19 deletions

View file

@ -100,6 +100,10 @@ ErrorOr<URL::URL> decode(Decoder& decoder)
template<>
ErrorOr<URL::Origin> decode(Decoder& decoder)
{
auto is_opaque = TRY(decoder.decode<bool>());
if (is_opaque)
return URL::Origin {};
auto scheme = TRY(decoder.decode<ByteString>());
auto host = TRY(decoder.decode<URL::Host>());
auto port = TRY(decoder.decode<Optional<u16>>());

View file

@ -119,9 +119,14 @@ ErrorOr<void> encode(Encoder& encoder, URL::URL const& value)
template<>
ErrorOr<void> encode(Encoder& encoder, URL::Origin const& origin)
{
TRY(encoder.encode<ByteString>(origin.scheme()));
TRY(encoder.encode(origin.host()));
TRY(encoder.encode(origin.port()));
if (origin.is_opaque()) {
TRY(encoder.encode(true));
} else {
TRY(encoder.encode(false));
TRY(encoder.encode<ByteString>(origin.scheme()));
TRY(encoder.encode(origin.host()));
TRY(encoder.encode(origin.port()));
}
return {};
}

View file

@ -42,13 +42,15 @@ namespace AK {
unsigned Traits<URL::Origin>::hash(URL::Origin const& origin)
{
if (origin.is_opaque())
return 0;
unsigned hash = origin.scheme().hash();
if (origin.port().has_value())
hash = pair_int_hash(hash, *origin.port());
if (!origin.host().has<Empty>())
hash = pair_int_hash(hash, URL::Parser::serialize_host(origin.host()).release_value_but_fixme_should_propagate_errors().hash());
hash = pair_int_hash(hash, URL::Parser::serialize_host(origin.host()).release_value_but_fixme_should_propagate_errors().hash());
return hash;
}

View file

@ -16,21 +16,23 @@ class Origin {
public:
Origin() = default;
Origin(Optional<ByteString> const& scheme, Host const& host, Optional<u16> port)
: m_scheme(scheme)
, m_host(host)
, m_port(port)
: m_state(State {
.scheme = scheme,
.host = host,
.port = move(port),
})
{
}
// https://html.spec.whatwg.org/multipage/origin.html#concept-origin-opaque
bool is_opaque() const { return !m_scheme.has_value() && m_host.has<Empty>() && !m_port.has_value(); }
bool is_opaque() const { return !m_state.has_value(); }
StringView scheme() const
{
return m_scheme.map([](auto& str) { return str.view(); }).value_or(StringView {});
return m_state->scheme.map([](auto& str) { return str.view(); }).value_or(StringView {});
}
Host const& host() const { return m_host; }
Optional<u16> port() const { return m_port; }
Host const& host() const { return m_state->host; }
Optional<u16> port() const { return m_state->port; }
// https://html.spec.whatwg.org/multipage/origin.html#same-origin
bool is_same_origin(Origin const& other) const
@ -40,10 +42,15 @@ public:
return true;
// 2. If A and B are both tuple origins and their schemes, hosts, and port are identical, then return true.
// 3. Return false.
return scheme() == other.scheme()
if (!is_opaque() && !other.is_opaque()
&& scheme() == other.scheme()
&& host() == other.host()
&& port() == other.port();
&& port() == other.port()) {
return true;
}
// 3. Return false.
return false;
}
// https://html.spec.whatwg.org/multipage/origin.html#same-origin-domain
@ -83,15 +90,18 @@ public:
// FIXME: 2. If origin's domain is non-null, then return origin's domain.
// 3. Return origin's host.
return m_host;
return m_state->host;
}
bool operator==(Origin const& other) const { return is_same_origin(other); }
private:
Optional<ByteString> m_scheme;
Host m_host;
Optional<u16> m_port;
struct State {
Optional<ByteString> scheme;
Host host;
Optional<u16> port;
};
Optional<State> m_state;
};
}