8585use Symfony \Component \HttpClient \Retry \GenericRetryStrategy ;
8686use Symfony \Component \HttpClient \RetryableHttpClient ;
8787use Symfony \Component \HttpClient \ScopingHttpClient ;
88+ use Symfony \Component \HttpClient \ThrottlingHttpClient ;
8889use Symfony \Component \HttpClient \UriTemplateHttpClient ;
8990use Symfony \Component \HttpFoundation \Request ;
9091use Symfony \Component \HttpKernel \Attribute \AsController ;
@@ -345,6 +346,7 @@ public function load(array $configs, ContainerBuilder $container): void
345346 }
346347
347348 if ($ this ->readConfigEnabled ('http_client ' , $ container , $ config ['http_client ' ])) {
349+ $ this ->readConfigEnabled ('rate_limiter ' , $ container , $ config ['rate_limiter ' ]); // makes sure that isInitializedConfigEnabled() will work
348350 $ this ->registerHttpClientConfiguration ($ config ['http_client ' ], $ container , $ loader );
349351 }
350352
@@ -2409,6 +2411,8 @@ private function registerHttpClientConfiguration(array $config, ContainerBuilder
24092411 $ loader ->load ('http_client.php ' );
24102412
24112413 $ options = $ config ['default_options ' ] ?? [];
2414+ $ rateLimiter = $ options ['rate_limiter ' ] ?? null ;
2415+ unset($ options ['rate_limiter ' ]);
24122416 $ retryOptions = $ options ['retry_failed ' ] ?? ['enabled ' => false ];
24132417 unset($ options ['retry_failed ' ]);
24142418 $ defaultUriTemplateVars = $ options ['vars ' ] ?? [];
@@ -2430,6 +2434,10 @@ private function registerHttpClientConfiguration(array $config, ContainerBuilder
24302434 $ container ->removeAlias (HttpClient::class);
24312435 }
24322436
2437+ if (null !== $ rateLimiter ) {
2438+ $ this ->registerThrottlingHttpClient ($ rateLimiter , 'http_client ' , $ container );
2439+ }
2440+
24332441 if ($ this ->readConfigEnabled ('http_client.retry_failed ' , $ container , $ retryOptions )) {
24342442 $ this ->registerRetryableHttpClient ($ retryOptions , 'http_client ' , $ container );
24352443 }
@@ -2451,6 +2459,8 @@ private function registerHttpClientConfiguration(array $config, ContainerBuilder
24512459
24522460 $ scope = $ scopeConfig ['scope ' ] ?? null ;
24532461 unset($ scopeConfig ['scope ' ]);
2462+ $ rateLimiter = $ scopeConfig ['rate_limiter ' ] ?? null ;
2463+ unset($ scopeConfig ['rate_limiter ' ]);
24542464 $ retryOptions = $ scopeConfig ['retry_failed ' ] ?? ['enabled ' => false ];
24552465 unset($ scopeConfig ['retry_failed ' ]);
24562466
@@ -2470,6 +2480,10 @@ private function registerHttpClientConfiguration(array $config, ContainerBuilder
24702480 ;
24712481 }
24722482
2483+ if (null !== $ rateLimiter ) {
2484+ $ this ->registerThrottlingHttpClient ($ rateLimiter , $ name , $ container );
2485+ }
2486+
24732487 if ($ this ->readConfigEnabled ('http_client.scoped_clients. ' .$ name .'.retry_failed ' , $ container , $ retryOptions )) {
24742488 $ this ->registerRetryableHttpClient ($ retryOptions , $ name , $ container );
24752489 }
@@ -2507,6 +2521,25 @@ private function registerHttpClientConfiguration(array $config, ContainerBuilder
25072521 }
25082522 }
25092523
2524+ private function registerThrottlingHttpClient (string $ rateLimiter , string $ name , ContainerBuilder $ container ): void
2525+ {
2526+ if (!class_exists (ThrottlingHttpClient::class)) {
2527+ throw new LogicException ('Rate limiter support cannot be enabled as version 7.1+ of the HttpClient component is required. ' );
2528+ }
2529+
2530+ if (!$ this ->isInitializedConfigEnabled ('rate_limiter ' )) {
2531+ throw new LogicException ('Rate limiter cannot be used within HttpClient as the RateLimiter component is not enabled. ' );
2532+ }
2533+
2534+ $ container ->register ($ name .'.throttling.limiter ' , LimiterInterface::class)
2535+ ->setFactory ([new Reference ('limiter. ' .$ rateLimiter ), 'create ' ]);
2536+
2537+ $ container
2538+ ->register ($ name .'.throttling ' , ThrottlingHttpClient::class)
2539+ ->setDecoratedService ($ name , null , 15 ) // higher priority than RetryableHttpClient (10)
2540+ ->setArguments ([new Reference ($ name .'.throttling.inner ' ), new Reference ($ name .'.throttling.limiter ' )]);
2541+ }
2542+
25102543 private function registerRetryableHttpClient (array $ options , string $ name , ContainerBuilder $ container ): void
25112544 {
25122545 if (null !== $ options ['retry_strategy ' ]) {
0 commit comments