Skip to content

Commit

Permalink
Add IDN support for redirects also
Browse files Browse the repository at this point in the history
  • Loading branch information
gmponos committed Dec 8, 2019
1 parent dbc2bc3 commit 3aded4a
Showing 1 changed file with 36 additions and 1 deletion.
37 changes: 36 additions & 1 deletion src/RedirectMiddleware.php
Expand Up @@ -2,6 +2,7 @@
namespace GuzzleHttp;

use GuzzleHttp\Exception\BadResponseException;
use GuzzleHttp\Exception\InvalidArgumentException;
use GuzzleHttp\Exception\TooManyRedirectsException;
use GuzzleHttp\Promise\PromiseInterface;
use GuzzleHttp\Psr7;
Expand Down Expand Up @@ -190,7 +191,41 @@ public function modifyRequest(
$modify['body'] = '';
}

$modify['uri'] = $this->redirectUri($request, $response, $protocols);
$uri = $this->redirectUri($request, $response, $protocols);

if ($uri->getHost() && isset($options['idn_conversion']) && ($options['idn_conversion'] !== false)) {
$idnOptions = ($options['idn_conversion'] === true) ? IDNA_DEFAULT : $options['idn_conversion'];

$asciiHost = idn_to_ascii($uri->getHost(), $idnOptions, INTL_IDNA_VARIANT_UTS46, $info);
if ($asciiHost === false) {
$errorBitSet = isset($info['errors']) ? $info['errors'] : 0;

$errorConstants = array_filter(array_keys(get_defined_constants()), function ($name) {
return substr($name, 0, 11) === 'IDNA_ERROR_';
});

$errors = [];
foreach ($errorConstants as $errorConstant) {
if ($errorBitSet & constant($errorConstant)) {
$errors[] = $errorConstant;
}
}

$errorMessage = 'IDN conversion failed';
if ($errors) {
$errorMessage .= ' (errors: ' . implode(', ', $errors) . ')';
}

throw new InvalidArgumentException($errorMessage);
} else {
if ($uri->getHost() !== $asciiHost) {
// Replace URI only if the ASCII version is different
$uri = $uri->withHost($asciiHost);
}
}
}

$modify['uri'] = $uri;
Psr7\rewind_body($request);

// Add the Referer header if it is told to do so and only
Expand Down

0 comments on commit 3aded4a

Please sign in to comment.