Skip to content

Add support for default_host and force_host options on each client #111

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@

### Added

- Option to configure default host for each client. default_host to add host if missing, force_host to change all requests to a specific host.
- Support for BatchClient
- The stopwatch plugin in included by default when using profiling.
- The stopwatch plugin in included by default when using profiling.

### Changed

Expand Down
21 changes: 19 additions & 2 deletions DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ public function getConfigTreeBuilder()
return $v;
})
->end()
->fixXmlConfig('client')
->children()
->arrayNode('main_alias')
->addDefaultsIfNotSet()
Expand Down Expand Up @@ -184,6 +185,22 @@ protected function configureClients(ArrayNodeDefinition $root)
->defaultFalse()
->info('Set to true to get the client wrapped in a BatchClient which allows you to send multiple request at the same time.')
->end()
->arrayNode('options')
->validate()
->ifTrue(function ($options) {
return array_key_exists('default_host', $options) && array_key_exists('force_host', $options);
})
->thenInvalid('You can only set one of default_host and force_host for each client')
->end()
->children()
->scalarNode('default_host')
->info('Configure the AddHostPlugin for this client. Add host if request is only for a path.')
->end()
->scalarNode('force_host')
->info('Configure the AddHostPlugin for this client. Send all requests to this host regardless of host in request.')
->end()
->end()
->end()
->arrayNode('plugins')
->info('A list of service ids of plugins. The order is important.')
->prototype('scalar')->end()
Expand All @@ -202,7 +219,7 @@ protected function configurePlugins(ArrayNodeDefinition $root)
->arrayNode('plugins')
->addDefaultsIfNotSet()
->children()
->append($this->addAuthenticationPluiginNode())
->append($this->addAuthenticationPluginNode())

