From a77c2035f65b5905cb57f07d65fc7c7da59fd4cd Mon Sep 17 00:00:00 2001 From: Arman <407448+armanist@users.noreply.github.com> Date: Mon, 19 Oct 2026 13:40:30 +0400 Subject: [PATCH] [#585] Create missing parent folders for the file rate limiter path --- CHANGELOG.md | 1 + .../Adapters/FileRateLimitAdapter.php | 2 +- .../Adapters/FileRateLimitAdapterTest.php | 20 +++++++++++++++++++ 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fef80adab..4b763b9ec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -52,6 +52,7 @@ The format is based on Keep a Changelog. ### Fixed - The page not found response is JSON for every client that asks for JSON, not only when the `Accept` header is exactly `application/json`: clients such as axios (`application/json, text/plain, */*`), a `charset` parameter, `+json` types and AJAX requests used to get the HTML page. `page_not_found_response()` decides with `Request::expectsJson()` and takes an optional request (#581) - `core:env` now looks for the existing `.env` in the application base directory, so running it from another working directory asks for the confirmation instead of silently overwriting the file (#575) +- The file rate limiter creates the missing parent folders of its `path` (for example `cache/data` when `cache/` does not exist), instead of failing every request that goes through the rate limit middleware with `mkdir(): No such file or directory` (#585) ## [3.0.3] - 2026-07-10 diff --git a/src/RateLimit/Adapters/FileRateLimitAdapter.php b/src/RateLimit/Adapters/FileRateLimitAdapter.php index 766892acf..70c23af46 100644 --- a/src/RateLimit/Adapters/FileRateLimitAdapter.php +++ b/src/RateLimit/Adapters/FileRateLimitAdapter.php @@ -43,7 +43,7 @@ public function __construct(array $params) $this->fs = fs(); if (!$this->fs->isDirectory($this->path)) { - $this->fs->makeDirectory($this->path); + mkdir($this->path, 0777, true); } } diff --git a/tests/Unit/RateLimit/Adapters/FileRateLimitAdapterTest.php b/tests/Unit/RateLimit/Adapters/FileRateLimitAdapterTest.php index 589f30aac..507619944 100644 --- a/tests/Unit/RateLimit/Adapters/FileRateLimitAdapterTest.php +++ b/tests/Unit/RateLimit/Adapters/FileRateLimitAdapterTest.php @@ -83,6 +83,26 @@ public function testFileAdapterCreatesStorageDirectoryWhenMissing(): void } } + public function testFileAdapterCreatesMissingParentDirectories(): void + { + $root = base_dir() . DS . 'cache' . DS . 'rate_limit_tests_nested'; + $path = $root . DS . 'level_one' . DS . 'level_two'; + + deleteDirectoryWithFiles($root); + + try { + new FileRateLimitAdapter([ + 'ttl' => 30, + 'prefix' => 'test', + 'path' => $path, + ]); + + $this->assertTrue(fs()->isDirectory($path)); + } finally { + deleteDirectoryWithFiles($root); + } + } + public function testFileAdapterRetryAfterReturnsZeroForMissingOrInvalidState(): void { $adapter = new FileRateLimitAdapter([