Skip to content

Commit 6babab5

Browse files
committed
Normalize host to lowercase
1 parent a1bf717 commit 6babab5

File tree

3 files changed

+23
-20
lines changed

3 files changed

+23
-20
lines changed

interfaces/Encoder.php

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -296,15 +296,16 @@ public static function normalizeHost(Stringable|string|null $host): ?string
296296
$host = (string) $host;
297297
}
298298

299-
if (null === $host || '' === $host) {
300-
return $host;
301-
}
302-
303-
if (false !== filter_var($host, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) || IPv6Converter::isIpv6($host)) {
299+
if (null === $host || '' === $host || false !== filter_var($host, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
304300
return $host;
305301
}
306302

307303
$host = strtolower($host);
304+
if (IPv6Converter::isIpv6($host)) {
305+
[$ipAddress, $zoneIdentifier] = explode('%', $host) + [1 => null];
306+
307+
return IPv6Converter::build(['ipAddress' => strtolower((string) $ipAddress), 'zoneIdentifier' => $zoneIdentifier]);
308+
}
308309

309310
return (!str_contains($host, '%')) ? $host : preg_replace_callback(
310311
'/%[a-fA-F0-9]{2}/',

interfaces/IPv6/Converter.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ public static function expand(Stringable|string|null $host): ?string
8484
return self::build($components);
8585
}
8686

87-
private static function build(array $components): string
87+
public static function build(array $components): string
8888
{
8989
$components['ipAddress'] ??= null;
9090
$components['zoneIdentifier'] ??= null;

interfaces/UriString.php

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -296,20 +296,22 @@ public static function parseNormalized(Stringable|string $uri): array
296296
static $isSupported = null;
297297
$isSupported ??= (function_exists('\idn_to_ascii') && defined('\INTL_IDNA_VARIANT_UTS46'));
298298

299-
if (null !== $components['host'] &&
300-
false === filter_var($components['host'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) &&
301-
!IPv6Converter::isIpv6($components['host'])
302-
) {
303-
$decodedHost = rawurldecode($components['host']);
304-
$components['host'] = (string) preg_replace_callback(
305-
'/%[0-9A-F]{2}/i',
306-
fn (array $matches): string => strtoupper($matches[0]),
307-
strtolower($components['host'])
308-
);
309-
if ($isSupported) {
310-
$host = IdnaConverter::toAscii($decodedHost);
311-
if (!$host->hasErrors()) {
312-
$components['host'] = $host->domain();
299+
if (null !== $components['host'] && false === filter_var($components['host'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
300+
// if host is IPv6 it should be lowercased according to
301+
// https://www.rfc-editor.org/rfc/rfc5952#section-4.3
302+
$components['host'] = strtolower($components['host']);
303+
if (!IPv6Converter::isIpv6($components['host'])) {
304+
$decodedHost = rawurldecode($components['host']);
305+
$components['host'] = (string) preg_replace_callback(
306+
'/%[0-9A-F]{2}/i',
307+
fn (array $matches): string => strtoupper($matches[0]),
308+
$components['host']
309+
);
310+
if ($isSupported) {
311+
$host = IdnaConverter::toAscii($decodedHost);
312+
if (!$host->hasErrors()) {
313+
$components['host'] = $host->domain();
314+
}
313315
}
314316
}
315317
}

0 commit comments

Comments
 (0)