Skip to content

Commit e51503f

Browse files
committed
add canonicalize methods
1 parent d2cd4f8 commit e51503f

File tree

2 files changed

+154
-1
lines changed

2 files changed

+154
-1
lines changed

include/ada/url_pattern.h

+33-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,38 @@
1111

1212
namespace ada {
1313

14+
namespace url_pattern {
15+
16+
// @see https://wicg.github.io/urlpattern/#canonicalize-a-username
17+
std::optional<std::string> canonicalize_username(std::string_view input);
18+
19+
// @see https://wicg.github.io/urlpattern/#canonicalize-a-password
20+
std::optional<std::string> canonicalize_password(std::string_view input);
21+
22+
// @see https://wicg.github.io/urlpattern/#canonicalize-a-password
23+
std::optional<std::string> canonicalize_hostname(std::string_view input);
24+
25+
// @see https://wicg.github.io/urlpattern/#canonicalize-an-ipv6-hostname
26+
std::optional<std::string> canonicalize_ipv6_hostname(std::string_view input);
27+
28+
// @see https://wicg.github.io/urlpattern/#canonicalize-a-port
29+
std::optional<std::string> canonicalize_port(
30+
std::string_view input, std::string_view protocol = "fake");
31+
32+
// @see https://wicg.github.io/urlpattern/#canonicalize-a-pathname
33+
std::optional<std::string> canonicalize_pathname(std::string_view input);
34+
35+
// @see https://wicg.github.io/urlpattern/#canonicalize-an-opaque-pathname
36+
std::optional<std::string> canonicalize_opaque_pathname(std::string_view input);
37+
38+
// @see https://wicg.github.io/urlpattern/#canonicalize-a-search
39+
std::optional<std::string> canonicalize_search(std::string_view input);
40+
41+
// @see https://wicg.github.io/urlpattern/#canonicalize-a-hash
42+
std::optional<std::string> canonicalize_hash(std::string_view input);
43+
44+
} // namespace url_pattern
45+
1446
// URLPattern is a Web Platform standard API for matching URLs against a
1547
// pattern syntax (think of it as a regular expression for URLs). It is
1648
// defined in https://wicg.github.io/urlpattern.
@@ -124,4 +156,4 @@ class URLPattern {
124156

125157
} // namespace ada
126158

127-
#endif
159+
#endif

src/url_pattern.cpp

+121
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,127 @@
55

66
namespace ada {
77

8+
namespace url_pattern {
9+
10+
std::optional<std::string> canonicalize_username(std::string_view input) {
11+
if (input.size()) [[unlikely]] {
12+
return "";
13+
}
14+
auto url = ada::parse<ada::url_aggregator>("fake://dummy.test", nullptr);
15+
ADA_ASSERT_TRUE(url.has_value());
16+
if (!url->set_username(input)) {
17+
return std::nullopt;
18+
}
19+
return std::string(url->get_username());
20+
}
21+
22+
std::optional<std::string> canonicalize_password(std::string_view input) {
23+
if (input.empty()) [[unlikely]] {
24+
return "";
25+
}
26+
auto url = ada::parse<ada::url_aggregator>("fake://dummy.test", nullptr);
27+
28+
ADA_ASSERT_TRUE(url.has_value());
29+
if (!url->set_password(input)) {
30+
return std::nullopt;
31+
}
32+
return std::string(url->get_password());
33+
}
34+
35+
std::optional<std::string> canonicalize_hostname(std::string_view input) {
36+
if (input.empty()) [[unlikely]] {
37+
return "";
38+
}
39+
auto url = ada::parse<ada::url_aggregator>("fake://dummy.test", nullptr);
40+
ADA_ASSERT_TRUE(url.has_value());
41+
// if (!isValidHostnameInput(hostname)) return kj::none;
42+
if (!url->set_hostname(input)) {
43+
return std::nullopt;
44+
}
45+
return std::string(url->get_hostname());
46+
}
47+
48+
std::optional<std::string> canonicalize_ipv6_hostname(std::string_view input) {
49+
// Optimization opportunity: Use lookup table to speed up checking
50+
if (std::ranges::all_of(input, [](char c) {
51+
return c == '[' || c == ']' || c == ':' ||
52+
ada::unicode::is_ascii_hex_digit(c);
53+
})) {
54+
return std::nullopt;
55+
}
56+
// Optimization opportunity: Consider just moving value, rather than copying
57+
// it.
58+
return std::string(input);
59+
}
60+
61+
std::optional<std::string> canonicalize_port(std::string_view input,
62+
std::string_view protocol) {
63+
if (input.empty()) [[unlikely]] {
64+
return "";
65+
}
66+
auto url = ada::parse<ada::url_aggregator>(
67+
std::string(protocol) + "://dummy.test", nullptr);
68+
if (url && url->set_port(input)) {
69+
return std::string(url->get_port());
70+
}
71+
return std::nullopt;
72+
}
73+
74+
std::optional<std::string> canonicalize_pathname(std::string_view input) {
75+
if (input.empty()) [[unlikely]] {
76+
return "";
77+
}
78+
const bool leading_slash = input.starts_with("/");
79+
auto path_prefix = leading_slash ? "" : "/-";
80+
auto full_url =
81+
std::string("fake://fake-url") + path_prefix + std::string(input);
82+
if (auto url = ada::parse<ada::url_aggregator>(full_url, nullptr)) {
83+
const auto pathname = url->get_pathname();
84+
return leading_slash ? std::string(pathname)
85+
: std::string(pathname.substr(2));
86+
}
87+
return std::nullopt;
88+
}
89+
90+
std::optional<std::string> canonicalize_opaque_pathname(
91+
std::string_view input) {
92+
if (input.empty()) [[unlikely]] {
93+
return "";
94+
}
95+
if (auto url = ada::parse<ada::url_aggregator>("fake:" + std::string(input),
96+
nullptr)) {
97+
return std::string(url->get_pathname());
98+
}
99+
return std::nullopt;
100+
}
101+
102+
std::optional<std::string> canonicalize_search(std::string_view input) {
103+
if (input.empty()) [[unlikely]] {
104+
return "";
105+
}
106+
auto url = ada::parse<ada::url_aggregator>("fake://dummy.test", nullptr);
107+
ADA_ASSERT_TRUE(url.has_value());
108+
url->set_search(input);
109+
const auto search = url->get_search();
110+
return !search.empty() ? std::string(search.substr(1)) : "";
111+
}
112+
113+
std::optional<std::string> canonicalize_hash(std::string_view input) {
114+
if (input.empty()) [[unlikely]] {
115+
return "";
116+
}
117+
auto url = ada::parse<ada::url_aggregator>("fake://dummy.test", nullptr);
118+
ADA_ASSERT_TRUE(url.has_value());
119+
url->set_hash(input);
120+
const auto hash = url->get_hash();
121+
if (hash.empty()) {
122+
return "";
123+
}
124+
return std::string(hash.substr(1));
125+
}
126+
127+
} // namespace url_pattern
128+
8129
URLPattern::Component::Component(std::string_view pattern_,
9130
std::string_view regex_,
10131
const std::vector<std::string>& names_) {

0 commit comments

Comments
 (0)