Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 8 additions & 5 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,16 @@ on:

jobs:
run-tests:
runs-on: ubuntu-20.04
runs-on: ubuntu-24.04
strategy:
fail-fast: false
matrix:
php: [ "8.0", "8.1", "8.2" ]
php: [ "8.0", "8.1", "8.2", "8.3", "8.4" ]
composer_flags: [ "", "--prefer-lowest" ]
symfony_version: [ "^5.4", "^6.1" ]
symfony_version: [ "^5.4", "^6.4" ]
exclude:
- php: "8.0"
symfony_version: "^6.1"
symfony_version: "^6.4"
name: PHP ${{ matrix.php }} SF ${{ matrix.symfony_version }} ${{ matrix.composer_flags}}
env:
PHP: ${{ matrix.os }}
Expand All @@ -38,8 +38,11 @@ jobs:
run: |
composer self-update
if [ "$SYMFONY_VERSION" != "" ]; then composer require "symfony/symfony:${SYMFONY_VERSION}" --no-update; fi;
if [ "$SYMFONY_VERSION" = "^6.1" ]; then composer remove --dev "friendsofsymfony/oauth-server-bundle" --no-update; fi;
if [ "$SYMFONY_VERSION" = "^6.4" ]; then composer remove --dev "friendsofsymfony/oauth-server-bundle" --no-update; fi;
COMPOSER_MEMORY_LIMIT=-1 composer update --prefer-dist --no-interaction $COMPOSER_FLAGS
- name: Static analysis
run: |
./vendor/bin/phpstan --memory-limit=-1
- name: Run tests
run: |
SYMFONY_DEPRECATIONS_HELPER=weak vendor/bin/simple-phpunit --coverage-text --coverage-clover=coverage.clover
Expand Down
10 changes: 3 additions & 7 deletions DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,9 @@ class Configuration implements ConfigurationInterface
public function getConfigTreeBuilder(): TreeBuilder
{
$treeBuilder = new TreeBuilder('noxlogic_rate_limit');
// Keep compatibility with symfony/config < 4.2
if (\method_exists($treeBuilder, 'getRootNode')) {
$rootNode = $treeBuilder->getRootNode();
} else {
$rootNode = $treeBuilder->root('noxlogic_rate_limit');
}
$rootNode
$rootNode = $treeBuilder->getRootNode();

$rootNode // @phpstan-ignore method.notFound
->canBeDisabled()
->children()
->enumNode('storage_engine')
Expand Down
1 change: 1 addition & 0 deletions DependencyInjection/NoxlogicRateLimitExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ class NoxlogicRateLimitExtension extends Extension
{
/**
* {@inheritDoc}
* @param mixed[][] $configs
*/
public function load(array $configs, ContainerBuilder $container): void
{
Expand Down
5 changes: 2 additions & 3 deletions EventListener/HeaderModificationListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
namespace Noxlogic\RateLimitBundle\EventListener;

use Noxlogic\RateLimitBundle\Service\RateLimitInfo;
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
use Symfony\Component\HttpKernel\Event\ResponseEvent;

class HeaderModificationListener extends BaseListener
Expand All @@ -18,7 +17,7 @@ public function __construct($defaultParameters = array())
}

/**
* @param FilterResponseEvent|ResponseEvent $event
* @param ResponseEvent $event
*/
public function onKernelResponse($event)
{
Expand All @@ -44,7 +43,7 @@ public function onKernelResponse($event)

$response = $event->getResponse();
$response->headers->set($this->getParameter('header_limit_name'), $rateLimitInfo->getLimit());
$response->headers->set($this->getParameter('header_remaining_name'), $remaining);
$response->headers->set($this->getParameter('header_remaining_name'), (string) $remaining);
$response->headers->set($this->getParameter('header_reset_name'), $rateLimitInfo->getResetTimestamp());
}
}
2 changes: 1 addition & 1 deletion Events/CheckedRateLimitEvent.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class CheckedRateLimitEvent extends Event

protected ?RateLimit $rateLimit;

public function __construct(Request $request, RateLimit $rateLimit = null)
public function __construct(Request $request, ?RateLimit $rateLimit = null)
{
$this->request = $request;
$this->rateLimit = $rateLimit;
Expand Down
4 changes: 2 additions & 2 deletions Service/RateLimitService.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
class RateLimitService
{
/**
* @var Storage\StorageInterface
* @var ?Storage\StorageInterface
*/
protected $storage;

Expand All @@ -20,7 +20,7 @@ public function setStorage(StorageInterface $storage)
}

/**
* @return StorageInterface
* @return ?StorageInterface
*/
public function getStorage()
{
Expand Down
2 changes: 1 addition & 1 deletion Service/Storage/PhpRedis.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
class PhpRedis implements StorageInterface
{
/**
* @var \Redis
* @var \Redis|\RedisCluster
*/
protected $client;

Expand Down
6 changes: 3 additions & 3 deletions Service/Storage/Redis.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,9 @@ public function createRate($key, $limit, $period)

$reset = time() + $period;

$this->client->hset($key, 'limit', $limit);
$this->client->hset($key, 'calls', 1);
$this->client->hset($key, 'reset', $reset);
$this->client->hset($key, 'limit', (string) $limit);
$this->client->hset($key, 'calls', '1');
$this->client->hset($key, 'reset', (string) $reset);
$this->client->expire($key, $period);

$rateLimitInfo = new RateLimitInfo();
Expand Down
12 changes: 7 additions & 5 deletions Service/Storage/StorageInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,18 @@ interface StorageInterface
/**
* Get information about the current rate
*
* @param string $key
* @return RateLimitInfo Rate limit information
*/
* @param string $key
* @return RateLimitInfo|bool Rate limit information
* @todo: Replace return type with RateLimitInfo|false when PHP 8.2 is the minimum version
*/
public function getRateInfo($key);

/**
* Limit the rate by one
*
* @param string $key
* @return RateLimitInfo Rate limit info
* @param string $key
* @return RateLimitInfo|bool Rate limit info
* @todo: Replace return type with RateLimitInfo|false when PHP 8.2 is the minimum version
*/
public function limitRate($key);

Expand Down
12 changes: 3 additions & 9 deletions Tests/EventListener/HeaderModificationListenerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,11 @@
namespace Noxlogic\RateLimitBundle\Tests\EventListener;

use Noxlogic\RateLimitBundle\EventListener\HeaderModificationListener;
use Noxlogic\RateLimitBundle\Events\ProxyFilterResponseEvent;
use Noxlogic\RateLimitBundle\Service\RateLimitInfo;
use Noxlogic\RateLimitBundle\Tests\TestCase;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\ControllerEvent;
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
use Symfony\Component\HttpKernel\Event\ResponseEvent;
use Symfony\Component\HttpKernel\HttpKernelInterface;

Expand Down Expand Up @@ -136,19 +134,15 @@ public function testListenerWithoutRateInfo()
}

/**
* @return FilterResponseEvent|ControllerEvent
* @return ResponseEvent
*/
protected function createEvent()
{
$kernel = $this->getMockBuilder('Symfony\\Component\\HttpKernel\\HttpKernelInterface')->getMock();
$kernel = $this->getMockBuilder(HttpKernelInterface::class)->getMock();
$request = new Request();
$response = new Response();

if (class_exists('Symfony\\Component\\HttpKernel\\Event\\ControllerEvent')) {
$event = new ResponseEvent($kernel, $request, HttpKernelInterface::MASTER_REQUEST, $response);
} else {
$event = new FilterResponseEvent($kernel, $request, HttpKernelInterface::MASTER_REQUEST, $response);
}
$event = new ResponseEvent($kernel, $request, HttpKernelInterface::MAIN_REQUEST, $response);

return $event;
}
Expand Down
7 changes: 4 additions & 3 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,16 @@
],
"require": {
"php": "^8.0",
"symfony/framework-bundle": "^5.4.2|^6.1"
"symfony/framework-bundle": "^5.4.2|^6.4"
},
"require-dev": {
"symfony/phpunit-bridge": ">=5.4",
"psr/simple-cache": "^1.0|^2.0",
"doctrine/cache": "^1.5",
"psr/cache": "^1.0|^2.0",
"predis/predis": "^0.8|^1.1|^2.0",
"friendsofsymfony/oauth-server-bundle": "^1.5|^2.0@dev"
"predis/predis": "^1.1|^2.0",
"friendsofsymfony/oauth-server-bundle": "^1.5|^2.0@dev",
"phpstan/phpstan": "^2.1"
},
"suggest": {
"snc/redis-bundle": "Use Redis as a storage engine.",
Expand Down
Loading