diff --git a/core/composer.json b/core/composer.json index 45e0742..4623e16 100644 --- a/core/composer.json +++ b/core/composer.json @@ -22,7 +22,7 @@ "twig/twig": "1.18.*", "doctrine/common": "~2.4.2", "doctrine/annotations": "1.2.*", - "guzzlehttp/guzzle": "~6.0", + "guzzlehttp/guzzle": "dev-master", "symfony-cmf/routing": "1.3.*", "easyrdf/easyrdf": "0.9.*", "phpunit/phpunit": "4.6.*", diff --git a/core/composer.lock b/core/composer.lock index cfb5145..a1cd7ba 100644 --- a/core/composer.lock +++ b/core/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "86c37f88b0879f2efa54f6b3f683d303", + "hash": "aedf5687c5d469a84a84d264be125f78", "packages": [ { "name": "behat/mink", @@ -785,16 +785,16 @@ }, { "name": "guzzlehttp/guzzle", - "version": "6.0.2", + "version": "dev-master", "source": { "type": "git", "url": "https://github.com/guzzle/guzzle.git", - "reference": "a8dfeff00eb84616a17fea7a4d72af35e750410f" + "reference": "1879fbe853b0c64d109e369c7aeff09849e62d1e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/a8dfeff00eb84616a17fea7a4d72af35e750410f", - "reference": "a8dfeff00eb84616a17fea7a4d72af35e750410f", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/1879fbe853b0c64d109e369c7aeff09849e62d1e", + "reference": "1879fbe853b0c64d109e369c7aeff09849e62d1e", "shasum": "" }, "require": { @@ -843,7 +843,7 @@ "rest", "web service" ], - "time": "2015-07-04 20:09:24" + "time": "2015-07-10 20:04:21" }, { "name": "guzzlehttp/promises", @@ -3415,6 +3415,7 @@ "aliases": [], "minimum-stability": "dev", "stability-flags": { + "guzzlehttp/guzzle": 20, "behat/mink-goutte-driver": 20 }, "prefer-stable": true, diff --git a/core/lib/Drupal/Core/Http/Client.php b/core/lib/Drupal/Core/Http/Client.php index c6b8da6..f225f45 100644 --- a/core/lib/Drupal/Core/Http/Client.php +++ b/core/lib/Drupal/Core/Http/Client.php @@ -10,11 +10,7 @@ use Drupal\Component\Utility\NestedArray; use Drupal\Core\Site\Settings; use GuzzleHttp\Client as GuzzleClient; -use GuzzleHttp\Handler\Proxy; use GuzzleHttp\HandlerStack; -use GuzzleHttp\Middleware; -use Psr\Http\Message\RequestInterface; -use Psr\Http\Message\ResponseInterface; use Symfony\Component\DependencyInjection\ContainerInterface; /** @@ -31,13 +27,6 @@ public function __construct(HandlerStack $stack, ContainerInterface $container, foreach ($service_ids as $id) { $stack->push($container->get($id)->register()); } - $stack->after('allow_redirects', Middleware::mapRequest(function (RequestInterface $request) { - $this->effectiveUrl = $request->getUri(); - return $request; - }), 'check_redirect'); - $stack->after('allow_redirects', Middleware::mapResponse(function (ResponseInterface $response) { - return $response->withHeader('X-Effective-Url', (string) $this->effectiveUrl); - }), 'store_redirect'); $default_config = array( // Security consideration: we must not use the certificate authority // file shipped with Guzzle because it can easily get outdated if a diff --git a/core/modules/aggregator/src/Plugin/aggregator/fetcher/DefaultFetcher.php b/core/modules/aggregator/src/Plugin/aggregator/fetcher/DefaultFetcher.php index 80d36bd..b242519 100644 --- a/core/modules/aggregator/src/Plugin/aggregator/fetcher/DefaultFetcher.php +++ b/core/modules/aggregator/src/Plugin/aggregator/fetcher/DefaultFetcher.php @@ -10,10 +10,13 @@ use Drupal\aggregator\Plugin\FetcherInterface; use Drupal\aggregator\FeedInterface; use Drupal\Component\Datetime\DateTimePlus; +use Drupal\Core\Http\ClientFactory; use Drupal\Core\Plugin\ContainerFactoryPluginInterface; -use GuzzleHttp\ClientInterface; use GuzzleHttp\Exception\RequestException; use GuzzleHttp\Psr7\Request; +use Psr\Http\Message\RequestInterface; +use Psr\Http\Message\ResponseInterface; +use Psr\Http\Message\UriInterface; use Psr\Log\LoggerInterface; use Symfony\Component\DependencyInjection\ContainerInterface; @@ -33,9 +36,9 @@ class DefaultFetcher implements FetcherInterface, ContainerFactoryPluginInterfac /** * The HTTP client to fetch the feed data with. * - * @var \GuzzleHttp\ClientInterface + * @var \Drupal\Core\Http\ClientFactory */ - protected $httpClient; + protected $httpClientFactory; /** * A logger instance. @@ -47,13 +50,13 @@ class DefaultFetcher implements FetcherInterface, ContainerFactoryPluginInterfac /** * Constructs a DefaultFetcher object. * - * @param \GuzzleHttp\ClientInterface $http_client + * @param \Drupal\Core\Http\ClientFactory $http_client_factory * A Guzzle client object. * @param \Psr\Log\LoggerInterface $logger * A logger instance. */ - public function __construct(ClientInterface $http_client, LoggerInterface $logger) { - $this->httpClient = $http_client; + public function __construct(ClientFactory $http_client_factory, LoggerInterface $logger) { + $this->httpClientFactory = $http_client_factory; $this->logger = $logger; } @@ -62,7 +65,7 @@ public function __construct(ClientInterface $http_client, LoggerInterface $logge */ public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { return new static( - $container->get('http_client'), + $container->get('http_client_factory'), $container->get('logger.factory')->get('aggregator') ); } @@ -83,7 +86,12 @@ public function fetch(FeedInterface $feed) { } try { - $response = $this->httpClient->send($request); + + /** @var \Psr\Http\Message\UriInterface $actual_uri */ + $actual_uri = NULL; + $response = $this->httpClientFactory->fromOptions(['on_redirect' => function(RequestInterface $request, ResponseInterface $response, UriInterface $uri) use (&$actual_uri) { + $actual_uri = $uri; + }])->send($request); // In case of a 304 Not Modified, there is no new content, so return // FALSE. @@ -101,8 +109,9 @@ public function fetch(FeedInterface $feed) { $feed->http_headers = $response->getHeaders(); // Update the feed URL in case of a 301 redirect. - if ($response->getHeader('X-Effective-Url')[0] != $feed->getUrl()) { - $feed->setUrl($response->getHeader('X-Effective-Url')[0]); + $actual_uri = (string) $actual_uri; + if ($actual_uri != $feed->getUrl()) { + $feed->setUrl($actual_uri); } return TRUE; } diff --git a/core/modules/locale/locale.batch.inc b/core/modules/locale/locale.batch.inc index 7c1c122..6f2ad73 100644 --- a/core/modules/locale/locale.batch.inc +++ b/core/modules/locale/locale.batch.inc @@ -6,6 +6,9 @@ */ use GuzzleHttp\Exception\RequestException; +use Psr\Http\Message\RequestInterface; +use Psr\Http\Message\ResponseInterface; +use Psr\Http\Message\UriInterface; /** * Load the common translation API. @@ -234,12 +237,16 @@ function locale_translation_batch_fetch_finished($success, $results) { function locale_translation_http_check($uri) { $logger = \Drupal::logger('locale'); try { - $response = \Drupal::httpClient()->head($uri); + $actual_uri = NULL; + $response = \Drupal::httpClientFactory()->fromOptions(['on_redirect' => function(RequestInterface $request, ResponseInterface $response, UriInterface $uri) { + $actual_uri = $uri; + }])->head($uri); $result = array(); + $actual_uri = (string) $actual_uri; // Return the effective URL if it differs from the requested. - if ($response->hasHeader('X-Effective-Url') && $response->getHeader('X-Effective-Url')[0] != $uri) { - $result['location'] = $response->getHeader('X-Effective-Url')[0]; + if ($actual_uri != $uri) { + $result['location'] = $actual_uri; } $result['last_modified'] = $response->hasHeader('Last-Modified') ? strtotime($response->getHeader('Last-Modified')[0]) : 0; diff --git a/core/vendor/composer/installed.json b/core/vendor/composer/installed.json index 7601966..7a3ba61 100644 --- a/core/vendor/composer/installed.json +++ b/core/vendor/composer/installed.json @@ -3245,70 +3245,6 @@ ] }, { - "name": "guzzlehttp/guzzle", - "version": "6.0.2", - "version_normalized": "6.0.2.0", - "source": { - "type": "git", - "url": "https://github.com/guzzle/guzzle.git", - "reference": "a8dfeff00eb84616a17fea7a4d72af35e750410f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/a8dfeff00eb84616a17fea7a4d72af35e750410f", - "reference": "a8dfeff00eb84616a17fea7a4d72af35e750410f", - "shasum": "" - }, - "require": { - "guzzlehttp/promises": "~1.0", - "guzzlehttp/psr7": "~1.1", - "php": ">=5.5.0" - }, - "require-dev": { - "ext-curl": "*", - "phpunit/phpunit": "~4.0", - "psr/log": "~1.0" - }, - "time": "2015-07-04 20:09:24", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "6.0-dev" - } - }, - "installation-source": "dist", - "autoload": { - "files": [ - "src/functions_include.php" - ], - "psr-4": { - "GuzzleHttp\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Michael Dowling", - "email": "mtdowling@gmail.com", - "homepage": "https://github.com/mtdowling" - } - ], - "description": "Guzzle is a PHP HTTP client library", - "homepage": "http://guzzlephp.org/", - "keywords": [ - "client", - "curl", - "framework", - "http", - "http client", - "rest", - "web service" - ] - }, - { "name": "symfony/dom-crawler", "version": "v2.7.1", "version_normalized": "2.7.1.0", @@ -3524,5 +3460,69 @@ "headless", "testing" ] + }, + { + "name": "guzzlehttp/guzzle", + "version": "dev-master", + "version_normalized": "9999999-dev", + "source": { + "type": "git", + "url": "https://github.com/guzzle/guzzle.git", + "reference": "1879fbe853b0c64d109e369c7aeff09849e62d1e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/1879fbe853b0c64d109e369c7aeff09849e62d1e", + "reference": "1879fbe853b0c64d109e369c7aeff09849e62d1e", + "shasum": "" + }, + "require": { + "guzzlehttp/promises": "~1.0", + "guzzlehttp/psr7": "~1.1", + "php": ">=5.5.0" + }, + "require-dev": { + "ext-curl": "*", + "phpunit/phpunit": "~4.0", + "psr/log": "~1.0" + }, + "time": "2015-07-10 20:04:21", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "6.0-dev" + } + }, + "installation-source": "dist", + "autoload": { + "files": [ + "src/functions_include.php" + ], + "psr-4": { + "GuzzleHttp\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Guzzle is a PHP HTTP client library", + "homepage": "http://guzzlephp.org/", + "keywords": [ + "client", + "curl", + "framework", + "http", + "http client", + "rest", + "web service" + ] } ] diff --git a/core/vendor/guzzlehttp/guzzle/src/Client.php b/core/vendor/guzzlehttp/guzzle/src/Client.php index 98f1ff7..74f5cfe 100644 --- a/core/vendor/guzzlehttp/guzzle/src/Client.php +++ b/core/vendor/guzzlehttp/guzzle/src/Client.php @@ -289,7 +289,7 @@ private function applyOptions(RequestInterface $request, array &$options) . 'x-www-form-urlencoded requests, and the multipart ' . 'option to send multipart/form-data requests.'); } - $options['body'] = http_build_query($options['form_params']); + $options['body'] = http_build_query($options['form_params'], null, '&'); unset($options['form_params']); $options['_conditional']['Content-Type'] = 'application/x-www-form-urlencoded'; } diff --git a/core/vendor/guzzlehttp/guzzle/src/RedirectMiddleware.php b/core/vendor/guzzlehttp/guzzle/src/RedirectMiddleware.php index 99d9e7e..374931d 100644 --- a/core/vendor/guzzlehttp/guzzle/src/RedirectMiddleware.php +++ b/core/vendor/guzzlehttp/guzzle/src/RedirectMiddleware.php @@ -89,6 +89,15 @@ public function checkRedirect( $this->guardMax($request, $options); $nextRequest = $this->modifyRequest($request, $options, $response); + if (isset($options['allow_redirects']['on_redirect'])) { + call_user_func( + $options['allow_redirects']['on_redirect'], + $request, + $response, + $nextRequest->getUri() + ); + } + return $this($nextRequest, $options); } diff --git a/core/vendor/guzzlehttp/guzzle/src/RequestOptions.php b/core/vendor/guzzlehttp/guzzle/src/RequestOptions.php index 6f4f159..e142b3f 100644 --- a/core/vendor/guzzlehttp/guzzle/src/RequestOptions.php +++ b/core/vendor/guzzlehttp/guzzle/src/RequestOptions.php @@ -14,7 +14,22 @@ * allow_redirects: (bool|array) Controls redirect behavior. Pass false * to disable redirects, pass true to enable redirects, pass an * associative to provide custom redirect settings. Defaults to "false". - * This option only works if your handler has the RedirectMiddleware. + * This option only works if your handler has the RedirectMiddleware. When + * passing an associative array, you can provide the following key value + * pairs: + * + * - max: (int, default=5) maximum number of allowed redirects. + * - strict: (bool, default=false) Set to true to use strict redirects + * meaning redirect POST requests with POST requests vs. doing what most + * browsers do which is redirect POST requests with GET requests + * - referer: (bool, default=true) Set to false to disable the Referer + * header. + * - protocols: (array, default=['http', 'https']) Allowed redirect + * protocols. + * - on_redirect: (callable) PHP callable that is invoked when a redirect + * is encountered. The callable is invoked with the request, the redirect + * response that was received, and the effective URI. Any return value + * from the on_redirect function is ignored. */ const ALLOW_REDIRECTS = 'allow_redirects';