Skip to content
Merged
22 changes: 21 additions & 1 deletion src/Http/Url.php
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ public function __construct($url = null)

$this->scheme = $p['scheme'] ?? '';
$this->port = $p['port'] ?? null;
$this->host = rawurldecode($p['host'] ?? '');
$this->host = self::idnHostToUnicode(rawurldecode($p['host'] ?? ''));
$this->user = rawurldecode($p['user'] ?? '');
$this->password = rawurldecode($p['pass'] ?? '');
$this->setPath($p['path'] ?? '');
Expand Down Expand Up @@ -363,6 +363,7 @@ public function isEqual($url): bool
/**
* Transforms URL to canonical form.
* @return static
* @deprecated
*/
public function canonicalize()
{
Expand Down Expand Up @@ -395,6 +396,25 @@ final public function export(): array
}


/**
* Convert IDN ASCII host to UTF-8.
* In case of an error, it returns the original input.
*
* @param int[]|null $info
*/
public static function idnHostToUnicode(string $host, int $options = 0, ?array &$info = []): string
{
if (strpos($host, '--') === false) { // host does not contain IDN
return $host;
}
if (\function_exists('idn_to_utf8') && \defined('INTL_IDNA_VARIANT_UTS46')) {
return \idn_to_utf8($host, $options, \INTL_IDNA_VARIANT_UTS46, $info) ?: $host;
}

throw new \Error('ext-idn not loaded or too old.');
}


/**
* Similar to rawurldecode, but preserves reserved chars encoded.
*/
Expand Down