->arrayNode('cache')
->canBeEnabled()
Expand Down Expand Up @@ -313,7 +330,7 @@ protected function configurePlugins(ArrayNodeDefinition $root)
*
* @return ArrayNodeDefinition|\Symfony\Component\Config\Definition\Builder\NodeDefinition
*/
private function addAuthenticationPluiginNode()
private function addAuthenticationPluginNode()
{
$builder = new TreeBuilder();
$node = $builder->root('authentication');
Expand Down
58 changes: 57 additions & 1 deletion DependencyInjection/HttplugExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use Http\Client\Common\BatchClient;
use Http\Client\Common\FlexibleHttpClient;
use Http\Client\Common\HttpMethodsClient;
use Http\Client\Common\Plugin\AddHostPlugin;
use Http\Client\Common\Plugin\AuthenticationPlugin;
use Http\Discovery\HttpAsyncClientDiscovery;
use Http\Discovery\HttpClientDiscovery;
Expand All @@ -14,6 +15,7 @@
use Http\Message\Authentication\BasicAuth;
use Http\Message\Authentication\Bearer;
use Http\Message\Authentication\Wsse;
use Psr\Http\Message\UriInterface;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
Expand Down Expand Up @@ -215,6 +217,7 @@ private function configureClient(ContainerBuilder $container, $name, array $argu
{
$serviceId = 'httplug.client.'.$name;

$plugins = $arguments['plugins'];
$pluginClientOptions = [];

if ($profiling) {
Expand All @@ -234,6 +237,42 @@ private function configureClient(ContainerBuilder $container, $name, array $argu
$pluginClientOptions['debug_plugins'] = [new Reference($debugPluginServiceId)];
}

if (array_key_exists('options', $arguments)) {
foreach ($arguments['options'] as $option => $value) {
switch ($option) {
case 'default_host':
$uriService = $serviceId.'.default_host_uri';
$addHostPlugin = $serviceId.'.default_host_plugin';
$this->createUri($container, $uriService, $value);
$container
->register($addHostPlugin, AddHostPlugin::class)
->setPublic(false)
->addArgument(new Reference($uriService))
;
// add to end of plugins list unless explicitly configured
if (!in_array($addHostPlugin, $plugins)) {
$plugins[] = $addHostPlugin;
}
break;
case 'force_host':
$uriService = $serviceId.'.force_host_uri';
$addHostPlugin = $serviceId.'.force_host_plugin';
$this->createUri($container, $uriService, $value);
$container
->register($addHostPlugin, AddHostPlugin::class)
->setPublic(false)
->addArgument(new Reference($uriService))
->addArgument(['replace' => true])
;
// add to end of plugins list unless explicitly configured
if (!in_array($addHostPlugin, $plugins)) {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

by default, we append the AddHostPlugin to the very end of the chain, but you can explicitly set it in the plugins list. i will explain this in the documentation

$plugins[] = $addHostPlugin;
}
break;
}
}
}

$container
->register($serviceId, DummyClient::class)
->setFactory([PluginClientFactory::class, 'createPluginClient'])
Expand All @@ -242,7 +281,7 @@ private function configureClient(ContainerBuilder $container, $name, array $argu
function ($id) {
return new Reference($id);
},
$arguments['plugins']
$plugins
)
)
->addArgument(new Reference($arguments['factory']))
Expand Down Expand Up @@ -282,6 +321,23 @@ function ($id) {
}
}

/**
* Create a URI object with the default URI factory.
*
* @param ContainerBuilder $container
* @param string $serviceId Name of the private service to create
* @param string $uri String representation of the URI
*/
private function createUri(ContainerBuilder $container, $serviceId, $uri)
{
$container
->register($serviceId, UriInterface::class)
->setPublic(false)
->setFactory([new Reference('httplug.uri_factory'), 'createUri'])
->addArgument($uri)
;
}

/**
* Make the user can select what client is used for auto discovery. If none is provided, a service will be created
* by finding a client using auto discovery.
Expand Down
9 changes: 9 additions & 0 deletions Tests/Resources/Fixtures/config/full.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,15 @@
'uri_factory' => 'Http\Message\UriFactory\GuzzleUriFactory',
'stream_factory' => 'Http\Message\StreamFactory\GuzzleStreamFactory',
],
'clients' => [
'test' => [
'factory' => 'httplug.factory.guzzle6',
'http_methods_client' => true,
'options' => [
'default_host' => 'http://localhost',
],
],
],
'profiling' => [
'enabled' => true,
'formatter' => 'my_toolbar_formatter',
Expand Down
3 changes: 3 additions & 0 deletions Tests/Resources/Fixtures/config/full.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
<uri-factory>Http\Message\UriFactory\GuzzleUriFactory</uri-factory>
<stream-factory>Http\Message\StreamFactory\GuzzleStreamFactory</stream-factory>
</classes>
<client name="test" factory="httplug.factory.guzzle6" http-methods-client="true">
<options default-host="http://localhost"/>
</client>
<profiling enabled="true" formatter="my_toolbar_formatter" captured_body_length="0"/>
<plugins>
<authentication>
Expand Down
6 changes: 6 additions & 0 deletions Tests/Resources/Fixtures/config/full.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ httplug:
message_factory: Http\Message\MessageFactory\GuzzleMessageFactory
uri_factory: Http\Message\UriFactory\GuzzleUriFactory
stream_factory: Http\Message\StreamFactory\GuzzleStreamFactory
clients:
test:
factory: httplug.factory.guzzle6
http_methods_client: true
options:
default_host: http://localhost
profiling:
enabled: true
formatter: my_toolbar_formatter
Expand Down
14 changes: 13 additions & 1 deletion Tests/Unit/DependencyInjection/ConfigurationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,19 @@ public function testSupportsAllConfigFormats()
'uri_factory' => 'Http\Message\UriFactory\GuzzleUriFactory',
'stream_factory' => 'Http\Message\StreamFactory\GuzzleStreamFactory',
],
'clients' => [],
'clients' => [
'test' => [
'factory' => 'httplug.factory.guzzle6',
'http_methods_client' => true,
'flexible_client' => false,
'batch_client' => false,
'options' => [
'default_host' => 'http://localhost',
],
'plugins' => [],
'config' => [],
],
],
'profiling' => [
'enabled' => true,
'formatter' => 'my_toolbar_formatter',
Expand Down