Skip to content

Commit

Permalink
Add custom rate/period on pre create event
Browse files Browse the repository at this point in the history
  • Loading branch information
Marcos Gómez committed Aug 1, 2016
1 parent 27daf33 commit 2b746f8
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 5 deletions.
8 changes: 6 additions & 2 deletions EventListener/RateLimitAnnotationListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Instasent\RateLimitBundle\Annotation\RateLimit;
use Instasent\RateLimitBundle\Events\GenerateKeyEvent;
use Instasent\RateLimitBundle\Events\RateLimitEvent;
use Instasent\RateLimitBundle\Events\RateLimitEvents;
use Instasent\RateLimitBundle\Service\RateLimitService;
use Instasent\RateLimitBundle\Util\PathLimitProcessor;
Expand Down Expand Up @@ -73,6 +74,11 @@ public function onKernelController(FilterControllerEvent $event)
// Ratelimit the call
$rateLimitInfo = $this->rateLimitService->limitRate($key);
if (! $rateLimitInfo) {

// Dispatch before create rateLimit key
$rateLimitEvent = new RateLimitEvent($event->getRequest(), $rateLimit);
$this->eventDispatcher->dispatch(RateLimitEvents::PRE_CREATE_RATE_LIMIT, $rateLimitEvent);

// Create new rate limit entry for this call
$rateLimitInfo = $this->rateLimitService->createRate($key, $rateLimit->getLimit(), $rateLimit->getPeriod());
if (! $rateLimitInfo) {
Expand All @@ -82,7 +88,6 @@ public function onKernelController(FilterControllerEvent $event)
}
}


// Store the current rating info in the request attributes
$request = $event->getRequest();
$request->attributes->set('rate_limit_info', $rateLimitInfo);
Expand Down Expand Up @@ -112,7 +117,6 @@ public function onKernelController(FilterControllerEvent $event)

}


/**
* @param RateLimit[] $annotations
*/
Expand Down
40 changes: 40 additions & 0 deletions Events/RateLimitEvent.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php

namespace Instasent\RateLimitBundle\Events;

use Instasent\RateLimitBundle\Annotation\RateLimit;
use Symfony\Component\EventDispatcher\Event;
use Symfony\Component\HttpFoundation\Request;

class RateLimitEvent extends Event
{

/** @var Request */
protected $request;

/** @var string */
protected $rateLimit;

public function __construct(Request $request, RateLimit $rateLimitAnnotation)
{
$this->request = $request;
$this->rateLimit = $rateLimitAnnotation;
}

/**
* @return RateLimit
*/
public function getRateLimit()
{
return $this->rateLimit;
}

/**
* @return Request
*/
public function getRequest()
{
return $this->request;
}

}
4 changes: 3 additions & 1 deletion Events/RateLimitEvents.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,7 @@

final class RateLimitEvents
{
const GENERATE_KEY = 'ratelimit.generate.key';
const PRE_CREATE_RATE_LIMIT = 'ratelimit.pre.create';

const GENERATE_KEY = 'ratelimit.generate.key';
}
35 changes: 33 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -247,11 +247,42 @@ class RateLimitGenerateKeyListener

Make sure to generate a key based on what is rate limited in your controllers.

## Set custom period or limit

If you need to create a custom period/limit based for example on client settings saved in database, you need to register a listener to listen to the `ratelimit.pre.create` event:

```yaml
services:
mybundle.listener.rate_limit_pre_create:
class: MyBundle\Listener\RateLimitFromDatabaseListener
tags:
- { name: kernel.event_listener, event: 'ratelimit.pre.create', method: 'findUserLimit' }
```
```php
<?php

namespace MyBundle\Listener;

use Instasent\RateLimitBundle\Events\RateLimit;

class RateLimitFromDatabaseListener
{
public function findUserLimit(RateLimit $event)
{

//TODO search value in database
$event->setLimit($value);
}
}
```

Set your own limit value

## Throwing exceptions

Instead of returning a Response object when a rate limit has exceeded, it's also possible to throw an exception. This
allows you to easily handle the rate limit on another level, for instance by capturing the ``kernel.exception`` event.
Instead of returning a Response object when a rate limit has exceeded, it's also possible to throw an exception. This
allows you to easily handle the rate limit on another level, for instance by capturing the ``kernel.exception`` event.


## Running tests
Expand Down

0 comments on commit 2b746f8

Please sign in to comment.