AK+LibURL: Use AK::IPv4/6 in Host
This resolves two FIXME comments.
This commit is contained in:
parent
bef8423f0f
commit
bd82dfa048
11 changed files with 87 additions and 44 deletions
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <AK/BitCast.h>
|
||||
#include <AK/Endian.h>
|
||||
#include <AK/Format.h>
|
||||
#include <AK/IPv4Address.h>
|
||||
|
|
@ -36,6 +37,15 @@ public:
|
|||
m_data[i] = data[i];
|
||||
}
|
||||
|
||||
constexpr IPv6Address(Array<u16, 8> const& data)
|
||||
{
|
||||
for (size_t i = 0; i < 8; i++) {
|
||||
auto piece = data[i];
|
||||
m_data[2 * i] = static_cast<u8>(piece >> 8);
|
||||
m_data[(2 * i) + 1] = static_cast<u8>(piece & 0xff);
|
||||
}
|
||||
}
|
||||
|
||||
template<SameAs<char const*> T>
|
||||
constexpr IPv6Address(T const&) = delete; // Disable implicit conversion of char const* -> ipv4 -> ipv6
|
||||
|
||||
|
|
@ -50,7 +60,7 @@ public:
|
|||
m_data[15] = ipv4_address[3];
|
||||
}
|
||||
|
||||
constexpr u16 operator[](int i) const { return group(i); }
|
||||
constexpr u16 operator[](size_t i) const { return piece(i); }
|
||||
|
||||
ErrorOr<String> to_string() const
|
||||
{
|
||||
|
|
@ -68,13 +78,13 @@ public:
|
|||
Optional<int> longest_zero_span_start;
|
||||
int zero_span_length = 0;
|
||||
for (int i = 0; i < 8;) {
|
||||
if (group(i) != 0) {
|
||||
if (piece(i) != 0) {
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
int contiguous_zeros = 1;
|
||||
for (int j = i + 1; j < 8; j++) {
|
||||
if (group(j) != 0)
|
||||
if (piece(j) != 0)
|
||||
break;
|
||||
contiguous_zeros++;
|
||||
}
|
||||
|
|
@ -98,9 +108,9 @@ public:
|
|||
}
|
||||
|
||||
if (i == 0)
|
||||
TRY(builder.try_appendff("{:x}", group(i)));
|
||||
TRY(builder.try_appendff("{:x}", piece(i)));
|
||||
else
|
||||
TRY(builder.try_appendff(":{:x}", group(i)));
|
||||
TRY(builder.try_appendff(":{:x}", piece(i)));
|
||||
|
||||
i++;
|
||||
}
|
||||
|
|
@ -186,8 +196,8 @@ public:
|
|||
}
|
||||
|
||||
in6_addr_t addr {};
|
||||
int group = 0;
|
||||
int have_groups = 0;
|
||||
int piece = 0;
|
||||
int have_pieces = 0;
|
||||
bool found_compressed = false;
|
||||
for (size_t i = 0; i < parts.size();) {
|
||||
auto trimmed_part = parts[i].trim_whitespace();
|
||||
|
|
@ -216,10 +226,10 @@ public:
|
|||
return {};
|
||||
}
|
||||
|
||||
int remaining_parts = parts.size() - empty_parts - have_groups;
|
||||
int remaining_parts = parts.size() - empty_parts - have_pieces;
|
||||
found_compressed = true;
|
||||
group = 8 - remaining_parts;
|
||||
VERIFY(group >= 0);
|
||||
piece = 8 - remaining_parts;
|
||||
VERIFY(piece >= 0);
|
||||
i += empty_parts;
|
||||
continue;
|
||||
} else {
|
||||
|
|
@ -229,13 +239,13 @@ public:
|
|||
if (!part.has_value() || part.value() > 0xffff)
|
||||
return {};
|
||||
|
||||
if (++have_groups > 8)
|
||||
if (++have_pieces > 8)
|
||||
return {};
|
||||
|
||||
VERIFY(group < 8);
|
||||
addr[group * sizeof(u16)] = (u8)(part.value() >> 8);
|
||||
addr[group * sizeof(u16) + 1] = (u8)part.value();
|
||||
group++;
|
||||
VERIFY(piece < 8);
|
||||
addr[piece * sizeof(u16)] = (u8)(part.value() >> 8);
|
||||
addr[piece * sizeof(u16) + 1] = (u8)part.value();
|
||||
piece++;
|
||||
}
|
||||
|
||||
return IPv6Address(addr);
|
||||
|
|
@ -278,7 +288,7 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
constexpr u16 group(unsigned i) const
|
||||
constexpr u16 piece(size_t i) const
|
||||
{
|
||||
VERIFY(i < 8);
|
||||
return ((u16)m_data[i * sizeof(u16)] << 8) | m_data[i * sizeof(u16) + 1];
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ struct ProxyData {
|
|||
SOCKS5,
|
||||
} type { Type::Direct };
|
||||
|
||||
u32 host_ipv4 { 0 };
|
||||
IPv4Address host_ipv4;
|
||||
int port { 0 };
|
||||
|
||||
bool operator==(ProxyData const& other) const = default;
|
||||
|
|
@ -33,9 +33,9 @@ struct ProxyData {
|
|||
|
||||
proxy_data.type = ProxyData::Type::SOCKS5;
|
||||
|
||||
if (!url.host().has_value() || !url.host()->has<URL::IPv4Address>())
|
||||
if (!url.host().has_value() || !url.host()->has<IPv4Address>())
|
||||
return Error::from_string_literal("Invalid proxy host, must be an IPv4 address");
|
||||
proxy_data.host_ipv4 = url.host()->get<URL::IPv4Address>();
|
||||
proxy_data.host_ipv4 = url.host()->get<IPv4Address>();
|
||||
|
||||
auto port = url.port();
|
||||
if (!port.has_value())
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@
|
|||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <AK/IPv4Address.h>
|
||||
#include <AK/IPv6Address.h>
|
||||
#include <AK/JsonValue.h>
|
||||
#include <AK/NumericLimits.h>
|
||||
#include <AK/Utf16String.h>
|
||||
|
|
@ -87,6 +89,20 @@ ErrorOr<UnixDateTime> decode(Decoder& decoder)
|
|||
return AK::UnixDateTime::from_nanoseconds_since_epoch(nanoseconds);
|
||||
}
|
||||
|
||||
template<>
|
||||
ErrorOr<IPv4Address> decode(Decoder& decoder)
|
||||
{
|
||||
auto ipv4 = TRY(decoder.decode<u32>());
|
||||
return IPv4Address(ipv4);
|
||||
}
|
||||
|
||||
template<>
|
||||
ErrorOr<IPv6Address> decode(Decoder& decoder)
|
||||
{
|
||||
auto ipv6 = TRY(decoder.decode<Array<u8, 16>>());
|
||||
return IPv6Address(ipv6);
|
||||
}
|
||||
|
||||
template<>
|
||||
ErrorOr<URL::URL> decode(Decoder& decoder)
|
||||
{
|
||||
|
|
@ -153,7 +169,7 @@ template<>
|
|||
ErrorOr<Core::ProxyData> decode(Decoder& decoder)
|
||||
{
|
||||
auto type = TRY(decoder.decode<Core::ProxyData::Type>());
|
||||
auto host_ipv4 = TRY(decoder.decode<u32>());
|
||||
auto host_ipv4 = IPv4Address(TRY(decoder.decode<u32>()));
|
||||
auto port = TRY(decoder.decode<int>());
|
||||
|
||||
return Core::ProxyData { type, host_ipv4, port };
|
||||
|
|
|
|||
|
|
@ -106,6 +106,12 @@ ErrorOr<AK::Duration> decode(Decoder&);
|
|||
template<>
|
||||
ErrorOr<UnixDateTime> decode(Decoder&);
|
||||
|
||||
template<>
|
||||
ErrorOr<IPv4Address> decode(Decoder&);
|
||||
|
||||
template<>
|
||||
ErrorOr<IPv6Address> decode(Decoder&);
|
||||
|
||||
template<>
|
||||
ErrorOr<URL::URL> decode(Decoder&);
|
||||
|
||||
|
|
|
|||
|
|
@ -111,6 +111,19 @@ ErrorOr<void> encode(Encoder& encoder, UnixDateTime const& value)
|
|||
return encoder.encode(value.nanoseconds_since_epoch());
|
||||
}
|
||||
|
||||
template<>
|
||||
ErrorOr<void> encode(Encoder& encoder, IPv4Address const& ipv4)
|
||||
{
|
||||
return encoder.encode(ipv4.to_u32());
|
||||
}
|
||||
|
||||
template<>
|
||||
ErrorOr<void> encode(Encoder& encoder, IPv6Address const& ipv6)
|
||||
{
|
||||
auto const& data = ipv6.to_in6_addr_t();
|
||||
return encoder.encode(ReadonlySpan<u8>(data));
|
||||
}
|
||||
|
||||
template<>
|
||||
ErrorOr<void> encode(Encoder& encoder, URL::URL const& value)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include <AK/Concepts.h>
|
||||
#include <AK/HashMap.h>
|
||||
#include <AK/IPv4Address.h>
|
||||
#include <AK/StdLibExtras.h>
|
||||
#include <AK/Variant.h>
|
||||
#include <LibCore/Forward.h>
|
||||
|
|
@ -108,6 +109,12 @@ ErrorOr<void> encode(Encoder&, AK::Duration const&);
|
|||
template<>
|
||||
ErrorOr<void> encode(Encoder&, UnixDateTime const&);
|
||||
|
||||
template<>
|
||||
ErrorOr<void> encode(Encoder&, IPv4Address const&);
|
||||
|
||||
template<>
|
||||
ErrorOr<void> encode(Encoder&, IPv6Address const&);
|
||||
|
||||
template<>
|
||||
ErrorOr<void> encode(Encoder&, URL::URL const&);
|
||||
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ static String serialize_ipv4_address(IPv4Address address)
|
|||
Array<u8, 4> output;
|
||||
|
||||
// 2. Let n be the value of address.
|
||||
u32 n = address;
|
||||
u32 n = address.to_u32();
|
||||
|
||||
// 3. For each i in the range 1 to 4, inclusive:
|
||||
for (size_t i = 0; i <= 3; ++i) {
|
||||
|
|
@ -64,7 +64,7 @@ static Optional<size_t> find_the_ipv6_address_compressed_piece_index(IPv6Address
|
|||
size_t found_size = 0;
|
||||
|
||||
// 5. For each pieceIndex of address’s pieces’s indices:
|
||||
for (size_t piece_index = 0; piece_index < address.size(); ++piece_index) {
|
||||
for (size_t piece_index = 0; piece_index < 8; ++piece_index) {
|
||||
// 1. If address’s pieces[pieceIndex] is not 0:
|
||||
if (address[piece_index] != 0) {
|
||||
// 1. If foundSize is greater than longestSize, then set longestIndex to foundIndex and longestSize to foundSize.
|
||||
|
|
@ -110,7 +110,7 @@ static void serialize_ipv6_address(IPv6Address const& address, StringBuilder& ou
|
|||
auto ignore0 = false;
|
||||
|
||||
// 4. For each pieceIndex of address’s pieces’s indices:
|
||||
for (size_t piece_index = 0; piece_index < address.size(); ++piece_index) {
|
||||
for (size_t piece_index = 0; piece_index < 8; ++piece_index) {
|
||||
// 1. If ignore0 is true and address[pieceIndex] is 0, then continue.
|
||||
if (ignore0 && address[piece_index] == 0)
|
||||
continue;
|
||||
|
|
|
|||
|
|
@ -8,22 +8,13 @@
|
|||
#pragma once
|
||||
|
||||
#include <AK/Array.h>
|
||||
#include <AK/IPv4Address.h>
|
||||
#include <AK/IPv6Address.h>
|
||||
#include <AK/String.h>
|
||||
#include <AK/Types.h>
|
||||
|
||||
namespace URL {
|
||||
|
||||
// https://url.spec.whatwg.org/#concept-ipv4
|
||||
// An IPv4 address is a 32-bit unsigned integer that identifies a network address. [RFC791]
|
||||
// FIXME: It would be nice if this were an AK::IPv4Address
|
||||
using IPv4Address = u32;
|
||||
|
||||
// https://url.spec.whatwg.org/#concept-ipv6
|
||||
// An IPv6 address is a 128-bit unsigned integer that identifies a network address. For the purposes of this standard
|
||||
// it is represented as a list of eight 16-bit unsigned integers, also known as IPv6 pieces. [RFC4291]
|
||||
// FIXME: It would be nice if this were an AK::IPv6Address
|
||||
using IPv6Address = Array<u16, 8>;
|
||||
|
||||
// https://url.spec.whatwg.org/#concept-host
|
||||
// A host is a domain, an IP address, an opaque host, or an empty host. Typically a host serves as a network address,
|
||||
// but it is sometimes used as opaque identifier in URLs where a network address is not necessary.
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@
|
|||
#include <AK/ByteString.h>
|
||||
#include <AK/CharacterTypes.h>
|
||||
#include <AK/Debug.h>
|
||||
#include <AK/IPv4Address.h>
|
||||
#include <AK/IPv6Address.h>
|
||||
#include <AK/IntegralMath.h>
|
||||
#include <AK/Optional.h>
|
||||
#include <AK/SourceLocation.h>
|
||||
|
|
@ -226,7 +228,7 @@ static Optional<IPv4Address> parse_ipv4_address(StringView input)
|
|||
}
|
||||
|
||||
// 13. Return ipv4.
|
||||
return ipv4;
|
||||
return IPv4Address(ipv4);
|
||||
}
|
||||
|
||||
// https://url.spec.whatwg.org/#concept-ipv6-parser
|
||||
|
|
@ -455,7 +457,7 @@ static Optional<IPv6Address> parse_ipv6_address(StringView input)
|
|||
}
|
||||
|
||||
// 9. Return address.
|
||||
return address;
|
||||
return IPv6Address(address);
|
||||
}
|
||||
|
||||
// https://url.spec.whatwg.org/#ends-in-a-number-checker
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ void upgrade_a_mixed_content_request_to_a_potentially_trustworthy_url_if_appropr
|
|||
SecureContexts::is_url_potentially_trustworthy(request.url()) == SecureContexts::Trustworthiness::PotentiallyTrustworthy
|
||||
|
||||
// 2. request’s URL’s host is an IP address.
|
||||
|| (request.url().host().has_value() && (request.url().host()->has<URL::IPv4Address>() || request.url().host()->has<URL::IPv6Address>()))
|
||||
|| (request.url().host().has_value() && (request.url().host()->has<IPv4Address>() || request.url().host()->has<IPv6Address>()))
|
||||
|
||||
// 3. § 4.3 Does settings prohibit mixed security contexts? returns "Does Not Restrict Mixed Security Contents" when applied to request’s client.
|
||||
|| does_settings_prohibit_mixed_security_contexts(request.client()) == ProhibitsMixedSecurityContexts::DoesNotRestrictMixedSecurityContexts
|
||||
|
|
|
|||
|
|
@ -28,14 +28,12 @@ Trustworthiness is_origin_potentially_trustworthy(URL::Origin const& origin)
|
|||
return Trustworthiness::PotentiallyTrustworthy;
|
||||
|
||||
// 4. If origin’s host matches one of the CIDR notations 127.0.0.0/8 or ::1/128 [RFC4632], return "Potentially Trustworthy".
|
||||
// FIXME: This would be nicer if URL::IPv4Address and URL::IPv6Address were instances of AK::IPv4Address and AK::IPv6Address
|
||||
if (origin.host().has<URL::IPv4Address>()) {
|
||||
if ((origin.host().get<URL::IPv4Address>() & 0xff000000) != 0)
|
||||
if (origin.host().has<IPv4Address>()) {
|
||||
if ((origin.host().get<IPv4Address>().to_u32() & 0xff000000) != 0)
|
||||
return Trustworthiness::PotentiallyTrustworthy;
|
||||
} else if (origin.host().has<URL::IPv6Address>()) {
|
||||
auto ipv6_address = origin.host().get<URL::IPv6Address>();
|
||||
static constexpr URL::IPv6Address loopback { 0, 0, 0, 0, 0, 0, 0, 1 };
|
||||
if (ipv6_address == loopback)
|
||||
} else if (origin.host().has<IPv6Address>()) {
|
||||
auto ipv6_address = origin.host().get<IPv6Address>();
|
||||
if (ipv6_address == IPv6Address::loopback())
|
||||
return Trustworthiness::PotentiallyTrustworthy;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue