diff --git a/CHANGELOG.md b/CHANGELOG.md
index e8baaa2d..18dbe530 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -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
diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php
index f6ef7e4f..1c73b29f 100644
--- a/DependencyInjection/Configuration.php
+++ b/DependencyInjection/Configuration.php
@@ -92,6 +92,7 @@ public function getConfigTreeBuilder()
return $v;
})
->end()
+ ->fixXmlConfig('client')
->children()
->arrayNode('main_alias')
->addDefaultsIfNotSet()
@@ -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()
@@ -202,7 +219,7 @@ protected function configurePlugins(ArrayNodeDefinition $root)
->arrayNode('plugins')
->addDefaultsIfNotSet()
->children()
- ->append($this->addAuthenticationPluiginNode())
+ ->append($this->addAuthenticationPluginNode())
->arrayNode('cache')
->canBeEnabled()
@@ -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');
diff --git a/DependencyInjection/HttplugExtension.php b/DependencyInjection/HttplugExtension.php
index 0e3c5315..6e034a7d 100644
--- a/DependencyInjection/HttplugExtension.php
+++ b/DependencyInjection/HttplugExtension.php
@@ -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;
@@ -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;
@@ -215,6 +217,7 @@ private function configureClient(ContainerBuilder $container, $name, array $argu
{
$serviceId = 'httplug.client.'.$name;
+ $plugins = $arguments['plugins'];
$pluginClientOptions = [];
if ($profiling) {
@@ -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)) {
+ $plugins[] = $addHostPlugin;
+ }
+ break;
+ }
+ }
+ }
+
$container
->register($serviceId, DummyClient::class)
->setFactory([PluginClientFactory::class, 'createPluginClient'])
@@ -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']))
@@ -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.
diff --git a/Tests/Resources/Fixtures/config/full.php b/Tests/Resources/Fixtures/config/full.php
index 0a8ab554..9180b3c7 100644
--- a/Tests/Resources/Fixtures/config/full.php
+++ b/Tests/Resources/Fixtures/config/full.php
@@ -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',
diff --git a/Tests/Resources/Fixtures/config/full.xml b/Tests/Resources/Fixtures/config/full.xml
index e0ded54b..83764450 100644
--- a/Tests/Resources/Fixtures/config/full.xml
+++ b/Tests/Resources/Fixtures/config/full.xml
@@ -14,6 +14,9 @@
Http\Message\UriFactory\GuzzleUriFactory
Http\Message\StreamFactory\GuzzleStreamFactory
+
+
+
diff --git a/Tests/Resources/Fixtures/config/full.yml b/Tests/Resources/Fixtures/config/full.yml
index 72341e8e..d8e7ef7a 100644
--- a/Tests/Resources/Fixtures/config/full.yml
+++ b/Tests/Resources/Fixtures/config/full.yml
@@ -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
diff --git a/Tests/Unit/DependencyInjection/ConfigurationTest.php b/Tests/Unit/DependencyInjection/ConfigurationTest.php
index df931ea3..1d72fd8e 100644
--- a/Tests/Unit/DependencyInjection/ConfigurationTest.php
+++ b/Tests/Unit/DependencyInjection/ConfigurationTest.php
@@ -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',