Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit e9505df

Browse filesBrowse files
committed
minor #20870 [RateLimiter] compound rate limiter (kbond)
This PR was merged into the 7.3 branch. Discussion ---------- [RateLimiter] compound rate limiter Closes #20866. Commits ------- 35349c1 [RateLimiter] compound rate limiter
2 parents 59fd3a3 + 35349c1 commit e9505df
Copy full SHA for e9505df

File tree

1 file changed

+117
-0
lines changed
Filter options

1 file changed

+117
-0
lines changed

‎rate_limiter.rst

Copy file name to clipboardExpand all lines: rate_limiter.rst
+117Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -547,6 +547,123 @@ at all):
547547
lock factory (``lock.factory``) failed if the Symfony Lock component was not
548548
installed in the application.
549549

550+
Compound Rate Limiter
551+
---------------------
552+
553+
.. versionadded:: 7.3
554+
555+
Configuring compound rate limiters was added in 7.3.
556+
557+
You can configure multiple rate limiters to work together:
558+
559+
.. configuration-block::
560+
561+
.. code-block:: yaml
562+
563+
# config/packages/rate_limiter.yaml
564+
framework:
565+
rate_limiter:
566+
two_per_minute:
567+
policy: 'fixed_window'
568+
limit: 2
569+
interval: '1 minute'
570+
five_per_hour:
571+
policy: 'fixed_window'
572+
limit: 5
573+
interval: '1 hour'
574+
contact_form:
575+
policy: 'compound'
576+
limiters: [two_per_minute, five_per_hour]
577+
578+
.. code-block:: xml
579+
580+
<!-- config/packages/rate_limiter.xml -->
581+
<?xml version="1.0" encoding="UTF-8" ?>
582+
<container xmlns="http://symfony.com/schema/dic/services"
583+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
584+
xmlns:framework="http://symfony.com/schema/dic/symfony"
585+
xsi:schemaLocation="http://symfony.com/schema/dic/services
586+
https://symfony.com/schema/dic/services/services-1.0.xsd
587+
http://symfony.com/schema/dic/symfony
588+
https://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
589+
590+
<framework:config>
591+
<framework:rate-limiter>
592+
<framework:limiter name="two_per_minute"
593+
policy="fixed_window"
594+
limit="2"
595+
interval="1 minute"
596+
/>
597+
598+
<framework:limiter name="five_per_hour"
599+
policy="fixed_window"
600+
limit="5"
601+
interval="1 hour"
602+
/>
603+
604+
<framework:limiter name="contact_form"
605+
policy="compound"
606+
>
607+
<limiter>two_per_minute</limiter>
608+
<limiter>five_per_hour</limiter>
609+
</framework:limiter>
610+
</framework:rate-limiter>
611+
</framework:config>
612+
</container>
613+
614+
.. code-block:: php
615+
616+
// config/packages/rate_limiter.php
617+
use Symfony\Config\FrameworkConfig;
618+
619+
return static function (FrameworkConfig $framework): void {
620+
$framework->rateLimiter()
621+
->limiter('two_per_minute')
622+
->policy('fixed_window')
623+
->limit(2)
624+
->interval('1 minute')
625+
;
626+
627+
$framework->rateLimiter()
628+
->limiter('two_per_minute')
629+
->policy('fixed_window')
630+
->limit(5)
631+
->interval('1 hour')
632+
;
633+
634+
$framework->rateLimiter()
635+
->limiter('contact_form')
636+
->policy('compound')
637+
->limiters(['two_per_minute', 'five_per_hour'])
638+
;
639+
};
640+
641+
Then, inject and use as normal::
642+
643+
// src/Controller/ContactController.php
644+
namespace App\Controller;
645+
646+
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
647+
use Symfony\Component\HttpFoundation\Request;
648+
use Symfony\Component\HttpFoundation\Response;
649+
use Symfony\Component\RateLimiter\RateLimiterFactory;
650+
651+
class ContactController extends AbstractController
652+
{
653+
public function registerUser(Request $request, RateLimiterFactoryInterface $contactFormLimiter): Response
654+
{
655+
$limiter = $contactFormLimiter->create($request->getClientIp());
656+
657+
if (false === $limiter->consume(1)->isAccepted()) {
658+
// either of the two limiters has been reached
659+
}
660+
661+
// ...
662+
}
663+
664+
// ...
665+
}
666+
550667
.. _`DoS attacks`: https://cheatsheetseries.owasp.org/cheatsheets/Denial_of_Service_Cheat_Sheet.html
551668
.. _`Apache mod_ratelimit`: https://httpd.apache.org/docs/current/mod/mod_ratelimit.html
552669
.. _`NGINX rate limiting`: https://www.nginx.com/blog/rate-limiting-nginx/

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.