@@ -7,42 +7,74 @@ namespace ada {
77
88namespace url_pattern {
99
10+ std::optional<std::string> canonicalize_protocol (std::string_view input) {
11+ // If value is the empty string, return value.
12+ if (input.empty ()) [[unlikely]] {
13+ return " " ;
14+ }
15+ // Let dummyURL be a new URL record.
16+ // Let parseResult be the result of running the basic URL parser given value
17+ // followed by "://dummy.test", with dummyURL as url.
18+ if (auto dummy_url = ada::parse<ada::url_aggregator>(
19+ std::string (input) + " ://dummy.test" , nullptr )) {
20+ // Return dummyURL’s scheme.
21+ return std::string (dummy_url->get_protocol ());
22+ }
23+ // If parseResult is failure, then throw a TypeError.
24+ return std::nullopt ;
25+ }
26+
1027std::optional<std::string> canonicalize_username (std::string_view input) {
11- if (input.size ()) [[unlikely]] {
28+ // If value is the empty string, return value.
29+ if (input.empty ()) [[unlikely]] {
1230 return " " ;
1331 }
32+ // Let dummyURL be a new URL record.
1433 auto url = ada::parse<ada::url_aggregator>(" fake://dummy.test" , nullptr );
1534 ADA_ASSERT_TRUE (url.has_value ());
35+ // Set the username given dummyURL and value.
1636 if (!url->set_username (input)) {
1737 return std::nullopt ;
1838 }
39+ // Return dummyURL’s username.
1940 return std::string (url->get_username ());
2041}
2142
2243std::optional<std::string> canonicalize_password (std::string_view input) {
44+ // If value is the empty string, return value.
2345 if (input.empty ()) [[unlikely]] {
2446 return " " ;
2547 }
48+ // Let dummyURL be a new URL record.
49+ // Set the password given dummyURL and value.
2650 auto url = ada::parse<ada::url_aggregator>(" fake://dummy.test" , nullptr );
2751
2852 ADA_ASSERT_TRUE (url.has_value ());
2953 if (!url->set_password (input)) {
3054 return std::nullopt ;
3155 }
56+ // Return dummyURL’s password.
3257 return std::string (url->get_password ());
3358}
3459
3560std::optional<std::string> canonicalize_hostname (std::string_view input) {
61+ // If value is the empty string, return value.
3662 if (input.empty ()) [[unlikely]] {
3763 return " " ;
3864 }
65+ // Let dummyURL be a new URL record.
66+ // Let parseResult be the result of running the basic URL parser given value
67+ // with dummyURL as url and hostname state as state override.
3968 auto url = ada::parse<ada::url_aggregator>(" fake://dummy.test" , nullptr );
4069 ADA_ASSERT_TRUE (url.has_value ());
4170 // if (!isValidHostnameInput(hostname)) return kj::none;
4271 if (!url->set_hostname (input)) {
72+ // If parseResult is failure, then throw a TypeError.
4373 return std::nullopt ;
4474 }
45- return std::string (url->get_hostname ());
75+ const auto hostname = url->get_hostname ();
76+ // Return dummyURL’s host, serialized, or empty string if it is null.
77+ return hostname.empty () ? " " : std::string (hostname);
4678}
4779
4880std::optional<std::string> canonicalize_ipv6_hostname (std::string_view input) {
@@ -53,74 +85,110 @@ std::optional<std::string> canonicalize_ipv6_hostname(std::string_view input) {
5385 })) {
5486 return std::nullopt ;
5587 }
56- // Optimization opportunity: Consider just moving value, rather than copying
57- // it.
58- return std::string (input);
88+ // Append the result of running ASCII lowercase given code point to the end of
89+ // result.
90+ auto hostname = std::string (input);
91+ ada::unicode::to_lower_ascii (hostname.data (), hostname.size ());
92+ return hostname;
5993}
6094
61- std::optional<std::string> canonicalize_port (std::string_view input ,
95+ std::optional<std::string> canonicalize_port (std::string_view port_value ,
6296 std::string_view protocol) {
63- if (input.empty ()) [[unlikely]] {
97+ // If portValue is the empty string, return portValue.
98+ if (port_value.empty ()) [[unlikely]] {
6499 return " " ;
65100 }
101+ // Let dummyURL be a new URL record.
102+ // If protocolValue was given, then set dummyURL’s scheme to protocolValue.
103+ // Let parseResult be the result of running basic URL parser given portValue
104+ // with dummyURL as url and port state as state override.
66105 auto url = ada::parse<ada::url_aggregator>(
67106 std::string (protocol) + " ://dummy.test" , nullptr );
68- if (url && url->set_port (input)) {
107+ if (url && url->set_port (port_value)) {
108+ // Return dummyURL’s port, serialized, or empty string if it is null.
69109 return std::string (url->get_port ());
70110 }
111+ // If parseResult is failure, then throw a TypeError.
71112 return std::nullopt ;
72113}
73114
74115std::optional<std::string> canonicalize_pathname (std::string_view input) {
116+ // If value is the empty string, then return value.
75117 if (input.empty ()) [[unlikely]] {
76118 return " " ;
77119 }
120+ // Let leading slash be true if the first code point in value is U+002F (/)
121+ // and otherwise false.
78122 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);
123+ // Let modified value be "/-" if leading slash is false and otherwise the
124+ // empty string.
125+ const auto modified_value = leading_slash ? " " : " /-" ;
126+ const auto full_url =
127+ std::string (" fake://fake-url" ) + modified_value + std::string (input);
82128 if (auto url = ada::parse<ada::url_aggregator>(full_url, nullptr )) {
83129 const auto pathname = url->get_pathname ();
130+ // If leading slash is false, then set result to the code point substring
131+ // from 2 to the end of the string within result.
84132 return leading_slash ? std::string (pathname)
85133 : std::string (pathname.substr (2 ));
86134 }
135+ // If parseResult is failure, then throw a TypeError.
87136 return std::nullopt ;
88137}
89138
90139std::optional<std::string> canonicalize_opaque_pathname (
91140 std::string_view input) {
141+ // If value is the empty string, return value.
92142 if (input.empty ()) [[unlikely]] {
93143 return " " ;
94144 }
145+ // Let dummyURL be a new URL record.
146+ // Set dummyURL’s path to the empty string.
147+ // Let parseResult be the result of running URL parsing given value with
148+ // dummyURL as url and opaque path state as state override.
95149 if (auto url = ada::parse<ada::url_aggregator>(" fake:" + std::string (input),
96150 nullptr )) {
151+ // Return the result of URL path serializing dummyURL.
97152 return std::string (url->get_pathname ());
98153 }
154+ // If parseResult is failure, then throw a TypeError.
99155 return std::nullopt ;
100156}
101157
102158std::optional<std::string> canonicalize_search (std::string_view input) {
159+ // If value is the empty string, return value.
103160 if (input.empty ()) [[unlikely]] {
104161 return " " ;
105162 }
163+ // Let dummyURL be a new URL record.
164+ // Set dummyURL’s query to the empty string.
165+ // Let parseResult be the result of running basic URL parser given value with
166+ // dummyURL as url and query state as state override.
106167 auto url = ada::parse<ada::url_aggregator>(" fake://dummy.test" , nullptr );
107168 ADA_ASSERT_TRUE (url.has_value ());
108169 url->set_search (input);
109170 const auto search = url->get_search ();
171+ // Return dummyURL’s query.
110172 return !search.empty () ? std::string (search.substr (1 )) : " " ;
111173}
112174
113175std::optional<std::string> canonicalize_hash (std::string_view input) {
176+ // If value is the empty string, return value.
114177 if (input.empty ()) [[unlikely]] {
115178 return " " ;
116179 }
180+ // Let dummyURL be a new URL record.
181+ // Set dummyURL’s fragment to the empty string.
182+ // Let parseResult be the result of running basic URL parser given value with
183+ // dummyURL as url and fragment state as state override.
117184 auto url = ada::parse<ada::url_aggregator>(" fake://dummy.test" , nullptr );
118185 ADA_ASSERT_TRUE (url.has_value ());
119186 url->set_hash (input);
120187 const auto hash = url->get_hash ();
121188 if (hash.empty ()) {
122189 return " " ;
123190 }
191+ // Return dummyURL’s fragment.
124192 return std::string (hash.substr (1 ));
125193}
126194
0 commit comments