Skip to content

Commit

Permalink
Merge pull request dingo#1202 from lucasmichot/feature/master/rfc8565
Browse files Browse the repository at this point in the history
Update RateLimit exception response to RFC6585 specifications
  • Loading branch information
hskrasek authored Oct 18, 2016
2 parents 950b37f + 9e44767 commit dc312a5
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 6 deletions.
28 changes: 28 additions & 0 deletions src/Exception/RateLimitExceededException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

namespace Dingo\Api\Exception;

use Exception;
use Symfony\Component\HttpKernel\Exception\HttpException;

class RateLimitExceededException extends HttpException
{
/**
* Create a new rate limit exceeded exception instance.
*
* @param string $message
* @param \Exception $previous
* @param array $headers
* @param int $code
*
* @return void
*/
public function __construct($message = null, Exception $previous = null, $headers = [], $code = 0)
{
if (array_key_exists('X-RateLimit-Reset', $headers)) {
$headers['Retry-After'] = $headers['X-RateLimit-Reset'] - time();
}

parent::__construct(429, $message ?: 'You have exceeded your rate limit.', $previous, $headers, $code);
}
}
4 changes: 2 additions & 2 deletions src/Http/Middleware/RateLimit.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
use Dingo\Api\Routing\Router;
use Dingo\Api\Http\InternalRequest;
use Dingo\Api\Http\RateLimit\Handler;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Dingo\Api\Exception\RateLimitExceededException;

class RateLimit
{
Expand Down Expand Up @@ -64,7 +64,7 @@ public function handle($request, Closure $next)
$this->handler->rateLimitRequest($request, $route->getRateLimit(), $route->getRateLimitExpiration());

if ($this->handler->exceededRateLimit()) {
throw new HttpException(403, 'You have exceeded your rate limit.', null, $this->getHeaders());
throw new RateLimitExceededException('You have exceeded your rate limit.', null, $this->getHeaders());
}

$response = $next($request);
Expand Down
13 changes: 9 additions & 4 deletions tests/Http/Middleware/RateLimitTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
use Dingo\Api\Http\RateLimit\Handler;
use Dingo\Api\Tests\Stubs\ThrottleStub;
use Dingo\Api\Http\Middleware\RateLimit;
use Dingo\Api\Exception\RateLimitExceededException;
use Symfony\Component\HttpKernel\Exception\HttpException;

class RateLimitTest extends PHPUnit_Framework_TestCase
Expand Down Expand Up @@ -125,11 +126,15 @@ public function testRateLimitingFailsAndHeadersAreSetOnException()
return new Response('foo');
});
} catch (HttpException $exception) {
$this->assertSame(403, $exception->getStatusCode());
$this->assertInstanceOf(RateLimitExceededException::class, $exception);
$this->assertSame(429, $exception->getStatusCode());
$this->assertSame('You have exceeded your rate limit.', $exception->getMessage());
$this->assertArrayHasKey('X-RateLimit-Limit', $exception->getHeaders());
$this->assertArrayHasKey('X-RateLimit-Remaining', $exception->getHeaders());
$this->assertArrayHasKey('X-RateLimit-Reset', $exception->getHeaders());

$headers = $exception->getHeaders();
$this->assertSame($headers['X-RateLimit-Reset'] - time(), $headers['Retry-After']);
$this->assertArrayHasKey('X-RateLimit-Limit', $headers);
$this->assertArrayHasKey('X-RateLimit-Remaining', $headers);
$this->assertArrayHasKey('X-RateLimit-Reset', $headers);
}
}

Expand Down

0 comments on commit dc312a5

Please sign in to comment.