5d84ffbebb
Rewrite `parseIPv4Address` and `parseIPv6Address` to not do so much unnecessary allocation and copying. This is a breaking change if someone, somewhere, depends on parsing IPv4 addresses with leading zeros. Neither RFC 3986 or the WhatWG URL spec allows leading zeros, so it wouldn't work anywhere else. Because of that, it's not expected to be breaking in practice. Fixes #61392. BUG= https://dartbug.com/61392 Change-Id: I045353d5d1606795048e12ee12cd12b30dbf8ab3 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/447260 Commit-Queue: Lasse Nielsen <lrn@google.com> Reviewed-by: Ömer Ağacan <omersa@google.com> Reviewed-by: Slava Egorov <vegorov@google.com> Reviewed-by: Stephen Adams <sra@google.com>
551 lines
16 KiB
Dart
551 lines
16 KiB
Dart
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
|
|
// for details. All rights reserved. Use of this source code is governed by a
|
|
// BSD-style license that can be found in the LICENSE file.
|
|
|
|
import 'package:expect/expect.dart';
|
|
|
|
import 'uri_ipv4_test.dart' as ipv4 show passSamples, failSamples;
|
|
|
|
void testValidIpv6Uri() {
|
|
var path = 'http://[::1]:1234/path?query=5#now';
|
|
var uri = Uri.parse(path);
|
|
Expect.equals('http', uri.scheme);
|
|
Expect.equals('::1', uri.host);
|
|
Expect.equals(1234, uri.port);
|
|
Expect.equals('/path', uri.path);
|
|
Expect.equals('query=5', uri.query);
|
|
Expect.equals('now', uri.fragment);
|
|
Expect.equals(path, uri.toString());
|
|
|
|
path = 'http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:8080/index.html';
|
|
uri = Uri.parse(path);
|
|
Expect.equals('http', uri.scheme);
|
|
Expect.equals('fedc:ba98:7654:3210:fedc:ba98:7654:3210', uri.host);
|
|
Expect.equals(8080, uri.port);
|
|
Expect.equals('/index.html', uri.path);
|
|
Expect.equals(path.toLowerCase(), uri.toString());
|
|
|
|
path = 'http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80/index.html';
|
|
uri = Uri.parse(path);
|
|
Expect.equals('http', uri.scheme);
|
|
Expect.equals('fedc:ba98:7654:3210:fedc:ba98:7654:3210', uri.host);
|
|
Expect.equals(80, uri.port);
|
|
Expect.equals('/index.html', uri.path);
|
|
Expect.equals(
|
|
'http://[fedc:ba98:7654:3210:fedc:ba98:7654:3210]/index.html',
|
|
uri.toString(),
|
|
);
|
|
|
|
path = 'https://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:443/index.html';
|
|
uri = Uri.parse(path);
|
|
Expect.equals('https', uri.scheme);
|
|
Expect.equals('fedc:ba98:7654:3210:fedc:ba98:7654:3210', uri.host);
|
|
Expect.equals(443, uri.port);
|
|
Expect.equals('/index.html', uri.path);
|
|
Expect.equals(
|
|
'https://[fedc:ba98:7654:3210:fedc:ba98:7654:3210]/index.html',
|
|
uri.toString(),
|
|
);
|
|
|
|
path = 'http://[1080:0:0:0:8:800:200C:417A]/index.html';
|
|
uri = Uri.parse(path);
|
|
Expect.equals('http', uri.scheme);
|
|
Expect.equals('1080:0:0:0:8:800:200c:417a', uri.host);
|
|
Expect.equals(80, uri.port);
|
|
Expect.equals('/index.html', uri.path);
|
|
Expect.equals(path.toLowerCase(), uri.toString());
|
|
|
|
path = 'http://[3ffe:2a00:100:7031::1]';
|
|
uri = Uri.parse(path);
|
|
Expect.equals('http', uri.scheme);
|
|
Expect.equals('3ffe:2a00:100:7031::1', uri.host);
|
|
Expect.equals(80, uri.port);
|
|
Expect.equals('', uri.path);
|
|
Expect.equals(path, uri.toString());
|
|
|
|
path = 'http://[1080::8:800:200C:417A]/foo';
|
|
uri = Uri.parse(path);
|
|
Expect.equals('http', uri.scheme);
|
|
Expect.equals('1080::8:800:200c:417a', uri.host);
|
|
Expect.equals(80, uri.port);
|
|
Expect.equals('/foo', uri.path);
|
|
Expect.equals(path.toLowerCase(), uri.toString());
|
|
|
|
path = 'http://[::192.9.5.5]/ipng';
|
|
uri = Uri.parse(path);
|
|
Expect.equals('http', uri.scheme);
|
|
Expect.equals('::192.9.5.5', uri.host);
|
|
Expect.equals(80, uri.port);
|
|
Expect.equals('/ipng', uri.path);
|
|
Expect.equals(path, uri.toString());
|
|
|
|
path = 'http://[::FFFF:129.144.52.38]:8080/index.html';
|
|
uri = Uri.parse(path);
|
|
Expect.equals('http', uri.scheme);
|
|
Expect.equals('::ffff:129.144.52.38', uri.host);
|
|
Expect.equals(8080, uri.port);
|
|
Expect.equals('/index.html', uri.path);
|
|
Expect.equals(path.toLowerCase(), uri.toString());
|
|
|
|
path = 'http://[::FFFF:129.144.52.38]:80/index.html';
|
|
uri = Uri.parse(path);
|
|
Expect.equals('http', uri.scheme);
|
|
Expect.equals('::ffff:129.144.52.38', uri.host);
|
|
Expect.equals(80, uri.port);
|
|
Expect.equals('/index.html', uri.path);
|
|
Expect.equals('http://[::ffff:129.144.52.38]/index.html', uri.toString());
|
|
|
|
path = 'https://[::FFFF:129.144.52.38]:443/index.html';
|
|
uri = Uri.parse(path);
|
|
Expect.equals('https', uri.scheme);
|
|
Expect.equals('::ffff:129.144.52.38', uri.host);
|
|
Expect.equals(443, uri.port);
|
|
Expect.equals('/index.html', uri.path);
|
|
Expect.equals('https://[::ffff:129.144.52.38]/index.html', uri.toString());
|
|
|
|
path = 'http://[2010:836B:4179::836B:4179]';
|
|
uri = Uri.parse(path);
|
|
Expect.equals('http', uri.scheme);
|
|
Expect.equals('2010:836b:4179::836b:4179', uri.host);
|
|
Expect.equals(80, uri.port);
|
|
Expect.equals('', uri.path);
|
|
Expect.equals(path.toLowerCase(), uri.toString());
|
|
|
|
// Checks for ZoneID in RFC 6874
|
|
path = 'https://[fe80::a%en1]:443/index.html';
|
|
uri = Uri.parse(path);
|
|
Expect.equals('https', uri.scheme);
|
|
Expect.equals('fe80::a%25en1', uri.host);
|
|
Expect.equals(443, uri.port);
|
|
Expect.equals('/index.html', uri.path);
|
|
Expect.equals('https://[fe80::a%25en1]/index.html', uri.toString());
|
|
|
|
path = 'https://[fe80::a%25eE1]:443/index.html';
|
|
uri = Uri.parse(path);
|
|
Expect.equals('https', uri.scheme);
|
|
Expect.equals('fe80::a%25eE1', uri.host);
|
|
Expect.equals(443, uri.port);
|
|
Expect.equals('/index.html', uri.path);
|
|
Expect.equals('https://[fe80::a%25eE1]/index.html', uri.toString());
|
|
|
|
// Recognize bare '%' and transform into '%25'
|
|
path = 'https://[fe80::a%1]:443/index.html';
|
|
uri = Uri.parse(path);
|
|
Expect.equals('https', uri.scheme);
|
|
Expect.equals('fe80::a%251', uri.host);
|
|
Expect.equals(443, uri.port);
|
|
Expect.equals('/index.html', uri.path);
|
|
Expect.equals('https://[fe80::a%251]/index.html', uri.toString());
|
|
|
|
path = 'https://[ff02::5678%pvc1.3]/index.html';
|
|
uri = Uri.parse(path);
|
|
Expect.equals('https', uri.scheme);
|
|
Expect.equals('ff02::5678%25pvc1.3', uri.host);
|
|
Expect.equals('/index.html', uri.path);
|
|
Expect.equals('https://[ff02::5678%25pvc1.3]/index.html', uri.toString());
|
|
|
|
// ZoneID contains percent encoded
|
|
path = 'https://[ff02::1%%321]/index.html';
|
|
uri = Uri.parse(path);
|
|
Expect.equals('https', uri.scheme);
|
|
Expect.equals('ff02::1%2521', uri.host);
|
|
Expect.equals('/index.html', uri.path);
|
|
Expect.equals('https://[ff02::1%2521]/index.html', uri.toString());
|
|
|
|
path = 'https://[ff02::1%321]/index.html';
|
|
uri = Uri.parse(path);
|
|
Expect.equals('https', uri.scheme);
|
|
Expect.equals('ff02::1%25321', uri.host);
|
|
Expect.equals('/index.html', uri.path);
|
|
Expect.equals('https://[ff02::1%25321]/index.html', uri.toString());
|
|
|
|
// Lower cases
|
|
path = 'https://[ff02::1%1%41]/index.html';
|
|
uri = Uri.parse(path);
|
|
Expect.equals('https', uri.scheme);
|
|
Expect.equals('ff02::1%251a', uri.host);
|
|
Expect.equals('/index.html', uri.path);
|
|
Expect.equals('https://[ff02::1%251a]/index.html', uri.toString());
|
|
|
|
path = 'https://[fe80::8eae:4c4d:fee9:8434%rename3]/index.html';
|
|
uri = Uri.parse(path);
|
|
Expect.equals('https', uri.scheme);
|
|
Expect.equals('fe80::8eae:4c4d:fee9:8434%25rename3', uri.host);
|
|
Expect.equals('/index.html', uri.path);
|
|
Expect.equals(
|
|
'https://[fe80::8eae:4c4d:fee9:8434%25rename3]/index.html',
|
|
uri.toString(),
|
|
);
|
|
|
|
// Test constructors with host name
|
|
uri = Uri(scheme: 'https', host: '[ff02::5678%pvc1.3]');
|
|
uri = Uri(scheme: 'https', host: '[fe80::a%1]');
|
|
uri = Uri(scheme: 'https', host: '[fe80::a%25eE1]');
|
|
uri = Uri(scheme: 'https', host: '[fe80::a%en1]');
|
|
}
|
|
|
|
void testParseIPv6Address() {
|
|
for (var i = 0; i < passSamples.length; i++) {
|
|
var sample = passSamples[i];
|
|
passIPv6(sample.host, sample.out);
|
|
}
|
|
|
|
for (var i = 0; i < failSamples.length; i++) {
|
|
var sample = failSamples[i];
|
|
failIPv6(sample);
|
|
}
|
|
|
|
for (var i = 0; i < ipv4.passSamples.length; i++) {
|
|
var sample = ipv4.passSamples[i];
|
|
var host = sample.host;
|
|
passIPv4inIPv6(host, sample.out);
|
|
|
|
// Invalid positions of valid IPv4.
|
|
// IPv4 alone.
|
|
failIPv6(host);
|
|
// IPv4 first.
|
|
failIPv6('$host:3:4:5:6:7:8');
|
|
failIPv6('$host::8');
|
|
// IPv4 in the middle.
|
|
failIPv6('1:2:3:$host:6:7:8:');
|
|
failIPv6('::3:$host:6:7:8:');
|
|
failIPv6('1:2:3:$host:6::');
|
|
// Too long with IPv4.
|
|
failIPv6('1:2:3:4:5:6:7::$host');
|
|
failIPv6('::1:2:3:4:5:6:$host');
|
|
failIPv6('1:2:3:4::5:6:$host');
|
|
failIPv6('1:2:3:4:5:6::$host');
|
|
// Too short with IPv4 and no wildcard.
|
|
failIPv6('1:2:3:4:5:$host');
|
|
failIPv6('1:$host');
|
|
// Too short or long with IPv4, longer parts.
|
|
failIPv6('2010:836B:4179:0000:$host');
|
|
failIPv6('2010:836B:4179:0000:0000:$host');
|
|
failIPv6('2010:836B:4179:0000:0000:0000::$host');
|
|
failIPv6('2010:836B:4179:0000:0000:0000:0000:$host');
|
|
}
|
|
|
|
for (var i = 0; i < ipv4.failSamples.length; i++) {
|
|
var sample = ipv4.failSamples[i];
|
|
// Avoid anything that would be valid as non-IPv4 after a `::`.
|
|
// Heuristically that's "nothing" or hex digits.
|
|
if (sample.isEmpty ||
|
|
(sample.trim() == sample && int.tryParse(sample, radix: 16) != null)) {
|
|
continue;
|
|
}
|
|
failIPv4inIPv6(sample);
|
|
}
|
|
}
|
|
|
|
void failIPv6(String host) {
|
|
void failWrap(String prefix, String suffix) {
|
|
var wrapped = "$prefix$host$suffix";
|
|
var start = prefix.length;
|
|
var end = start + host.length;
|
|
Expect.throwsFormatException(
|
|
() => Uri.parseIPv6Address(wrapped, start, end),
|
|
wrapped,
|
|
);
|
|
}
|
|
|
|
failWrap('', '');
|
|
failWrap('xyz', '');
|
|
failWrap('', 'xyz');
|
|
failWrap('0', '0');
|
|
failWrap(':', ':');
|
|
failWrap('::', '::');
|
|
failWrap('0:', ':0');
|
|
failWrap('', '.0');
|
|
failWrap('', '.0.0.0.0');
|
|
}
|
|
|
|
void passIPv4inIPv6(String ipv4Host, List<int> ipv4Bytes) {
|
|
// No wildcard.
|
|
passIPv6('1234:5678:9abc:def0:8765:4321:$ipv4Host', [
|
|
0x12,
|
|
0x34,
|
|
0x56,
|
|
0x78,
|
|
0x9a,
|
|
0xbc,
|
|
0xde,
|
|
0xf0,
|
|
0x87,
|
|
0x65,
|
|
0x43,
|
|
0x21,
|
|
...ipv4Bytes,
|
|
]);
|
|
// Wildcards.
|
|
passIPv6('::$ipv4Host', [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ...ipv4Bytes]);
|
|
passIPv6('0::$ipv4Host', [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ...ipv4Bytes]);
|
|
passIPv6('::0:$ipv4Host', [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ...ipv4Bytes]);
|
|
passIPv6('0000::FFFF:$ipv4Host', [
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0xFF,
|
|
0xFF,
|
|
...ipv4Bytes,
|
|
]);
|
|
}
|
|
|
|
void failIPv4inIPv6(String ipv4Host) {
|
|
failIPv6('::$ipv4Host');
|
|
failIPv6('0::$ipv4Host');
|
|
failIPv6('::0:$ipv4Host');
|
|
failIPv6('::FFFF:$ipv4Host');
|
|
failIPv6('1234:5678:9abc:def0:8765:4321:$ipv4Host');
|
|
}
|
|
|
|
const ____ = 0; // Used to represent wildcard fills below.
|
|
/// Samples containing IPv4 are generated from [ipv4.passSamples].
|
|
const List<({String host, List<int> out})> passSamples = [
|
|
// Upper and lower case both allowed.
|
|
(
|
|
host: 'abcd:efAB:CDEF:aBcD:eFAb:CdEf:aAaA:bBbB',
|
|
out: [
|
|
0xab, 0xcd, 0xef, 0xab, 0xcd, 0xef, 0xab, 0xcd, //
|
|
0xef, 0xab, 0xcd, 0xef, 0xaa, 0xaa, 0xbb, 0xbb,
|
|
],
|
|
),
|
|
// 1-4 digits allowed, leading zeros allowed.
|
|
(
|
|
host: 'a:bc:def:1234:0a:00b:000c:0de',
|
|
out: [
|
|
0x00, 0x0a, 0x00, 0xbc, 0x0d, 0xef, 0x12, 0x34, //
|
|
0x00, 0x0a, 0x00, 0x0b, 0x00, 0x0c, 0x00, 0xde,
|
|
],
|
|
),
|
|
//
|
|
// Wildcard positions and sizes.
|
|
// No wildcard.
|
|
(
|
|
host: '1223:3445:5667:7889:9aab:bccd:deef:f001',
|
|
out: [
|
|
0x12, 0x23, 0x34, 0x45, 0x56, 0x67, 0x78, 0x89, //
|
|
0x9a, 0xab, 0xbc, 0xcd, 0xde, 0xef, 0xf0, 0x01,
|
|
],
|
|
),
|
|
// At start.
|
|
(
|
|
host: '::3445:5667:7889:9aab:bccd:deef:f001',
|
|
out: [
|
|
____, ____, 0x34, 0x45, 0x56, 0x67, 0x78, 0x89, //
|
|
0x9a, 0xab, 0xbc, 0xcd, 0xde, 0xef, 0xf0, 0x01,
|
|
],
|
|
),
|
|
(
|
|
host: '::f001',
|
|
out: [
|
|
____, ____, ____, ____, ____, ____, ____, ____, //
|
|
____, ____, ____, ____, ____, ____, 0xf0, 0x01,
|
|
],
|
|
),
|
|
// In middle
|
|
(
|
|
host: '1223:3445:5667:7889::bccd:deef:f001',
|
|
out: [
|
|
0x12, 0x23, 0x34, 0x45, 0x56, 0x67, 0x78, 0x89, //
|
|
____, ____, 0xbc, 0xcd, 0xde, 0xef, 0xf0, 0x01,
|
|
],
|
|
),
|
|
(
|
|
host: '1223::f001',
|
|
out: [
|
|
0x12, 0x23, ____, ____, ____, ____, ____, ____, //
|
|
____, ____, ____, ____, ____, ____, 0xf0, 0x01,
|
|
],
|
|
),
|
|
// At end
|
|
(
|
|
host: '1223:3445:5667:7889:9aab:bccd:deef::',
|
|
out: [
|
|
0x12, 0x23, 0x34, 0x45, 0x56, 0x67, 0x78, 0x89, //
|
|
0x9a, 0xab, 0xbc, 0xcd, 0xde, 0xef, ____, ____,
|
|
],
|
|
),
|
|
(
|
|
host: '1223::',
|
|
out: [
|
|
0x12, 0x23, ____, ____, ____, ____, ____, ____, //
|
|
____, ____, ____, ____, ____, ____, ____, ____,
|
|
],
|
|
),
|
|
// All.
|
|
(
|
|
host: '::',
|
|
out: [
|
|
____, ____, ____, ____, ____, ____, ____, ____, //
|
|
____, ____, ____, ____, ____, ____, ____, ____,
|
|
],
|
|
),
|
|
];
|
|
|
|
const List<String> failSamples = [
|
|
'', // No part
|
|
':', // Empty leading part, at end.
|
|
':0::', // Leading `:`.
|
|
'0::0:', // trailing colon.
|
|
// More than two `:`s
|
|
':::',
|
|
'0:::0',
|
|
// More than one wildcard.
|
|
'::0::',
|
|
'0::0::0',
|
|
// More than four digits in a part.
|
|
'00000::0',
|
|
'0::00000',
|
|
'0.0.0.0.00000.0.0.0',
|
|
// Negative
|
|
'-1::0',
|
|
'0::-1',
|
|
'0:0:0:-1:0:0:0:0',
|
|
'-AAA::0',
|
|
// Too long without wildcard.
|
|
'1:2:3:4:5:6:7:8:9',
|
|
// Too long with wildcard.
|
|
'::1:2:3:4:5:6:7:8',
|
|
'1:2:3:4::5:6:7:8',
|
|
'1:2:3:4:5:6:7:8::',
|
|
];
|
|
|
|
void testPropagateIPv6() {
|
|
// A regression test for https://dartbug.com/55085
|
|
|
|
// A "Normal" URI. Simple URIs cannot have IPv6 addresses.
|
|
var ipv6Uri = Uri.parse("s://u:p@[::127.0.0.1]:1/p1/p2?q#f");
|
|
|
|
// A non-IPv6 URI.
|
|
var plainUri = Uri.parse("s2://u2:p2@host:2/p3/p4?q2#f2");
|
|
|
|
void expectSame(Uri expected, Uri actual) {
|
|
Expect.equals(expected, actual, "URI equality");
|
|
Expect.equals(
|
|
expected.toString(),
|
|
actual.toString(),
|
|
"URI.toString() equality",
|
|
);
|
|
}
|
|
|
|
Expect.equals("s://u:p@[::127.0.0.1]:1/p1/p2?q#f", ipv6Uri.toString());
|
|
Expect.equals("::127.0.0.1", ipv6Uri.host);
|
|
Expect.equals("u:p", ipv6Uri.userInfo);
|
|
Expect.equals(1, ipv6Uri.port);
|
|
|
|
// Using resolve to change parts of an IPv6 URI.
|
|
expectSame(
|
|
Uri.parse("s://u:p@[::127.0.0.1]:1/p1/p2?q#f2"),
|
|
ipv6Uri.resolve("#f2"),
|
|
);
|
|
expectSame(
|
|
Uri.parse("s://u:p@[::127.0.0.1]:1/p1/p2?q2#f2"),
|
|
ipv6Uri.resolve("?q2#f2"),
|
|
);
|
|
expectSame(
|
|
Uri.parse("s://u:p@[::127.0.0.1]:1/p1/p3?q2#f2"),
|
|
ipv6Uri.resolve("p3?q2#f2"),
|
|
);
|
|
expectSame(
|
|
Uri.parse("s://u:p@[::127.0.0.1]:1/p3/p4?q2#f2"),
|
|
ipv6Uri.resolve("/p3/p4?q2#f2"),
|
|
);
|
|
expectSame(
|
|
Uri.parse("s://u:p@[::127.0.0.1]:1/p3/p4?q2#f2"),
|
|
ipv6Uri.resolve("/p3/p4?q2#f2"),
|
|
);
|
|
expectSame(
|
|
Uri.parse("s://u2:p2@192.168.0.1:2/p3/p4?q2#f2"),
|
|
ipv6Uri.resolve("//u2:p2@192.168.0.1:2/p3/p4?q2#f2"),
|
|
);
|
|
expectSame(
|
|
Uri.parse("s2://u2:p2@192.168.0.1:2/p3/p4?q2#f2"),
|
|
ipv6Uri.resolve("s2://u2:p2@192.168.0.1:2/p3/p4?q2#f2"),
|
|
);
|
|
|
|
// Using resolve to change parts to an IPv6 URI.
|
|
expectSame(
|
|
Uri.parse("s2://u:p@[::127.0.0.1]:1/p1/p2?q#f"),
|
|
plainUri.resolve("//u:p@[::127.0.0.1]:1/p1/p2?q#f"),
|
|
);
|
|
expectSame(
|
|
Uri.parse("s://u:p@[::127.0.0.1]:1/p1/p2?q#f"),
|
|
plainUri.resolveUri(ipv6Uri),
|
|
);
|
|
|
|
// Using replace to change non-host parts of an IPv6 URI.
|
|
expectSame(
|
|
Uri.parse("s2://u:p@[::127.0.0.1]:1/p1/p2?q#f"),
|
|
ipv6Uri.replace(scheme: "s2"),
|
|
);
|
|
expectSame(
|
|
Uri.parse("s://u:p@[::127.0.0.1]:2/p1/p2?q#f"),
|
|
ipv6Uri.replace(port: 2),
|
|
);
|
|
expectSame(
|
|
Uri.parse("s://u:p@[::127.0.0.1]:1/p3/p4?q#f"),
|
|
ipv6Uri.replace(path: "p3/p4"),
|
|
);
|
|
expectSame(
|
|
Uri.parse("s://u:p@[::127.0.0.1]:1?q#f"),
|
|
ipv6Uri.replace(path: ""),
|
|
);
|
|
expectSame(
|
|
Uri.parse("s://u:p@[::127.0.0.1]:1/p1/p2?q2#f"),
|
|
ipv6Uri.replace(query: "q2"),
|
|
);
|
|
expectSame(
|
|
Uri.parse("s://u:p@[::127.0.0.1]:1/p1/p2?q#f2"),
|
|
ipv6Uri.replace(fragment: "f2"),
|
|
);
|
|
// Replacing the host to or from an IPv6 address.
|
|
expectSame(
|
|
Uri.parse("s://u:p@host:1/p1/p2?q#f"),
|
|
ipv6Uri.replace(host: "host"),
|
|
);
|
|
expectSame(
|
|
Uri.parse("s2://u2:p2@[::127.0.0.1]:2/p3/p4?q2#f2"),
|
|
plainUri.replace(host: "[::127.0.0.1]"),
|
|
);
|
|
expectSame(
|
|
Uri.parse("s2://u2:p2@[::127.0.0.1]:2/p3/p4?q2#f2"),
|
|
plainUri.replace(host: "::127.0.0.1"),
|
|
);
|
|
|
|
// Removing fragment.
|
|
expectSame(
|
|
Uri.parse("s://u:p@[::127.0.0.1]:1/p1/p2?q"),
|
|
ipv6Uri.removeFragment(),
|
|
);
|
|
}
|
|
|
|
void main() {
|
|
testValidIpv6Uri();
|
|
testParseIPv6Address();
|
|
testPropagateIPv6();
|
|
}
|
|
|
|
void passIPv6(String host, List<int> expected) {
|
|
_passIPv6(expected, host, 0, host.length);
|
|
_passIPv6(expected, '0${host}0', 1, host.length + 1);
|
|
_passIPv6(expected, ':${host}:', 1, host.length + 1);
|
|
_passIPv6(expected, '${host}.0', 0, host.length);
|
|
_passIPv6(expected, '0x${host}x0', 2, host.length + 2);
|
|
}
|
|
|
|
void _passIPv6(List<int> expected, String input, int start, int end) {
|
|
try {
|
|
Expect.listEquals(expected, Uri.parseIPv6Address(input, start, end), input);
|
|
} on Object {
|
|
print("Failed: $input[$start..$end]");
|
|
rethrow;
|
|
}
|
|
}
|