diff --git a/cache/stores/redis/lib.php b/cache/stores/redis/lib.php index 2b81e8eaf41..5c469056d85 100644 --- a/cache/stores/redis/lib.php +++ b/cache/stores/redis/lib.php @@ -234,6 +234,15 @@ class cachestore_redis extends cache_store implements cache_is_key_aware, cache_ // We only need the first record for the single redis. if (!$clustermode) { + // Handle the case when the server is not a Unix domain socket. + if ($port !== 0) { + // We only need the first record for the single redis. + $serverchunks = explode(':', $trimmedservers[0]); + // Get the last chunk as the port. + $port = array_pop($serverchunks); + // Combine the rest of the chunks back into a string as the server. + $server = implode(':', $serverchunks); + } break; } } @@ -259,8 +268,6 @@ class cachestore_redis extends cache_store implements cache_is_key_aware, cache_ if ($clustermode) { $redis = new RedisCluster(null, $trimmedservers, 1, 1, true, $password, !empty($opts) ? $opts : null); } else { - // We only need the first record for the single redis. - list($server, $port) = explode(':', $trimmedservers[0]); $redis = new Redis(); $redis->connect($server, $port, 1, null, 100, 1, $opts); if (!empty($password)) { diff --git a/lib/classes/session/redis.php b/lib/classes/session/redis.php index 93930adcbfe..2d67ea7909e 100644 --- a/lib/classes/session/redis.php +++ b/lib/classes/session/redis.php @@ -117,9 +117,6 @@ class redis extends handler implements SessionHandlerInterface { } if (isset($CFG->session_redis_encrypt) && $CFG->session_redis_encrypt) { - if (!$this->clustermode) { - $this->host[0] = 'tls://' . $this->host[0]; - } $this->sslopts = $CFG->session_redis_encrypt; } @@ -228,7 +225,7 @@ class redis extends handler implements SessionHandlerInterface { $port = 0; $trimmedservers[] = $server; } else { - $port = 6379; // No Unix socket so set default port. + $port = $this->port ?? 6379; // No Unix socket so set default port. if (strpos($server, ':')) { // Check for custom port. list($server, $port) = explode(':', $server); } @@ -237,6 +234,12 @@ class redis extends handler implements SessionHandlerInterface { // We only need the first record for the single redis. if (!$this->clustermode) { + // Handle the case when the server is not a Unix domain socket. + if ($port !== 0) { + list($server, ) = explode(':', $trimmedservers[0]); + } else { + $server = $trimmedservers[0]; + } break; } } @@ -266,9 +269,8 @@ class redis extends handler implements SessionHandlerInterface { $this->auth, !empty($opts) ? $opts : null); } else { $delay = rand(100, 500); - list($server, $port) = explode(':', $trimmedservers[0]); $this->connection = new \Redis(); - $this->connection->connect($server, $this->port ?? $port, 1, null, $delay, 1, $opts); + $this->connection->connect($server, $port, 1, null, $delay, 1, $opts); if ($this->auth !== '' && !$this->connection->auth($this->auth)) { throw new $exceptionclass('Unable to authenticate.'); } @@ -296,7 +298,7 @@ class redis extends handler implements SessionHandlerInterface { } return true; } catch (RedisException | RedisClusterException $e) { - $redishost = $this->clustermode ? implode(',', $this->host) : $this->host[0].':'.$this->port ?? $port; + $redishost = $this->clustermode ? implode(',', $this->host) : $server . ':' . $port; $logstring = "Failed to connect (try {$counter} out of " . self::MAX_RETRIES . ") to Redis "; $logstring .= "at ". $redishost .", the error returned was: {$e->getMessage()}"; debugging($logstring); diff --git a/lib/tests/session_redis_test.php b/lib/tests/session_redis_test.php index 1628f34e842..56ef3a57c43 100644 --- a/lib/tests/session_redis_test.php +++ b/lib/tests/session_redis_test.php @@ -69,13 +69,14 @@ class session_redis_test extends \advanced_testcase { $this->keyprefix = 'phpunit'.rand(1, 100000); - $CFG->session_redis_host = TEST_SESSION_REDIS_HOST; if (strpos(TEST_SESSION_REDIS_HOST, ':')) { list($server, $port) = explode(':', TEST_SESSION_REDIS_HOST); } else { $server = TEST_SESSION_REDIS_HOST; $port = 6379; } + $CFG->session_redis_host = $server; + $CFG->session_redis_port = $port; $opts = []; if (defined('TEST_SESSION_REDIS_ENCRYPT') && TEST_SESSION_REDIS_ENCRYPT) { @@ -344,10 +345,10 @@ class session_redis_test extends \advanced_testcase { $actual = $e->getMessage(); } - $host = TEST_SESSION_REDIS_HOST; - if ($this->encrypted) { - $host = "tls://$host"; - } + // The Redis session test config allows the user to put the port number inside the host. e.g. 127.0.0.1:6380. + // Therefore, to get the host, we need to explode it. + list($host, ) = explode(':', TEST_SESSION_REDIS_HOST); + $expected = "Failed to connect (try 5 out of 5) to Redis at $host:111111"; $this->assertDebuggingCalledCount(5); $this->assertStringContainsString($expected, $actual); @@ -367,7 +368,8 @@ class session_redis_test extends \advanced_testcase { $sess = new \core\session\redis(); - $prop = new \ReflectionProperty(\core\session\redis::class, 'host'); - $this->assertEquals('tls://' . TEST_SESSION_REDIS_HOST, $prop->getValue($sess)[0]); + $prop = new \ReflectionProperty(\core\session\redis::class, 'sslopts'); + + $this->assertEquals($CFG->session_redis_encrypt, $prop->getValue($sess)); } }