Issue #2237681 by damiankloip: Revise Guzzle client configuration and event registration.
							parent
							
								
									f0677c1161
								
							
						
					
					
						commit
						c4b7a5b8fd
					
				| 
						 | 
				
			
			@ -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']
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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');
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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)));
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -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')
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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')
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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']
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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']
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue