Issue #2237681 by damiankloip: Revise Guzzle client configuration and event registration.

8.0.x
Nathaniel Catchpole 2014-04-15 20:12:03 +01:00
parent f0677c1161
commit c4b7a5b8fd
11 changed files with 91 additions and 29 deletions

View File

@ -159,8 +159,12 @@ services:
path.alias_manager:
class: Drupal\Core\Path\AliasManager
arguments: ['@path.alias_storage', '@path.alias_whitelist', '@language_manager']
http_default_client:
http_client:
class: Drupal\Core\Http\Client
http_client_simpletest_subscriber:
class: Drupal\Core\Http\Plugin\SimpletestHttpRequestSubscriber
tags:
- { name: http_client_subscriber }
theme.negotiator:
class: Drupal\Core\Theme\ThemeNegotiator
arguments: ['@access_check.theme', '@request_stack']

View File

@ -349,7 +349,7 @@ class Drupal {
* A guzzle http client instance.
*/
public static function httpClient() {
return static::$container->get('http_default_client');
return static::$container->get('http_client');
}
/**

View File

@ -26,6 +26,7 @@ use Drupal\Core\DependencyInjection\Compiler\RegisterStringTranslatorsPass;
use Drupal\Core\DependencyInjection\Compiler\RegisterBreadcrumbBuilderPass;
use Drupal\Core\DependencyInjection\Compiler\RegisterAuthenticationPass;
use Drupal\Core\DependencyInjection\Compiler\RegisterTwigExtensionsPass;
use Drupal\Core\Http\HttpClientSubscriberPass;
use Drupal\Core\Plugin\PluginManagerPass;
use Drupal\Core\Theme\ThemeNegotiatorPass;
use Symfony\Component\DependencyInjection\ContainerInterface;
@ -92,6 +93,8 @@ class CoreServiceProvider implements ServiceProviderInterface {
$container->addCompilerPass(new RegisterTwigExtensionsPass());
// Register plugin managers.
$container->addCompilerPass(new PluginManagerPass());
// Register HTTP client subscribers.
$container->addCompilerPass(new HttpClientSubscriberPass());
}
/**

View File

@ -7,9 +7,10 @@
namespace Drupal\Core\Http;
use Drupal\Core\Http\Plugin\SimpletestHttpRequestSubscriber;
use Drupal\Component\Utility\NestedArray;
use Drupal\Component\Utility\Settings;
use GuzzleHttp\Client as GuzzleClient;
use GuzzleHttp\Event\SubscriberInterface;
/**
* Drupal default HTTP client class.
@ -21,31 +22,54 @@ class Client extends GuzzleClient {
*/
public function __construct(array $config = []) {
$default_config = array(
'defaults' => array(
'config' => array(
'curl' => array(
CURLOPT_TIMEOUT => 30,
CURLOPT_MAXREDIRS => 3,
),
),
// Security consideration: we must not use the certificate authority
// file shipped with Guzzle because it can easily get outdated if a
// certificate authority is hacked. Instead, we rely on the certificate
// authority file provided by the operating system which is more likely
// going to be updated in a timely fashion. This overrides the default
// path to the pem file bundled with Guzzle.
'verify' => TRUE,
'headers' => array(
'User-Agent' => 'Drupal (+http://drupal.org/)',
'config' => array(
'curl' => array(
CURLOPT_TIMEOUT => 30,
CURLOPT_MAXREDIRS => 3,
),
),
// Security consideration: we must not use the certificate authority
// file shipped with Guzzle because it can easily get outdated if a
// certificate authority is hacked. Instead, we rely on the certificate
// authority file provided by the operating system which is more likely
// going to be updated in a timely fashion. This overrides the default
// path to the pem file bundled with Guzzle.
'verify' => TRUE,
'headers' => array(
'User-Agent' => 'Drupal (+http://drupal.org/)',
),
);
$config = NestedArray::mergeDeep($default_config, $config);
// The entire config array is merged/configurable to allow Guzzle client
// options outside of 'defaults' to be changed, such as 'adapter', or
// 'message_factory'.
$config = NestedArray::mergeDeep(array('defaults' => $default_config), $config, Settings::get('http_client_config', array()));
parent::__construct($config);
$this->getEmitter()->attach(new SimpletestHttpRequestSubscriber());
}
/**
* Attaches an event subscriber.
*
* @param \GuzzleHttp\Event\SubscriberInterface $subscriber
* The subscriber to attach.
*
* @see \GuzzleHttp\Event\Emitter::attach()
*/
public function attach(SubscriberInterface $subscriber) {
$this->getEmitter()->attach($subscriber);
}
/**
* Detaches an event subscriber.
*
* @param \GuzzleHttp\Event\SubscriberInterface $subscriber
* The subscriber to detach.
*
* @see \GuzzleHttp\Event\Emitter::detach()
*/
public function detach(SubscriberInterface $subscriber) {
$this->getEmitter()->detach($subscriber);
}
}

View File

@ -0,0 +1,31 @@
<?php
/**
* @file
* Contains \Drupal\Core\Http\HttpClientSubscriberPass.
*/
namespace Drupal\Core\Http;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\Reference;
/**
* Registers 'http_client_subscriber' tagged services as http client subscribers.
*/
class HttpClientSubscriberPass implements CompilerPassInterface {
/**
* {@inheritdoc}
*/
public function process(ContainerBuilder $container) {
$http_client = $container->getDefinition('http_client');
foreach (array_keys($container->findTaggedServiceIds('http_client_subscriber')) as $id) {
$http_client->addMethodCall('attach', array(new Reference($id)));
}
}
}

View File

@ -52,7 +52,7 @@ class OpmlFeedAdd extends FormBase {
public static function create(ContainerInterface $container) {
return new static(
$container->get('entity.manager')->getStorage('aggregator_feed'),
$container->get('http_default_client')
$container->get('http_client')
);
}

View File

@ -17,7 +17,7 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Defines a default fetcher implementation.
*
* Uses the http_default_client service to download the feed.
* Uses the http_client service to download the feed.
*
* @AggregatorFetcher(
* id = "aggregator",
@ -49,7 +49,7 @@ class DefaultFetcher implements FetcherInterface, ContainerFactoryPluginInterfac
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static(
$container->get('http_default_client')
$container->get('http_client')
);
}

View File

@ -14,7 +14,7 @@ use Drupal\aggregator\FeedInterface;
/**
* Defines a test fetcher implementation.
*
* Uses http_default_client class to download the feed.
* Uses http_client class to download the feed.
*
* @AggregatorFetcher(
* id = "aggregator_test_fetcher",

View File

@ -16,7 +16,7 @@ services:
class: Drupal\hal\Normalizer\FileEntityNormalizer
tags:
- { name: normalizer, priority: 20 }
arguments: ['@entity.manager', '@http_default_client', '@rest.link_manager', '@module_handler']
arguments: ['@entity.manager', '@http_client', '@rest.link_manager', '@module_handler']
serializer.normalizer.entity.hal:
class: Drupal\hal\Normalizer\ContentEntityNormalizer
arguments: ['@rest.link_manager', '@entity.manager', '@module_handler']

View File

@ -12,4 +12,4 @@ services:
arguments: ['@config.factory', '@queue', '@update.fetcher', '@state', '@private_key', '@keyvalue', '@keyvalue.expirable']
update.fetcher:
class: Drupal\update\UpdateFetcher
arguments: ['@config.factory', '@http_default_client']
arguments: ['@config.factory', '@http_client']

View File

@ -177,7 +177,7 @@ class DrupalTest extends UnitTestCase {
* Tests the httpClient() method.
*/
public function testHttpClient() {
$this->setMockContainerService('http_default_client');
$this->setMockContainerService('http_client');
$this->assertNotNull(\Drupal::httpClient());
}