Skip to content

Commit 69cbfc0

Browse files
authored
[6.x] Normalize scheme in Redis connections (#33892)
* Normalize scheme in Redis connections * Map `redis` and `rediss` schemes to `tcp` and `tls`
1 parent cb75c89 commit 69cbfc0

File tree

5 files changed

+230
-6
lines changed

5 files changed

+230
-6
lines changed

src/Illuminate/Redis/Connectors/PhpRedisConnector.php

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ public function connectToCluster(array $config, array $clusterOptions, array $op
5656
*/
5757
protected function buildClusterConnectionString(array $server)
5858
{
59-
return $server['host'].':'.$server['port'].'?'.Arr::query(Arr::only($server, [
59+
return $this->formatHost($server).':'.$server['port'].'?'.Arr::query(Arr::only($server, [
6060
'database', 'password', 'prefix', 'read_timeout',
6161
]));
6262
}
@@ -116,7 +116,7 @@ protected function establishConnection($client, array $config)
116116
$persistent = $config['persistent'] ?? false;
117117

118118
$parameters = [
119-
$config['host'],
119+
$this->formatHost($config),
120120
$config['port'],
121121
Arr::get($config, 'timeout', 0.0),
122122
$persistent ? Arr::get($config, 'persistent_id', null) : null,
@@ -165,4 +165,19 @@ protected function createRedisClusterInstance(array $servers, array $options)
165165
}
166166
});
167167
}
168+
169+
/**
170+
* Format the host using the scheme if available.
171+
*
172+
* @param array $options
173+
* @return string
174+
*/
175+
protected function formatHost(array $options)
176+
{
177+
if (isset($options['scheme'])) {
178+
return "{$options['scheme']}://{$options['host']}";
179+
}
180+
181+
return $options['host'];
182+
}
168183
}

src/Illuminate/Redis/RedisManager.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,12 @@ protected function parseConnectionConfiguration($config)
185185
{
186186
$parsed = (new ConfigurationUrlParser)->parseConfiguration($config);
187187

188+
$driver = strtolower($parsed['driver'] ?? '');
189+
190+
if (in_array($driver, ['tcp', 'tls'])) {
191+
$parsed['scheme'] = $driver;
192+
}
193+
188194
return array_filter($parsed, function ($key) {
189195
return ! in_array($key, ['driver', 'username'], true);
190196
}, ARRAY_FILTER_USE_KEY);

src/Illuminate/Support/ConfigurationUrlParser.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ class ConfigurationUrlParser
1717
'postgres' => 'pgsql',
1818
'postgresql' => 'pgsql',
1919
'sqlite3' => 'sqlite',
20+
'redis' => 'tcp',
21+
'rediss' => 'tls',
2022
];
2123

2224
/**

tests/Redis/RedisConnectorTest.php

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
<?php
2+
3+
namespace Illuminate\Tests\Redis;
4+
5+
use Illuminate\Foundation\Application;
6+
use Illuminate\Foundation\Testing\Concerns\InteractsWithRedis;
7+
use Illuminate\Redis\RedisManager;
8+
use Mockery as m;
9+
use PHPUnit\Framework\TestCase;
10+
11+
class RedisConnectorTest extends TestCase
12+
{
13+
use InteractsWithRedis;
14+
15+
protected function setUp(): void
16+
{
17+
parent::setUp();
18+
$this->setUpRedis();
19+
}
20+
21+
protected function tearDown(): void
22+
{
23+
parent::tearDown();
24+
25+
$this->tearDownRedis();
26+
27+
m::close();
28+
}
29+
30+
public function testDefaultConfiguration()
31+
{
32+
$host = env('REDIS_HOST', '127.0.0.1');
33+
$port = env('REDIS_PORT', 6379);
34+
35+
$predisClient = $this->redis['predis']->connection()->client();
36+
$parameters = $predisClient->getConnection()->getParameters();
37+
$this->assertEquals('tcp', $parameters->scheme);
38+
$this->assertEquals($host, $parameters->host);
39+
$this->assertEquals($port, $parameters->port);
40+
41+
$phpRedisClient = $this->redis['phpredis']->connection()->client();
42+
$this->assertEquals($host, $phpRedisClient->getHost());
43+
$this->assertEquals($port, $phpRedisClient->getPort());
44+
}
45+
46+
public function testUrl()
47+
{
48+
$host = env('REDIS_HOST', '127.0.0.1');
49+
$port = env('REDIS_PORT', 6379);
50+
51+
$predis = new RedisManager(new Application, 'predis', [
52+
'cluster' => false,
53+
'options' => [
54+
'prefix' => 'test_',
55+
],
56+
'default' => [
57+
'url' => "redis://{$host}:{$port}",
58+
'database' => 5,
59+
'timeout' => 0.5,
60+
],
61+
]);
62+
$predisClient = $predis->connection()->client();
63+
$parameters = $predisClient->getConnection()->getParameters();
64+
$this->assertEquals('tcp', $parameters->scheme);
65+
$this->assertEquals($host, $parameters->host);
66+
$this->assertEquals($port, $parameters->port);
67+
68+
$phpRedis = new RedisManager(new Application, 'phpredis', [
69+
'cluster' => false,
70+
'options' => [
71+
'prefix' => 'test_',
72+
],
73+
'default' => [
74+
'url' => "redis://{$host}:{$port}",
75+
'database' => 5,
76+
'timeout' => 0.5,
77+
],
78+
]);
79+
$phpRedisClient = $phpRedis->connection()->client();
80+
$this->assertEquals("tcp://{$host}", $phpRedisClient->getHost());
81+
$this->assertEquals($port, $phpRedisClient->getPort());
82+
}
83+
84+
public function testUrlWithScheme()
85+
{
86+
$host = env('REDIS_HOST', '127.0.0.1');
87+
$port = env('REDIS_PORT', 6379);
88+
89+
$predis = new RedisManager(new Application, 'predis', [
90+
'cluster' => false,
91+
'options' => [
92+
'prefix' => 'test_',
93+
],
94+
'default' => [
95+
'url' => "tls://{$host}:{$port}",
96+
'database' => 5,
97+
'timeout' => 0.5,
98+
],
99+
]);
100+
$predisClient = $predis->connection()->client();
101+
$parameters = $predisClient->getConnection()->getParameters();
102+
$this->assertEquals('tls', $parameters->scheme);
103+
$this->assertEquals($host, $parameters->host);
104+
$this->assertEquals($port, $parameters->port);
105+
106+
$phpRedis = new RedisManager(new Application, 'phpredis', [
107+
'cluster' => false,
108+
'options' => [
109+
'prefix' => 'test_',
110+
],
111+
'default' => [
112+
'url' => "tcp://{$host}:{$port}",
113+
'database' => 5,
114+
'timeout' => 0.5,
115+
],
116+
]);
117+
$phpRedisClient = $phpRedis->connection()->client();
118+
$this->assertEquals("tcp://{$host}", $phpRedisClient->getHost());
119+
$this->assertEquals($port, $phpRedisClient->getPort());
120+
}
121+
122+
public function testScheme()
123+
{
124+
$host = env('REDIS_HOST', '127.0.0.1');
125+
$port = env('REDIS_PORT', 6379);
126+
127+
$predis = new RedisManager(new Application, 'predis', [
128+
'cluster' => false,
129+
'options' => [
130+
'prefix' => 'test_',
131+
],
132+
'default' => [
133+
'scheme' => 'tls',
134+
'host' => $host,
135+
'port' => $port,
136+
'database' => 5,
137+
'timeout' => 0.5,
138+
],
139+
]);
140+
$predisClient = $predis->connection()->client();
141+
$parameters = $predisClient->getConnection()->getParameters();
142+
$this->assertEquals('tls', $parameters->scheme);
143+
$this->assertEquals($host, $parameters->host);
144+
$this->assertEquals($port, $parameters->port);
145+
146+
$phpRedis = new RedisManager(new Application, 'phpredis', [
147+
'cluster' => false,
148+
'options' => [
149+
'prefix' => 'test_',
150+
],
151+
'default' => [
152+
'scheme' => 'tcp',
153+
'host' => $host,
154+
'port' => $port,
155+
'database' => 5,
156+
'timeout' => 0.5,
157+
],
158+
]);
159+
$phpRedisClient = $phpRedis->connection()->client();
160+
$this->assertEquals("tcp://{$host}", $phpRedisClient->getHost());
161+
$this->assertEquals($port, $phpRedisClient->getPort());
162+
}
163+
}

tests/Support/ConfigurationUrlParserTest.php

Lines changed: 42 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ public function testDriversAliases()
2323
'postgres' => 'pgsql',
2424
'postgresql' => 'pgsql',
2525
'sqlite3' => 'sqlite',
26+
'redis' => 'tcp',
27+
'rediss' => 'tls',
2628
], ConfigurationUrlParser::getDriverAliases());
2729

2830
ConfigurationUrlParser::addDriverAlias('some-particular-alias', 'mysql');
@@ -33,6 +35,8 @@ public function testDriversAliases()
3335
'postgres' => 'pgsql',
3436
'postgresql' => 'pgsql',
3537
'sqlite3' => 'sqlite',
38+
'redis' => 'tcp',
39+
'rediss' => 'tls',
3640
'some-particular-alias' => 'mysql',
3741
], ConfigurationUrlParser::getDriverAliases());
3842

@@ -355,7 +359,7 @@ public function databaseUrls()
355359
'database' => 0,
356360
],
357361
[
358-
'driver' => 'redis',
362+
'driver' => 'tcp',
359363
'host' => 'ec2-111-1-1-1.compute-1.amazonaws.com',
360364
'port' => 111,
361365
'database' => 0,
@@ -367,19 +371,53 @@ public function databaseUrls()
367371
[
368372
'url' => 'redis://h:[email protected]:111/',
369373
'host' => '127.0.0.1',
370-
'password' => null,
371-
'port' => 6379,
374+
'password' => null,
375+
'port' => 6379,
372376
'database' => 2,
373377
],
374378
[
375-
'driver' => 'redis',
379+
'driver' => 'tcp',
376380
'host' => 'ec2-111-1-1-1.compute-1.amazonaws.com',
377381
'port' => 111,
378382
'database' => 2,
379383
'username' => 'h',
380384
'password' => 'asdfqwer1234asdf',
381385
],
382386
],
387+
'Redis Example with tls scheme' => [
388+
[
389+
'url' => 'tls://h:[email protected]:111',
390+
'host' => '127.0.0.1',
391+
'password' => null,
392+
'port' => 6379,
393+
'database' => 0,
394+
],
395+
[
396+
'driver' => 'tls',
397+
'host' => 'ec2-111-1-1-1.compute-1.amazonaws.com',
398+
'port' => 111,
399+
'database' => 0,
400+
'username' => 'h',
401+
'password' => 'asdfqwer1234asdf',
402+
],
403+
],
404+
'Redis Example with rediss scheme' => [
405+
[
406+
'url' => 'rediss://h:[email protected]:111',
407+
'host' => '127.0.0.1',
408+
'password' => null,
409+
'port' => 6379,
410+
'database' => 0,
411+
],
412+
[
413+
'driver' => 'tls',
414+
'host' => 'ec2-111-1-1-1.compute-1.amazonaws.com',
415+
'port' => 111,
416+
'database' => 0,
417+
'username' => 'h',
418+
'password' => 'asdfqwer1234asdf',
419+
],
420+
],
383421
];
384422
}
385423
}

0 commit comments

Comments
 (0)