LibURL: Move registrable-domain PSL lookup to PublicSuffixData
Move the registrable-domain helper from URL into PublicSuffixData and name it find_matching_registrable_domain(). This keeps it alongside find_matching_public_suffix(), making it clear that both APIs only return results matched from the PSL data, while Host::public_suffix() implements the URL Standard fallback to the top-level domain.
This commit is contained in:
parent
ac344a5196
commit
9b80ac00be
7 changed files with 41 additions and 46 deletions
|
|
@ -10,6 +10,7 @@
|
|||
#include <LibHTTP/Cookie/Cookie.h>
|
||||
#include <LibIPC/Decoder.h>
|
||||
#include <LibIPC/Encoder.h>
|
||||
#include <LibURL/PublicSuffixData.h>
|
||||
#include <LibURL/URL.h>
|
||||
|
||||
namespace HTTP::Cookie {
|
||||
|
|
@ -161,7 +162,7 @@ bool cookie_matches_url(Cookie const& cookie, URL::URL const& url, String const&
|
|||
// the cookie's domain.
|
||||
// - The cookie's domain is not a public suffix, for user agents configured to reject "public suffixes".
|
||||
bool is_not_host_only_and_domain_matches = (!cookie.host_only && domain_matches(retrieval_host_canonical, cookie.domain))
|
||||
&& !URL::is_public_suffix(cookie.domain);
|
||||
&& !URL::PublicSuffixData::the()->is_matching_public_suffix(cookie.domain);
|
||||
|
||||
if (!is_host_only_and_has_identical_domain && !is_not_host_only_and_domain_matches)
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -238,7 +238,7 @@ Optional<String> Host::registrable_domain() const
|
|||
host_without_trailing_dot = host_without_trailing_dot.substring_view(0, host_without_trailing_dot.length() - 1);
|
||||
|
||||
// NB: If we do not find a registrable domain via the PSL, use everything after the second to last dot.
|
||||
auto registrable_domain = get_registrable_domain(host_without_trailing_dot);
|
||||
auto registrable_domain = PublicSuffixData::the()->find_matching_registrable_domain(host_without_trailing_dot);
|
||||
if (!registrable_domain.has_value()) {
|
||||
auto last_dot = host_without_trailing_dot.find_last('.');
|
||||
if (last_dot.has_value()) {
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@
|
|||
#include <AK/Utf8View.h>
|
||||
#include <LibURL/Parser.h>
|
||||
#include <LibURL/PublicSuffixData.h>
|
||||
#include <LibURL/URL.h>
|
||||
|
||||
namespace URL {
|
||||
|
||||
|
|
@ -505,33 +504,4 @@ ByteString percent_decode(StringView input)
|
|||
return builder.to_byte_string();
|
||||
}
|
||||
|
||||
bool is_public_suffix(StringView host)
|
||||
{
|
||||
return PublicSuffixData::the()->is_matching_public_suffix(host);
|
||||
}
|
||||
|
||||
// https://github.com/publicsuffix/list/wiki/Format#algorithm
|
||||
Optional<String> get_registrable_domain(StringView host)
|
||||
{
|
||||
// The registered or registrable domain is the public suffix plus one additional label.
|
||||
auto public_suffix = PublicSuffixData::the()->find_matching_public_suffix(host);
|
||||
if (!public_suffix.has_value() || !host.ends_with(*public_suffix))
|
||||
return {};
|
||||
|
||||
if (host == *public_suffix)
|
||||
return {};
|
||||
|
||||
auto subhost = host.substring_view(0, host.length() - public_suffix->bytes_as_string_view().length());
|
||||
subhost = subhost.trim("."sv, TrimMode::Right);
|
||||
|
||||
if (subhost.is_empty())
|
||||
return {};
|
||||
|
||||
size_t start_index = 0;
|
||||
if (auto index = subhost.find_last('.'); index.has_value())
|
||||
start_index = *index + 1;
|
||||
|
||||
return MUST(String::from_utf8(host.substring_view(start_index)));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -210,9 +210,6 @@ Optional<URL> create_with_url_or_path(ByteString const&);
|
|||
Optional<URL> create_with_file_scheme(ByteString const& path, ByteString const& fragment = {}, ByteString const& hostname = {});
|
||||
URL create_with_data(StringView mime_type, StringView payload, bool is_base64 = false);
|
||||
|
||||
bool is_public_suffix(StringView host);
|
||||
Optional<String> get_registrable_domain(StringView host);
|
||||
|
||||
inline URL about_blank() { return URL::about("blank"_string); }
|
||||
inline URL about_srcdoc() { return URL::about("srcdoc"_string); }
|
||||
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
#include <AK/Vector.h>
|
||||
#include <LibDatabase/Database.h>
|
||||
#include <LibHTTP/Cookie/ParsedCookie.h>
|
||||
#include <LibURL/PublicSuffixData.h>
|
||||
#include <LibURL/URL.h>
|
||||
#include <LibWebView/CookieJar.h>
|
||||
#include <LibWebView/ViewImplementation.h>
|
||||
|
|
@ -198,7 +199,7 @@ void CookieJar::set_cookie(URL::URL const& url, HTTP::Cookie::ParsedCookie const
|
|||
return;
|
||||
|
||||
// 9. If the user agent is configured to reject "public suffixes" and the domain-attribute is a public suffix:
|
||||
if (URL::is_public_suffix(domain_attribute)) {
|
||||
if (URL::PublicSuffixData::the()->is_matching_public_suffix(domain_attribute)) {
|
||||
// 1. Let request-host-canonical be the canonicalized request-host.
|
||||
// 2. If request-host fails to be canonicalized then abort this algorithm and ignore the cookie entirely.
|
||||
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ public:
|
|||
|
||||
bool is_matching_public_suffix(StringView host);
|
||||
Optional<String> find_matching_public_suffix(StringView string);
|
||||
Optional<String> find_matching_registrable_domain(StringView string);
|
||||
|
||||
};
|
||||
|
||||
|
|
@ -139,6 +140,30 @@ Optional<String> PublicSuffixData::find_matching_public_suffix(StringView string
|
|||
return MUST(return_string_builder.to_string());
|
||||
}
|
||||
|
||||
// https://github.com/publicsuffix/list/wiki/Format#algorithm
|
||||
Optional<String> PublicSuffixData::find_matching_registrable_domain(StringView host)
|
||||
{
|
||||
// The registered or registrable domain is the public suffix plus one additional label.
|
||||
auto public_suffix = find_matching_public_suffix(host);
|
||||
if (!public_suffix.has_value() || !host.ends_with(*public_suffix))
|
||||
return {};
|
||||
|
||||
if (host == *public_suffix)
|
||||
return {};
|
||||
|
||||
auto subhost = host.substring_view(0, host.length() - public_suffix->bytes_as_string_view().length());
|
||||
subhost = subhost.trim("."sv, TrimMode::Right);
|
||||
|
||||
if (subhost.is_empty())
|
||||
return {};
|
||||
|
||||
size_t start_index = 0;
|
||||
if (auto index = subhost.find_last('.'); index.has_value())
|
||||
start_index = *index + 1;
|
||||
|
||||
return MUST(String::from_utf8(host.substring_view(start_index)));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
#include <LibTest/TestCase.h>
|
||||
|
||||
#include <LibURL/Parser.h>
|
||||
#include <LibURL/PublicSuffixData.h>
|
||||
#include <LibURL/URL.h>
|
||||
|
||||
TEST_CASE(basic)
|
||||
|
|
@ -633,47 +634,47 @@ TEST_CASE(invalid_domain_code_points)
|
|||
TEST_CASE(get_registrable_domain)
|
||||
{
|
||||
{
|
||||
auto domain = URL::get_registrable_domain({});
|
||||
auto domain = URL::PublicSuffixData::the()->find_matching_registrable_domain({});
|
||||
EXPECT(!domain.has_value());
|
||||
}
|
||||
{
|
||||
auto domain = URL::get_registrable_domain("foobar"sv);
|
||||
auto domain = URL::PublicSuffixData::the()->find_matching_registrable_domain("foobar"sv);
|
||||
EXPECT(!domain.has_value());
|
||||
}
|
||||
{
|
||||
auto domain = URL::get_registrable_domain("com"sv);
|
||||
auto domain = URL::PublicSuffixData::the()->find_matching_registrable_domain("com"sv);
|
||||
EXPECT(!domain.has_value());
|
||||
}
|
||||
{
|
||||
auto domain = URL::get_registrable_domain(".com"sv);
|
||||
auto domain = URL::PublicSuffixData::the()->find_matching_registrable_domain(".com"sv);
|
||||
EXPECT(!domain.has_value());
|
||||
}
|
||||
{
|
||||
auto domain = URL::get_registrable_domain("example.com"sv);
|
||||
auto domain = URL::PublicSuffixData::the()->find_matching_registrable_domain("example.com"sv);
|
||||
VERIFY(domain.has_value());
|
||||
EXPECT_EQ(*domain, "example.com"sv);
|
||||
}
|
||||
{
|
||||
auto domain = URL::get_registrable_domain(".example.com"sv);
|
||||
auto domain = URL::PublicSuffixData::the()->find_matching_registrable_domain(".example.com"sv);
|
||||
VERIFY(domain.has_value());
|
||||
EXPECT_EQ(*domain, "example.com"sv);
|
||||
}
|
||||
{
|
||||
auto domain = URL::get_registrable_domain("www.example.com"sv);
|
||||
auto domain = URL::PublicSuffixData::the()->find_matching_registrable_domain("www.example.com"sv);
|
||||
VERIFY(domain.has_value());
|
||||
EXPECT_EQ(*domain, "example.com"sv);
|
||||
}
|
||||
{
|
||||
auto domain = URL::get_registrable_domain("sub.www.example.com"sv);
|
||||
auto domain = URL::PublicSuffixData::the()->find_matching_registrable_domain("sub.www.example.com"sv);
|
||||
VERIFY(domain.has_value());
|
||||
EXPECT_EQ(*domain, "example.com"sv);
|
||||
}
|
||||
{
|
||||
auto domain = URL::get_registrable_domain("github.io"sv);
|
||||
auto domain = URL::PublicSuffixData::the()->find_matching_registrable_domain("github.io"sv);
|
||||
EXPECT(!domain.has_value());
|
||||
}
|
||||
{
|
||||
auto domain = URL::get_registrable_domain("ladybird.github.io"sv);
|
||||
auto domain = URL::PublicSuffixData::the()->find_matching_registrable_domain("ladybird.github.io"sv);
|
||||
VERIFY(domain.has_value());
|
||||
EXPECT_EQ(*domain, "ladybird.github.io"sv);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue