Skip to content

Commit

Permalink
[6.x] Normalize scheme in Redis connections (#33892)
Browse files Browse the repository at this point in the history
* Normalize scheme in Redis connections

* Map `redis` and `rediss` schemes to `tcp` and `tls`
  • Loading branch information
sebdesign authored Aug 17, 2020
1 parent cb75c89 commit 69cbfc0
Show file tree
Hide file tree
Showing 5 changed files with 230 additions and 6 deletions.
19 changes: 17 additions & 2 deletions src/Illuminate/Redis/Connectors/PhpRedisConnector.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ public function connectToCluster(array $config, array $clusterOptions, array $op
*/
protected function buildClusterConnectionString(array $server)
{
return $server['host'].':'.$server['port'].'?'.Arr::query(Arr::only($server, [
return $this->formatHost($server).':'.$server['port'].'?'.Arr::query(Arr::only($server, [
'database', 'password', 'prefix', 'read_timeout',
]));
}
Expand Down Expand Up @@ -116,7 +116,7 @@ protected function establishConnection($client, array $config)
$persistent = $config['persistent'] ?? false;

$parameters = [
$config['host'],
$this->formatHost($config),
$config['port'],
Arr::get($config, 'timeout', 0.0),
$persistent ? Arr::get($config, 'persistent_id', null) : null,
Expand Down Expand Up @@ -165,4 +165,19 @@ protected function createRedisClusterInstance(array $servers, array $options)
}
});
}

/**
* Format the host using the scheme if available.
*
* @param array $options
* @return string
*/
protected function formatHost(array $options)
{
if (isset($options['scheme'])) {
return "{$options['scheme']}://{$options['host']}";
}

return $options['host'];
}
}
6 changes: 6 additions & 0 deletions src/Illuminate/Redis/RedisManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,12 @@ protected function parseConnectionConfiguration($config)
{
$parsed = (new ConfigurationUrlParser)->parseConfiguration($config);

$driver = strtolower($parsed['driver'] ?? '');

if (in_array($driver, ['tcp', 'tls'])) {
$parsed['scheme'] = $driver;
}

return array_filter($parsed, function ($key) {
return ! in_array($key, ['driver', 'username'], true);
}, ARRAY_FILTER_USE_KEY);
Expand Down
2 changes: 2 additions & 0 deletions src/Illuminate/Support/ConfigurationUrlParser.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ class ConfigurationUrlParser
'postgres' => 'pgsql',
'postgresql' => 'pgsql',
'sqlite3' => 'sqlite',
'redis' => 'tcp',
'rediss' => 'tls',
];

/**
Expand Down
163 changes: 163 additions & 0 deletions tests/Redis/RedisConnectorTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
<?php

namespace Illuminate\Tests\Redis;

use Illuminate\Foundation\Application;
use Illuminate\Foundation\Testing\Concerns\InteractsWithRedis;
use Illuminate\Redis\RedisManager;
use Mockery as m;
use PHPUnit\Framework\TestCase;

class RedisConnectorTest extends TestCase
{
use InteractsWithRedis;

protected function setUp(): void
{
parent::setUp();
$this->setUpRedis();
}

protected function tearDown(): void
{
parent::tearDown();

$this->tearDownRedis();

m::close();
}

public function testDefaultConfiguration()
{
$host = env('REDIS_HOST', '127.0.0.1');
$port = env('REDIS_PORT', 6379);

$predisClient = $this->redis['predis']->connection()->client();
$parameters = $predisClient->getConnection()->getParameters();
$this->assertEquals('tcp', $parameters->scheme);
$this->assertEquals($host, $parameters->host);
$this->assertEquals($port, $parameters->port);

$phpRedisClient = $this->redis['phpredis']->connection()->client();
$this->assertEquals($host, $phpRedisClient->getHost());
$this->assertEquals($port, $phpRedisClient->getPort());
}

public function testUrl()
{
$host = env('REDIS_HOST', '127.0.0.1');
$port = env('REDIS_PORT', 6379);

$predis = new RedisManager(new Application, 'predis', [
'cluster' => false,
'options' => [
'prefix' => 'test_',
],
'default' => [
'url' => "redis://{$host}:{$port}",
'database' => 5,
'timeout' => 0.5,
],
]);
$predisClient = $predis->connection()->client();
$parameters = $predisClient->getConnection()->getParameters();
$this->assertEquals('tcp', $parameters->scheme);
$this->assertEquals($host, $parameters->host);
$this->assertEquals($port, $parameters->port);

$phpRedis = new RedisManager(new Application, 'phpredis', [
'cluster' => false,
'options' => [
'prefix' => 'test_',
],
'default' => [
'url' => "redis://{$host}:{$port}",
'database' => 5,
'timeout' => 0.5,
],
]);
$phpRedisClient = $phpRedis->connection()->client();
$this->assertEquals("tcp://{$host}", $phpRedisClient->getHost());
$this->assertEquals($port, $phpRedisClient->getPort());
}

public function testUrlWithScheme()
{
$host = env('REDIS_HOST', '127.0.0.1');
$port = env('REDIS_PORT', 6379);

$predis = new RedisManager(new Application, 'predis', [
'cluster' => false,
'options' => [
'prefix' => 'test_',
],
'default' => [
'url' => "tls://{$host}:{$port}",
'database' => 5,
'timeout' => 0.5,
],
]);
$predisClient = $predis->connection()->client();
$parameters = $predisClient->getConnection()->getParameters();
$this->assertEquals('tls', $parameters->scheme);
$this->assertEquals($host, $parameters->host);
$this->assertEquals($port, $parameters->port);

$phpRedis = new RedisManager(new Application, 'phpredis', [
'cluster' => false,
'options' => [
'prefix' => 'test_',
],
'default' => [
'url' => "tcp://{$host}:{$port}",
'database' => 5,
'timeout' => 0.5,
],
]);
$phpRedisClient = $phpRedis->connection()->client();
$this->assertEquals("tcp://{$host}", $phpRedisClient->getHost());
$this->assertEquals($port, $phpRedisClient->getPort());
}

public function testScheme()
{
$host = env('REDIS_HOST', '127.0.0.1');
$port = env('REDIS_PORT', 6379);

$predis = new RedisManager(new Application, 'predis', [
'cluster' => false,
'options' => [
'prefix' => 'test_',
],
'default' => [
'scheme' => 'tls',
'host' => $host,
'port' => $port,
'database' => 5,
'timeout' => 0.5,
],
]);
$predisClient = $predis->connection()->client();
$parameters = $predisClient->getConnection()->getParameters();
$this->assertEquals('tls', $parameters->scheme);
$this->assertEquals($host, $parameters->host);
$this->assertEquals($port, $parameters->port);

$phpRedis = new RedisManager(new Application, 'phpredis', [
'cluster' => false,
'options' => [
'prefix' => 'test_',
],
'default' => [
'scheme' => 'tcp',
'host' => $host,
'port' => $port,
'database' => 5,
'timeout' => 0.5,
],
]);
$phpRedisClient = $phpRedis->connection()->client();
$this->assertEquals("tcp://{$host}", $phpRedisClient->getHost());
$this->assertEquals($port, $phpRedisClient->getPort());
}
}
46 changes: 42 additions & 4 deletions tests/Support/ConfigurationUrlParserTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ public function testDriversAliases()
'postgres' => 'pgsql',
'postgresql' => 'pgsql',
'sqlite3' => 'sqlite',
'redis' => 'tcp',
'rediss' => 'tls',
], ConfigurationUrlParser::getDriverAliases());

ConfigurationUrlParser::addDriverAlias('some-particular-alias', 'mysql');
Expand All @@ -33,6 +35,8 @@ public function testDriversAliases()
'postgres' => 'pgsql',
'postgresql' => 'pgsql',
'sqlite3' => 'sqlite',
'redis' => 'tcp',
'rediss' => 'tls',
'some-particular-alias' => 'mysql',
], ConfigurationUrlParser::getDriverAliases());

Expand Down Expand Up @@ -355,7 +359,7 @@ public function databaseUrls()
'database' => 0,
],
[
'driver' => 'redis',
'driver' => 'tcp',
'host' => 'ec2-111-1-1-1.compute-1.amazonaws.com',
'port' => 111,
'database' => 0,
Expand All @@ -367,19 +371,53 @@ public function databaseUrls()
[
'url' => 'redis://h:asdfqwer1234asdf@ec2-111-1-1-1.compute-1.amazonaws.com:111/',
'host' => '127.0.0.1',
'password' => null,
'port' => 6379,
'password' => null,
'port' => 6379,
'database' => 2,
],
[
'driver' => 'redis',
'driver' => 'tcp',
'host' => 'ec2-111-1-1-1.compute-1.amazonaws.com',
'port' => 111,
'database' => 2,
'username' => 'h',
'password' => 'asdfqwer1234asdf',
],
],
'Redis Example with tls scheme' => [
[
'url' => 'tls://h:asdfqwer1234asdf@ec2-111-1-1-1.compute-1.amazonaws.com:111',
'host' => '127.0.0.1',
'password' => null,
'port' => 6379,
'database' => 0,
],
[
'driver' => 'tls',
'host' => 'ec2-111-1-1-1.compute-1.amazonaws.com',
'port' => 111,
'database' => 0,
'username' => 'h',
'password' => 'asdfqwer1234asdf',
],
],
'Redis Example with rediss scheme' => [
[
'url' => 'rediss://h:asdfqwer1234asdf@ec2-111-1-1-1.compute-1.amazonaws.com:111',
'host' => '127.0.0.1',
'password' => null,
'port' => 6379,
'database' => 0,
],
[
'driver' => 'tls',
'host' => 'ec2-111-1-1-1.compute-1.amazonaws.com',
'port' => 111,
'database' => 0,
'username' => 'h',
'password' => 'asdfqwer1234asdf',
],
],
];
}
}

0 comments on commit 69cbfc0

Please sign in to comment.