mirror of
https://github.com/guzzle/guzzle.git
synced 2025-01-29 11:17:44 +01:00
Merge pull request #2483 from gmponos/merge650-to-master
Merge 6.5 to master
This commit is contained in:
commit
b8310d23c8
@ -1,5 +1,10 @@
|
||||
# Change Log
|
||||
|
||||
## 6.5.1 - 2019-12-21
|
||||
|
||||
* Better defaults for PHP installations with old ICU lib [#2454](https://github.com/guzzle/guzzle/pull/2454)
|
||||
* IDN support for redirects [#2424](https://github.com/guzzle/guzzle/pull/2424)
|
||||
|
||||
## 6.5.0 - 2019-12-07
|
||||
|
||||
* Improvement: Added support for reset internal queue in MockHandler. [#2143](https://github.com/guzzle/guzzle/pull/2143)
|
||||
|
@ -561,7 +561,7 @@ idn_conversion
|
||||
:Types:
|
||||
- bool
|
||||
- int
|
||||
:Default: ``true`` if ``intl`` extension is available, ``false`` otherwise
|
||||
:Default: ``true`` if ``intl`` extension is available (and ICU library is 4.6+ for PHP 7.2+), ``false`` otherwise
|
||||
:Constant: ``GuzzleHttp\RequestOptions::IDN_CONVERSION``
|
||||
|
||||
.. code-block:: php
|
||||
|
@ -222,36 +222,9 @@ class Client implements ClientInterface, \Psr\Http\Client\ClientInterface
|
||||
$uri = Psr7\UriResolver::resolve(Psr7\uri_for($config['base_uri']), $uri);
|
||||
}
|
||||
|
||||
if ($uri->getHost() && isset($config['idn_conversion']) && ($config['idn_conversion'] !== false)) {
|
||||
if (isset($config['idn_conversion']) && ($config['idn_conversion'] !== false)) {
|
||||
$idnOptions = ($config['idn_conversion'] === true) ? IDNA_DEFAULT : $config['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);
|
||||
}
|
||||
}
|
||||
$uri = _idn_uri_convert($uri, $idnOptions);
|
||||
}
|
||||
|
||||
return $uri->getScheme() === '' && $uri->getHost() !== '' ? $uri->withScheme('http') : $uri;
|
||||
@ -271,7 +244,9 @@ class Client implements ClientInterface, \Psr\Http\Client\ClientInterface
|
||||
];
|
||||
|
||||
// idn_to_ascii() is a part of ext-intl and might be not available
|
||||
$defaults['idn_conversion'] = \function_exists('idn_to_ascii');
|
||||
// Old ICU versions don't have this constant, so we are basically stuck (see https://github.com/guzzle/guzzle/pull/2424
|
||||
// and https://github.com/guzzle/guzzle/issues/2448 for details)
|
||||
$defaults['idn_conversion'] = \function_exists('idn_to_ascii') && defined('INTL_IDNA_VARIANT_UTS46');
|
||||
|
||||
// Use the standard Linux HTTP_PROXY and HTTPS_PROXY if set.
|
||||
|
||||
|
@ -168,7 +168,13 @@ class RedirectMiddleware
|
||||
$modify['body'] = '';
|
||||
}
|
||||
|
||||
$modify['uri'] = $this->redirectUri($request, $response, $protocols);
|
||||
$uri = $this->redirectUri($request, $response, $protocols);
|
||||
if (isset($options['idn_conversion']) && ($options['idn_conversion'] !== false)) {
|
||||
$idnOptions = ($options['idn_conversion'] === true) ? IDNA_DEFAULT : $options['idn_conversion'];
|
||||
$uri = _idn_uri_convert($uri, $idnOptions);
|
||||
}
|
||||
|
||||
$modify['uri'] = $uri;
|
||||
Psr7\rewind_body($request);
|
||||
|
||||
// Add the Referer header if it is told to do so and only
|
||||
|
@ -1,10 +1,12 @@
|
||||
<?php
|
||||
namespace GuzzleHttp;
|
||||
|
||||
use GuzzleHttp\Exception\InvalidArgumentException;
|
||||
use GuzzleHttp\Handler\CurlHandler;
|
||||
use GuzzleHttp\Handler\CurlMultiHandler;
|
||||
use GuzzleHttp\Handler\Proxy;
|
||||
use GuzzleHttp\Handler\StreamHandler;
|
||||
use Psr\Http\Message\UriInterface;
|
||||
|
||||
/**
|
||||
* Debug function used to describe the provided value type and class.
|
||||
@ -312,3 +314,46 @@ function _current_time()
|
||||
{
|
||||
return \function_exists('hrtime') ? \hrtime(true) / 1e9 : \microtime(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $options
|
||||
*
|
||||
* @return UriInterface
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
function _idn_uri_convert(UriInterface $uri, $options = 0)
|
||||
{
|
||||
if ($uri->getHost()) {
|
||||
$idnaVariant = defined('INTL_IDNA_VARIANT_UTS46') ? INTL_IDNA_VARIANT_UTS46 : 0;
|
||||
$asciiHost = idn_to_ascii($uri->getHost(), $options, $idnaVariant, $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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $uri;
|
||||
}
|
||||
|
@ -5,11 +5,13 @@ use GuzzleHttp\Client;
|
||||
use GuzzleHttp\Cookie\CookieJar;
|
||||
use GuzzleHttp\Handler\MockHandler;
|
||||
use GuzzleHttp\HandlerStack;
|
||||
use GuzzleHttp\Middleware;
|
||||
use GuzzleHttp\Promise\PromiseInterface;
|
||||
use GuzzleHttp\Psr7;
|
||||
use GuzzleHttp\Psr7\Request;
|
||||
use GuzzleHttp\Psr7\Response;
|
||||
use GuzzleHttp\Psr7\Uri;
|
||||
use GuzzleHttp\RequestOptions;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
@ -764,4 +766,36 @@ class ClientTest extends TestCase
|
||||
self::assertSame('http://xn--d1acpjx3f.xn--p1ai/baz', (string) $mock->getLastRequest()->getUri());
|
||||
self::assertSame('xn--d1acpjx3f.xn--p1ai', (string) $mock->getLastRequest()->getHeaderLine('Host'));
|
||||
}
|
||||
|
||||
public function testIdnWithRedirect()
|
||||
{
|
||||
if (!extension_loaded('intl')) {
|
||||
self::markTestSkipped('intl PHP extension is not loaded');
|
||||
}
|
||||
$mockHandler = new MockHandler([
|
||||
new Response(302, ['Location' => 'http://www.tést.com/whatever']),
|
||||
new Response()
|
||||
]);
|
||||
$handler = HandlerStack::create($mockHandler);
|
||||
$requests = [];
|
||||
$handler->push(Middleware::history($requests));
|
||||
$client = new Client(['handler' => $handler]);
|
||||
|
||||
$client->request('GET', 'https://яндекс.рф/images', [
|
||||
RequestOptions::ALLOW_REDIRECTS => [
|
||||
'referer' => true,
|
||||
'track_redirects' => true
|
||||
],
|
||||
'idn_conversion' => true
|
||||
]);
|
||||
|
||||
$request = $mockHandler->getLastRequest();
|
||||
|
||||
self::assertSame('http://www.xn--tst-bma.com/whatever', (string) $request->getUri());
|
||||
self::assertSame('www.xn--tst-bma.com', (string) $request->getHeaderLine('Host'));
|
||||
|
||||
$request = $requests[0]['request'];
|
||||
self::assertSame('https://xn--d1acpjx3f.xn--p1ai/images', (string) $request->getUri());
|
||||
self::assertSame('xn--d1acpjx3f.xn--p1ai', (string) $request->getHeaderLine('Host'));
|
||||
}
|
||||
}
|
||||
|
@ -139,6 +139,17 @@ class FunctionsTest extends TestCase
|
||||
{
|
||||
self::assertGreaterThan(0, GuzzleHttp\_current_time());
|
||||
}
|
||||
|
||||
public function testIdnConvert()
|
||||
{
|
||||
if (!extension_loaded('intl')) {
|
||||
self::markTestSkipped('intl PHP extension is not loaded');
|
||||
}
|
||||
|
||||
$uri = GuzzleHttp\Psr7\uri_for('https://яндекс.рф/images');
|
||||
$uri = GuzzleHttp\_idn_uri_convert($uri);
|
||||
self::assertSame('xn--d1acpjx3f.xn--p1ai', $uri->getHost());
|
||||
}
|
||||
}
|
||||
|
||||
final class StrClass
|
||||
|
Loading…
x
Reference in New Issue
Block a user