diff --git a/composer.json b/composer.json index 27111a4a..3daeef71 100644 --- a/composer.json +++ b/composer.json @@ -45,7 +45,8 @@ "php-http/guzzle6-adapter": "<1.1", "php-http/cache-plugin": "<1.7.0", "php-http/curl-client": "<2.0", - "php-http/socket-client": "<2.0" + "php-http/socket-client": "<2.0", + "php-http/throttle-plugin": "<1.1" }, "require-dev": { "guzzlehttp/psr7": "^1.7 || ^2.0", diff --git a/src/DependencyInjection/Configuration.php b/src/DependencyInjection/Configuration.php index 4b842990..bd70c712 100644 --- a/src/DependencyInjection/Configuration.php +++ b/src/DependencyInjection/Configuration.php @@ -624,6 +624,18 @@ private function addSharedPluginNodes(ArrayNodeDefinition $pluginNode, $disableA ->end() ->end(); // End error plugin + + $throttle = $children->arrayNode('throttle') + ->canBeEnabled() + ->addDefaultsIfNotSet() + ->children() + ->scalarNode('name')->end() + ->scalarNode('key')->defaultNull()->end() + ->integerNode('tokens')->defaultValue(1)->end() + ->floatNode('max_time')->defaultNull()->end() + ->end() + ->end(); + // End throttle plugin } /** diff --git a/src/DependencyInjection/HttplugExtension.php b/src/DependencyInjection/HttplugExtension.php index 3fea496c..cdcbfcf0 100644 --- a/src/DependencyInjection/HttplugExtension.php +++ b/src/DependencyInjection/HttplugExtension.php @@ -10,6 +10,7 @@ use Http\Client\Common\HttpMethodsClient; use Http\Client\Common\HttpMethodsClientInterface; use Http\Client\Common\Plugin\AuthenticationPlugin; +use Http\Client\Common\Plugin\ThrottlePlugin; use Http\Client\Common\PluginClient; use Http\Client\Common\PluginClientFactory; use Http\Client\HttpAsyncClient; @@ -35,6 +36,7 @@ use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; use Symfony\Component\DependencyInjection\Reference; use Symfony\Component\HttpKernel\Kernel; +use Symfony\Component\RateLimiter\LimiterInterface; use Twig\Environment as TwigEnvironment; /** @@ -292,6 +294,24 @@ private function configurePluginByName($name, Definition $definition, array $con break; + case 'throttle': + if (!\class_exists(ThrottlePlugin::class)) { + throw new InvalidConfigurationException('You need to require the Throttle Plugin to be able to use it: "composer require php-http/throttle-plugin".'); + } + + $key = $config['name'] ? '.'.$config['name'] : ''; + $container + ->register($serviceId.$key, LimiterInterface::class) + ->setFactory([new Reference('limiter.'.$config['name']), 'create']) + ->addArgument($config['key']) + ->setPublic(false); + + $definition->replaceArgument(0, new Reference($serviceId.$key)); + $definition->setArgument('$tokens', $config['tokens']); + $definition->setArgument('$maxTime', $config['max_time']); + + break; + /* client specific plugins */ case 'add_host': diff --git a/src/Resources/config/plugins.xml b/src/Resources/config/plugins.xml index 749407c4..9f9c0ec1 100644 --- a/src/Resources/config/plugins.xml +++ b/src/Resources/config/plugins.xml @@ -28,6 +28,9 @@ + + + diff --git a/tests/Unit/DependencyInjection/ConfigurationTest.php b/tests/Unit/DependencyInjection/ConfigurationTest.php index 447efe1a..999c813b 100644 --- a/tests/Unit/DependencyInjection/ConfigurationTest.php +++ b/tests/Unit/DependencyInjection/ConfigurationTest.php @@ -98,6 +98,12 @@ class ConfigurationTest extends AbstractExtensionConfigurationTestCase 'enabled' => false, 'only_server_exception' => false, ], + 'throttle' => [ + 'enabled' => false, + 'key' => null, + 'tokens' => 1, + 'max_time' => null, + ], ], 'discovery' => [ 'client' => 'auto', @@ -308,6 +314,12 @@ public function testSupportsAllConfigFormats(): void 'enabled' => false, 'only_server_exception' => false, ], + 'throttle' => [ + 'enabled' => false, + 'key' => null, + 'tokens' => 1, + 'max_time' => null, + ], ], 'discovery' => [ 'client' => 'auto',