Skip to content

Commit 3c0ac2d

Browse files
authored
Merge pull request #7187 from ddevsr/redis-tls
fix: [Session] `Redis` connect to protocol `TLS`
2 parents 6e5a9cb + 8787e8e commit 3c0ac2d

4 files changed

Lines changed: 64 additions & 12 deletions

File tree

system/Session/Handlers/RedisHandler.php

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@
2424
*/
2525
class RedisHandler extends BaseHandler
2626
{
27-
private const DEFAULT_PORT = 6379;
27+
private const DEFAULT_PORT = 6379;
28+
private const DEFAULT_PROTOCOL = 'tcp';
2829

2930
/**
3031
* phpRedis instance
@@ -102,20 +103,21 @@ protected function setSavePath(): void
102103
throw SessionException::forEmptySavepath();
103104
}
104105

105-
if (preg_match('#(?:tcp://)?([^:?]+)(?:\:(\d+))?(\?.+)?#', $this->savePath, $matches)) {
106-
if (! isset($matches[3])) {
107-
$matches[3] = ''; // Just to avoid undefined index notices below
106+
if (preg_match('#(?:(tcp|tls)://)?([^:?]+)(?:\:(\d+))?(\?.+)?#', $this->savePath, $matches)) {
107+
if (! isset($matches[4])) {
108+
$matches[4] = ''; // Just to avoid undefined index notices below
108109
}
109110

110111
$this->savePath = [
111-
'host' => $matches[1],
112-
'port' => empty($matches[2]) ? self::DEFAULT_PORT : $matches[2],
113-
'password' => preg_match('#auth=([^\s&]+)#', $matches[3], $match) ? $match[1] : null,
114-
'database' => preg_match('#database=(\d+)#', $matches[3], $match) ? (int) $match[1] : 0,
115-
'timeout' => preg_match('#timeout=(\d+\.\d+|\d+)#', $matches[3], $match) ? (float) $match[1] : 0.0,
112+
'protocol' => ! empty($matches[1]) ? $matches[1] : self::DEFAULT_PROTOCOL,
113+
'host' => $matches[2],
114+
'port' => empty($matches[3]) ? self::DEFAULT_PORT : $matches[3],
115+
'password' => preg_match('#auth=([^\s&]+)#', $matches[4], $match) ? $match[1] : null,
116+
'database' => preg_match('#database=(\d+)#', $matches[4], $match) ? (int) $match[1] : 0,
117+
'timeout' => preg_match('#timeout=(\d+\.\d+|\d+)#', $matches[4], $match) ? (float) $match[1] : 0.0,
116118
];
117119

118-
preg_match('#prefix=([^\s&]+)#', $matches[3], $match) && $this->keyPrefix = $match[1];
120+
preg_match('#prefix=([^\s&]+)#', $matches[4], $match) && $this->keyPrefix = $match[1];
119121
} else {
120122
throw SessionException::forInvalidSavePathFormat($this->savePath);
121123
}
@@ -135,7 +137,7 @@ public function open($path, $name): bool
135137

136138
$redis = new Redis();
137139

138-
if (! $redis->connect($this->savePath['host'], ($this->savePath['host'][0] === '/' ? 0 : $this->savePath['port']), $this->savePath['timeout'])) {
140+
if (! $redis->connect($this->savePath['protocol'] . '://' . $this->savePath['host'], ($this->savePath['host'][0] === '/' ? 0 : $this->savePath['port']), $this->savePath['timeout'])) {
139141
$this->logger->error('Session: Unable to connect to Redis with the configured settings.');
140142
} elseif (isset($this->savePath['password']) && ! $redis->auth($this->savePath['password'])) {
141143
$this->logger->error('Session: Unable to authenticate to Redis instance.');

tests/system/Session/Handlers/Database/RedisHandlerTest.php

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,41 @@ protected function getInstance($options = [])
5454
return new RedisHandler(new AppConfig(), $this->userIpAddress);
5555
}
5656

57+
public function testSavePathWithoutProtocol()
58+
{
59+
$handler = $this->getInstance(
60+
['savePath' => '127.0.0.1:6379']
61+
);
62+
63+
$savePath = $this->getPrivateProperty($handler, 'savePath');
64+
65+
$this->assertSame('tcp', $savePath['protocol']);
66+
}
67+
68+
public function testSavePathTLSAuth()
69+
{
70+
$handler = $this->getInstance(
71+
['savePath' => 'tls://127.0.0.1:6379?auth=password']
72+
);
73+
74+
$savePath = $this->getPrivateProperty($handler, 'savePath');
75+
76+
$this->assertSame('tls', $savePath['protocol']);
77+
$this->assertSame('password', $savePath['password']);
78+
}
79+
80+
public function testSavePathTCPAuth()
81+
{
82+
$handler = $this->getInstance(
83+
['savePath' => 'tcp://127.0.0.1:6379?auth=password']
84+
);
85+
86+
$savePath = $this->getPrivateProperty($handler, 'savePath');
87+
88+
$this->assertSame('tcp', $savePath['protocol']);
89+
$this->assertSame('password', $savePath['password']);
90+
}
91+
5792
public function testSavePathTimeoutFloat()
5893
{
5994
$handler = $this->getInstance(
@@ -82,6 +117,19 @@ public function testOpen()
82117
$this->assertTrue($handler->open($this->sessionSavePath, $this->sessionName));
83118
}
84119

120+
public function testOpenWithDefaultProtocol()
121+
{
122+
$default = $this->sessionSavePath;
123+
124+
$this->sessionSavePath = '127.0.0.1:6379';
125+
126+
$handler = $this->getInstance();
127+
$this->assertTrue($handler->open($this->sessionSavePath, $this->sessionName));
128+
129+
// Rollback to default
130+
$this->sessionSavePath = $default;
131+
}
132+
85133
public function testWrite()
86134
{
87135
$handler = $this->getInstance();

user_guide_src/source/changelogs/v4.3.2.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ Deprecations
2727
Bugs Fixed
2828
**********
2929

30+
* Fixed : ``Session`` Redis connect to protocol TLS
31+
3032
See the repo's
3133
`CHANGELOG.md <https://github.com/codeigniter4/CodeIgniter4/blob/develop/CHANGELOG.md>`_
3234
for a complete list of bugs fixed.

user_guide_src/source/libraries/sessions.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -613,7 +613,7 @@ RedisHandler Driver
613613

614614
.. note:: Since Redis doesn't have a locking mechanism exposed, locks for
615615
this driver are emulated by a separate value that is kept for up
616-
to 300 seconds.
616+
to 300 seconds. With ``v4.3.2`` or above, You can connect ``Redis`` with **TLS** protocol.
617617

618618
Redis is a storage engine typically used for caching and popular because
619619
of its high performance, which is also probably your reason to use the

0 commit comments

Comments
 (0)