|
@@ -236,102 +236,6 @@ static Optional<IPv4Address> parse_ipv4_address(StringView input)
|
|
|
return ipv4;
|
|
|
}
|
|
|
|
|
|
-// https://url.spec.whatwg.org/#concept-ipv4-serializer
|
|
|
-static ErrorOr<String> serialize_ipv4_address(IPv4Address address)
|
|
|
-{
|
|
|
- // 1. Let output be the empty string.
|
|
|
- // NOTE: Array to avoid prepend.
|
|
|
- Array<u8, 4> output;
|
|
|
-
|
|
|
- // 2. Let n be the value of address.
|
|
|
- u32 n = address;
|
|
|
-
|
|
|
- // 3. For each i in the range 1 to 4, inclusive:
|
|
|
- for (size_t i = 0; i <= 3; ++i) {
|
|
|
- // 1. Prepend n % 256, serialized, to output.
|
|
|
- output[3 - i] = n % 256;
|
|
|
-
|
|
|
- // 2. If i is not 4, then prepend U+002E (.) to output.
|
|
|
- // NOTE: done at end
|
|
|
-
|
|
|
- // 3. Set n to floor(n / 256).
|
|
|
- n /= 256;
|
|
|
- }
|
|
|
-
|
|
|
- // 4. Return output.
|
|
|
- return String::formatted("{}.{}.{}.{}", output[0], output[1], output[2], output[3]);
|
|
|
-}
|
|
|
-
|
|
|
-// https://url.spec.whatwg.org/#concept-ipv6-serializer
|
|
|
-static void serialize_ipv6_address(IPv6Address const& address, StringBuilder& output)
|
|
|
-{
|
|
|
- // 1. Let output be the empty string.
|
|
|
-
|
|
|
- // 2. Let compress be an index to the first IPv6 piece in the first longest sequences of address’s IPv6 pieces that are 0.
|
|
|
- Optional<size_t> compress;
|
|
|
- size_t longest_sequence_length = 0;
|
|
|
- size_t current_sequence_length = 0;
|
|
|
- size_t current_sequence_start = 0;
|
|
|
- for (size_t i = 0; i < 8; ++i) {
|
|
|
- if (address[i] == 0) {
|
|
|
- if (current_sequence_length == 0)
|
|
|
- current_sequence_start = i;
|
|
|
- ++current_sequence_length;
|
|
|
- } else {
|
|
|
- if (current_sequence_length > longest_sequence_length) {
|
|
|
- longest_sequence_length = current_sequence_length;
|
|
|
- compress = current_sequence_start;
|
|
|
- }
|
|
|
- current_sequence_length = 0;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if (current_sequence_length > longest_sequence_length) {
|
|
|
- longest_sequence_length = current_sequence_length;
|
|
|
- compress = current_sequence_start;
|
|
|
- }
|
|
|
-
|
|
|
- // 3. If there is no sequence of address’s IPv6 pieces that are 0 that is longer than 1, then set compress to null.
|
|
|
- if (longest_sequence_length <= 1)
|
|
|
- compress = {};
|
|
|
-
|
|
|
- // 4. Let ignore0 be false.
|
|
|
- auto ignore0 = false;
|
|
|
-
|
|
|
- // 5. For each pieceIndex in the range 0 to 7, inclusive:
|
|
|
- for (size_t piece_index = 0; piece_index <= 7; ++piece_index) {
|
|
|
- // 1. If ignore0 is true and address[pieceIndex] is 0, then continue.
|
|
|
- if (ignore0 && address[piece_index] == 0)
|
|
|
- continue;
|
|
|
-
|
|
|
- // 2. Otherwise, if ignore0 is true, set ignore0 to false.
|
|
|
- if (ignore0)
|
|
|
- ignore0 = false;
|
|
|
-
|
|
|
- // 3. If compress is pieceIndex, then:
|
|
|
- if (compress == piece_index) {
|
|
|
- // 1. Let separator be "::" if pieceIndex is 0, and U+003A (:) otherwise.
|
|
|
- auto separator = piece_index == 0 ? "::"sv : ":"sv;
|
|
|
-
|
|
|
- // 2. Append separator to output.
|
|
|
- output.append(separator);
|
|
|
-
|
|
|
- // 3. Set ignore0 to true and continue.
|
|
|
- ignore0 = true;
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- // 4. Append address[pieceIndex], represented as the shortest possible lowercase hexadecimal number, to output.
|
|
|
- output.appendff("{:x}", address[piece_index]);
|
|
|
-
|
|
|
- // 5. If pieceIndex is not 7, then append U+003A (:) to output.
|
|
|
- if (piece_index != 7)
|
|
|
- output.append(':');
|
|
|
- }
|
|
|
-
|
|
|
- // 6. Return output.
|
|
|
-}
|
|
|
-
|
|
|
// https://url.spec.whatwg.org/#concept-ipv6-parser
|
|
|
static Optional<IPv6Address> parse_ipv6_address(StringView input)
|
|
|
{
|
|
@@ -654,7 +558,7 @@ static Optional<Host> parse_host(StringView input, bool is_opaque = false)
|
|
|
auto address = parse_ipv6_address(input.substring_view(1, input.length() - 2));
|
|
|
if (!address.has_value())
|
|
|
return {};
|
|
|
- return address.release_value();
|
|
|
+ return Host { address.release_value() };
|
|
|
}
|
|
|
|
|
|
// 2. If isOpaque is true, then return the result of opaque-host parsing input.
|
|
@@ -690,35 +594,13 @@ static Optional<Host> parse_host(StringView input, bool is_opaque = false)
|
|
|
if (!ipv4_host.has_value())
|
|
|
return {};
|
|
|
|
|
|
- return ipv4_host.release_value();
|
|
|
+ return Host { ipv4_host.release_value() };
|
|
|
}
|
|
|
|
|
|
// 9. Return asciiDomain.
|
|
|
return ascii_domain;
|
|
|
}
|
|
|
|
|
|
-// https://url.spec.whatwg.org/#concept-host-serializer
|
|
|
-ErrorOr<String> Parser::serialize_host(Host const& host)
|
|
|
-{
|
|
|
- // 1. If host is an IPv4 address, return the result of running the IPv4 serializer on host.
|
|
|
- if (host.has<IPv4Address>())
|
|
|
- return serialize_ipv4_address(host.get<IPv4Address>());
|
|
|
-
|
|
|
- // 2. Otherwise, if host is an IPv6 address, return U+005B ([), followed by the result of running the IPv6 serializer on host, followed by U+005D (]).
|
|
|
- if (host.has<IPv6Address>()) {
|
|
|
- StringBuilder output;
|
|
|
- TRY(output.try_append('['));
|
|
|
- serialize_ipv6_address(host.get<IPv6Address>(), output);
|
|
|
- TRY(output.try_append(']'));
|
|
|
- return output.to_string();
|
|
|
- }
|
|
|
-
|
|
|
- // 3. Otherwise, host is a domain, opaque host, or empty host, return host.
|
|
|
- if (host.has<String>())
|
|
|
- return host.get<String>();
|
|
|
- return String {};
|
|
|
-}
|
|
|
-
|
|
|
// https://url.spec.whatwg.org/#start-with-a-windows-drive-letter
|
|
|
constexpr bool starts_with_windows_drive_letter(StringView input)
|
|
|
{
|
|
@@ -953,7 +835,7 @@ URL Parser::basic_parse(StringView raw_input, Optional<URL> const& base_url, URL
|
|
|
return *url;
|
|
|
|
|
|
// 4. If url’s scheme is "file" and its host is an empty host, then return.
|
|
|
- if (url->scheme() == "file"sv && url->host() == String {})
|
|
|
+ if (url->scheme() == "file"sv && url->host().has_value() && url->host()->is_empty_host())
|
|
|
return *url;
|
|
|
}
|
|
|
|