From 5eccc65d42a25e3095aa5341bc5232575aba753d Mon Sep 17 00:00:00 2001 From: Daniele Alessandri Date: Tue, 1 Sep 2020 11:35:35 +0200 Subject: [PATCH] Fix handling of username when using "redis://". The username is now correctly retrieved from the userinfo fragment of the URI when using the "redis" scheme and a "username:password" pair is present. Values retrieved from the userinfo fragment always override the ones specified in `username` and `password` if those fields are present in the query string. --- CHANGELOG.md | 9 ++++ src/Connection/Parameters.php | 11 ++++- tests/Predis/Connection/ParametersTest.php | 51 ++++++++++++++-------- 3 files changed, 53 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9afc7136..7b12f514 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,12 @@ +v1.1.5 (2020-09-xx) +================================================================================ + +- __FIX__: the username is now correctly retrieved from the userinfo fragment of +the URI when using the "redis" scheme and a "username:password" pair is present. +Values retrieved from the userinfo fragment always override the ones specified +in `username` and `password` if those fields are present in the query string. + + v1.1.4 (2020-08-31) ================================================================================ diff --git a/src/Connection/Parameters.php b/src/Connection/Parameters.php index 3349c96a..c1c3a73b 100644 --- a/src/Connection/Parameters.php +++ b/src/Connection/Parameters.php @@ -109,8 +109,17 @@ class Parameters implements ParametersInterface } if (stripos($uri, 'redis') === 0) { + if (isset($parsed['user'])) { + if (strlen($parsed['user'])) { + $parsed['username'] = $parsed['user']; + } + unset($parsed['user']); + } + if (isset($parsed['pass'])) { - $parsed['password'] = $parsed['pass']; + if (strlen($parsed['pass'])) { + $parsed['password'] = $parsed['pass']; + } unset($parsed['pass']); } diff --git a/tests/Predis/Connection/ParametersTest.php b/tests/Predis/Connection/ParametersTest.php index dbe3c3e7..dae74724 100644 --- a/tests/Predis/Connection/ParametersTest.php +++ b/tests/Predis/Connection/ParametersTest.php @@ -156,7 +156,7 @@ class ParametersTest extends PredisTestCase */ public function testParsingURIWithRedisScheme() { - $uri = 'redis://:secret@10.10.10.10:6400/5?timeout=0.5&persistent=1'; + $uri = 'redis://predis:secret@10.10.10.10:6400/5?timeout=0.5&persistent=1'; $expected = array( 'scheme' => 'redis', @@ -164,20 +164,48 @@ class ParametersTest extends PredisTestCase 'port' => 6400, 'timeout' => '0.5', 'persistent' => '1', + 'username' => 'predis', 'password' => 'secret', 'database' => '5', ); $parameters = Parameters::parse($uri); - // TODO: parse_url() in PHP >= 5.6 returns an empty "user" entry in the - // dictionary when no username has been provided in the URI string. This - // actually makes sense, but let's keep the test ugly & simple for now. - unset($parameters['user']); - $this->assertSame($expected, $parameters); } + /** + * @group disconnected + */ + public function testRedisSchemeOverridesUsernameAndPasswordInQueryString() + { + $parameters = Parameters::parse('redis://predis:secret@10.10.10.10/5?username=ignored&password=ignored'); + + $this->assertSame('predis', $parameters['username']); + $this->assertSame('secret', $parameters['password']); + } + + /** + * @group disconnected + */ + public function testRedisSchemeDoesNotOverridesUsernameAndPasswordInQueryStringOnEmptyAuthFragment() + { + $parameters = Parameters::parse('redis://:@10.10.10.10/5?username=predis&password=secret'); + + $this->assertSame('predis', $parameters['username']); + $this->assertSame('secret', $parameters['password']); + } + + /** + * @group disconnected + */ + public function testRedisSchemeOverridesDatabaseInQueryString() + { + $parameters = Parameters::parse('redis://10.10.10.10/5?database=10'); + + $this->assertSame('5', $parameters['database']); + } + /** * @group disconnected */ @@ -197,17 +225,6 @@ class ParametersTest extends PredisTestCase $this->assertSame($expected, $parameters); } - /** - * @group disconnected - */ - public function testRedisSchemeOverridesPasswordAndDatabaseInQueryString() - { - $parameters = Parameters::parse('redis://:secret@10.10.10.10/5?password=ignored&database=4'); - - $this->assertSame('secret', $parameters['password']); - $this->assertSame('5', $parameters['database']); - } - /** * @group disconnected */