php-http/HttplugBundle

Client configuration is ignored for async client

sergehardy opened this issue · 1 comments

Q A
Bug? yes
New Feature? no
Version 1.16.0

Actual Behavior

The bundle configuration and the documentation suggest that the async client discovery can be disabled.
In fact, the HttpAsyncClient creation is always created by a HttpAsyncClientDiscovery and thus bypasses client config.

Expected Behavior

Same behavior as for the HttpClient

Steps to Reproduce

  1. use the following configuration:
httplug:
    plugins:
        redirect:
            preserve_header: true

    discovery:
        client: null
        async_client: null
    clients:
        app:
            factory: 'httplug.factory.guzzle6'
            plugins:
                - 'httplug.plugin.content_length'
                - 'httplug.plugin.redirect'
            config:
                verify: false
  1. Inject both HttpClient & HttpAsyncClient in a service, eg a test command:
namespace App\Command;

use Http\Client\HttpAsyncClient;
use Http\Client\HttpClient;
use Http\Message\MessageFactory;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

class HttpCommand extends Command
{

    protected static $defaultName = 'http:test';
    /**
     * @var HttpAsyncClient
     */
    private $client;
    /**
     * @var MessageFactory
     */
    private $messageFactory;

    /**
     * @var HttpAsyncClient
     */
    private $asyncClient;

    public function __construct(?string $name = null, HttpAsyncClient $asyncClient, HttpClient $client, MessageFactory $messageFactory)
    {
        parent::__construct($name);
        $this->client = $client;
        $this->messageFactory = $messageFactory;
        $this->asyncClient = $asyncClient;
    }

    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $request = $this->messageFactory->createRequest('GET', 'https://getcomposer.org/robots.txt');

        $response = $this->client->sendAsyncRequest($request);
        $response = $this->asyncClient->sendAsyncRequest($request)->wait();
       ...

    }
}
  1. Inspect and check both client & async client configurations:
  • client's 'verify' option is set to false as expected
  • async client's 'verify' option is unexpectedly set to true

Possible Solutions

For the moment I can use the flexible client as the guzzle adapter provides both implementations.

Not sure about the solution but there is a difference in dealing autowiring for both classes in services.xml:

  <service id="Http\Client\HttpAsyncClient" alias="httplug.async_client.default" public="false" />
  <service id="Http\Client\HttpClient" alias="httplug.client" public="false" />

I have fixed this problem by not trying to redefine the default async client but redefining my own and overriding the default implementation in my application's services definition:

# config/packages/dev/httplug.yaml
httplug:
    profiling:
        enabled: true
    plugins:
        logger:
            formatter: "httplug.formatter.full_http_message"
    clients:
        my_client:
            config:
               verify: false
# config/services.yaml
    Http\Client\HttpAsyncClient: '@httplug.client.my_client'

Hence autowiring the HttpAsyncClient provides an implementation that is configured with the "verify: false" option.