diff --git a/config/redirection.php b/config/redirection.php index ef0e923..abc3422 100644 --- a/config/redirection.php +++ b/config/redirection.php @@ -27,6 +27,17 @@ */ 'default_status_code' => (int)env('REDIRECT_DEFAULT_STATUS', 301), + /* + |-------------------------------------------------------------------------- + | Case sensitivity + |-------------------------------------------------------------------------- + | + | Whether to match URLs case sensitively or not. + | Default to false because most URLs are not case sensitive. + | + */ + 'case-sensitive' => (bool) env('REDIRECT_CASE_SENSITIVE', false), + /* |-------------------------------------------------------------------------- | Redirect Driver diff --git a/src/Drivers/FileRedirector.php b/src/Drivers/FileRedirector.php index cad6e44..c24edfe 100644 --- a/src/Drivers/FileRedirector.php +++ b/src/Drivers/FileRedirector.php @@ -19,6 +19,11 @@ public function getRedirectFor(string $path): ?Redirect { $redirect = config(config("redirection.drivers.{$this->driver}.source")); + if (false === config('redirection.case-sensitive')) { + $redirect = array_change_key_case($redirect, CASE_LOWER); + $path = strtolower($path); + } + if (! array_key_exists($path, $redirect)) { return null; } diff --git a/src/Models/Redirection.php b/src/Models/Redirection.php index 591da1b..fe72bf3 100644 --- a/src/Models/Redirection.php +++ b/src/Models/Redirection.php @@ -61,7 +61,7 @@ public static function getStatuses(): array */ public function scopeWhereOldUrl(Builder $query, string $url): Builder { - return $query->where('old_url', $url); + return $query->where('old_url', config('redirection.case-sensitive') ? $url : strtolower($url)); } /** @@ -74,7 +74,7 @@ public function scopeWhereOldUrl(Builder $query, string $url): Builder */ public function scopeWhereNewUrl(Builder $query, string $url): Builder { - return $query->where('new_url', $url); + return $query->where('new_url', config('redirection.case-sensitive') ? $url : strtolower($url)); } /** @@ -85,7 +85,8 @@ public function scopeWhereNewUrl(Builder $query, string $url): Builder */ public function setOldUrlAttribute(string $value): void { - $this->attributes['old_url'] = trim(parse_url($value)['path'], '/'); + $value = trim(parse_url($value)['path'], '/'); + $this->attributes['old_url'] = config('redirection.case-sensitive') ? $value : strtolower($value); } /** @@ -96,7 +97,8 @@ public function setOldUrlAttribute(string $value): void */ public function setNewUrlAttribute(string $value): void { - $this->attributes['new_url'] = trim(parse_url($value)['path'], '/'); + $value = trim(parse_url($value)['path'], '/'); + $this->attributes['new_url'] = config('redirection.case-sensitive') ? $value : strtolower($value); } /** @@ -127,7 +129,9 @@ public function syncOldRedirects(RedirectionModelContract $model, string $finalU */ public static function findValidOrNull(string $path): ?Redirection { - return static::where('old_url', $path === '/' ? $path : trim($path, '/')) + $path = ($path === '/' ? $path : trim($path, '/')); + + return static::where('old_url', config('redirection.case-sensitive') ? $path : strtolower($path)) ->whereNotNull('new_url') ->whereIn('status_code', array_keys(self::getStatuses())) ->latest() diff --git a/tests/Drivers/DatabaseRedirectionTest.php b/tests/Drivers/DatabaseRedirectionTest.php index 729da32..433a792 100644 --- a/tests/Drivers/DatabaseRedirectionTest.php +++ b/tests/Drivers/DatabaseRedirectionTest.php @@ -22,6 +22,36 @@ public function it_redirects_a_request(): void ->assertRedirect('new/url'); } + /** @test */ + public function it_doesnt_redirect_case_sensitive_requests(): void + { + $this->app['config']->set('redirection.driver', 'database'); + $this->app['config']->set('redirection.case-sensitive', true); + + Redirection::create([ + 'old_url' => 'old-url', + 'new_url' => 'new/url', + ]); + + $this->get('old-URL') + ->assertNotFound(); + } + + /** @test */ + public function it_does_redirect_case_insensitive_requests(): void + { + $this->app['config']->set('redirection.driver', 'database'); + $this->app['config']->set('redirection.case-sensitive', false); + + Redirection::create([ + 'old_url' => 'old-url', + 'new_url' => 'new/url', + ]); + + $this->get('OLD-URL') + ->assertRedirect('new/url'); + } + /** @test */ public function it_redirects_nested_requests(): void { diff --git a/tests/Drivers/FileRedirectorTest.php b/tests/Drivers/FileRedirectorTest.php index e7081f1..c263fa5 100644 --- a/tests/Drivers/FileRedirectorTest.php +++ b/tests/Drivers/FileRedirectorTest.php @@ -17,6 +17,30 @@ public function it_inserts_a_path_redirection_and_redirects_a_request_with_defau $this->get('old-url')->assertRedirect('new/url'); } + /** @test */ + public function it_inserts_a_path_redirection_and_redirects_a_request_with_case_sensitive_matching(): void + { + $this->app['config']->set('redirection.driver', 'config'); + $this->app['config']->set('redirection.case-sensitive', true); + $this->app['config']->set('redirection.urls', [ + 'old-url' => 'new/url', + ]); + + $this->get('old-URL')->assertNotFound(); + } + + /** @test */ + public function it_inserts_a_path_redirection_and_redirects_a_request_with_case_insensitive_matching(): void + { + $this->app['config']->set('redirection.driver', 'config'); + $this->app['config']->set('redirection.case-sensitive', false); + $this->app['config']->set('redirection.urls', [ + 'old-url' => 'new/url', + ]); + + $this->get('OLD-URL')->assertRedirect('new/url'); + } + /** @test */ public function it_inserts_a_path_redirection_and_redirects_a_request_with_a_custom_status_code(): void { diff --git a/tests/TestCase.php b/tests/TestCase.php index f83f730..0139bb9 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -39,6 +39,9 @@ protected function defineRoutes($router): void $router->middleware(RedirectRequests::class)->get('old-url', function () { return ''; }); + $router->middleware(RedirectRequests::class)->get('OLD-URL', function () { + return ''; + }); $router->middleware(RedirectRequests::class)->get('/new/url', function () { return ''; });