Skip to content

Commit 4fbd825

Browse files
committed
Support redis:// URI scheme and deprecate default tcp:// URI scheme
1 parent 9ba9019 commit 4fbd825

File tree

3 files changed

+31
-11
lines changed

3 files changed

+31
-11
lines changed

README.md

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ It helps with establishing a plain TCP/IP connection to Redis
111111
and optionally authenticating (AUTH) and selecting the right database (SELECT).
112112

113113
```php
114-
$factory->createClient('localhost:6379')->then(
114+
$factory->createClient('redis://localhost:6379')->then(
115115
function (Client $client) {
116116
// client connected (and authenticated)
117117
},
@@ -121,26 +121,37 @@ $factory->createClient('localhost:6379')->then(
121121
);
122122
```
123123

124-
You can omit the port if you're connecting to the default port 6379:
124+
The `$redisUri` can be given in the form `[redis://][:auth@]host[:port][/db]`.
125+
You can omit the URI scheme and port if you're connecting to the default port 6379:
125126

126127
```php
128+
// both are equivalent due to defaults being applied
127129
$factory->createClient('localhost');
130+
$factory->createClient('redis://localhost:6379');
128131
```
129132

130-
You can optionally include a password that will be used to authenticate (AUTH command) the client:
133+
Redis supports password-based authentication (`AUTH` command). Note that Redis'
134+
authentication mechanism does not employ a username, so you can pass the
135+
password "secret" as part of the URI like this:
131136

132137
```php
133-
$factory->createClient('auth@localhost');
138+
$factory->createClient('redis://ignored:secret@localhost');
134139
```
135140

141+
> Legacy notice: The `redis://` scheme is defined and preferred as of `v1.2.0`.
142+
For BC reasons, the `Factory` defaults to the `tcp://` scheme in which case
143+
the authentication details would include the otherwise unused username.
144+
This legacy API will be removed in a future `v2.0.0` version, so it's highly
145+
recommended to upgrade to the above API.
146+
136147
You can optionally include a path that will be used to select (SELECT command) the right database:
137148

138149
```php
139-
$factory->createClient('localhost/2');
150+
$factory->createClient('redis://localhost/2');
140151
```
141152

142153
[Deprecated] You can omit the complete URI if you want to connect to the default
143-
address `localhost:6379`. This legacy API will be removed in a future
154+
address `redis://localhost:6379`. This legacy API will be removed in a future
144155
`v2.0.0` version, so it's highly recommended to upgrade to the above API.
145156

146157
```php

src/Factory.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ private function parseUrl($target)
109109
}
110110

111111
$parts = parse_url($target);
112-
if ($parts === false || !isset($parts['host']) || $parts['scheme'] !== 'tcp') {
112+
if ($parts === false || !isset($parts['scheme'], $parts['host']) || !in_array($parts['scheme'], array('tcp', 'redis'))) {
113113
throw new InvalidArgumentException('Given URL can not be parsed');
114114
}
115115

@@ -122,11 +122,11 @@ private function parseUrl($target)
122122
}
123123

124124
$auth = null;
125-
if (isset($parts['user'])) {
125+
if (isset($parts['user']) && $parts['scheme'] === 'tcp') {
126126
$auth = $parts['user'];
127127
}
128128
if (isset($parts['pass'])) {
129-
$auth .= ':' . $parts['pass'];
129+
$auth .= ($parts['scheme'] === 'tcp' ? ':' : '') . $parts['pass'];
130130
}
131131
if ($auth !== null) {
132132
$parts['auth'] = $auth;

tests/FactoryTest.php

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,19 @@ public function testWillWriteSelectCommandIfTargetContainsPath()
6565
$stream->expects($this->once())->method('write')->with("*2\r\n$6\r\nselect\r\n$4\r\ndemo\r\n");
6666

6767
$this->connector->expects($this->once())->method('connect')->willReturn(Promise\resolve($stream));
68-
$this->factory->createClient('tcp://127.0.0.1/demo');
68+
$this->factory->createClient('redis://127.0.0.1/demo');
6969
}
7070

71-
public function testWillWriteAuthCommandIfTargetContainsUserInfo()
71+
public function testWillWriteAuthCommandIfRedisUriContainsUserInfo()
72+
{
73+
$stream = $this->getMockBuilder('React\Socket\ConnectionInterface')->getMock();
74+
$stream->expects($this->once())->method('write')->with("*2\r\n$4\r\nauth\r\n$5\r\nworld\r\n");
75+
76+
$this->connector->expects($this->once())->method('connect')->willReturn(Promise\resolve($stream));
77+
$this->factory->createClient('redis://hello:[email protected]');
78+
}
79+
80+
public function testWillWriteAuthCommandIfTcpUriContainsUserInfo()
7281
{
7382
$stream = $this->getMockBuilder('React\Socket\ConnectionInterface')->getMock();
7483
$stream->expects($this->once())->method('write')->with("*2\r\n$4\r\nauth\r\n$11\r\nhello:world\r\n");

0 commit comments

Comments
 (0)