diff options
author | John Molakvoæ <skjnldsv@users.noreply.github.com> | 2021-07-22 12:47:26 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-07-22 12:47:26 +0200 |
commit | f14b8aa34bfb9f7af7b23cfecc09e2fb8f604c1b (patch) | |
tree | 7f02c9fcb169d6b091e39b5db65599a098822c54 | |
parent | dd4668f935f59cdb21deea38cfd16e6226798da0 (diff) | |
parent | 6e00fe8c26c8d1cd68497911371c3b4b785d903c (diff) | |
download | nextcloud-server-f14b8aa34bfb9f7af7b23cfecc09e2fb8f604c1b.tar.gz nextcloud-server-f14b8aa34bfb9f7af7b23cfecc09e2fb8f604c1b.zip |
Merge pull request #27888 from nextcloud/fix/redis-auth
-rw-r--r-- | .drone.yml | 74 | ||||
-rw-r--r-- | build/psalm-baseline.xml | 4 | ||||
-rw-r--r-- | build/stubs/redis.php | 212 | ||||
-rw-r--r-- | build/stubs/redis_cluster.php | 58 | ||||
-rw-r--r-- | config/config.sample.php | 20 | ||||
-rw-r--r-- | lib/private/RedisFactory.php | 116 |
6 files changed, 286 insertions, 198 deletions
diff --git a/.drone.yml b/.drone.yml index e5ef78f3d18..43a3866ce02 100644 --- a/.drone.yml +++ b/.drone.yml @@ -739,7 +739,7 @@ steps: commands: - git submodule update --init - name: integration-capabilities_features - image: ghcr.io/nextcloud/continuous-integration-integration-php7.3:integration-php7.3-2 + image: ghcr.io/nextcloud/continuous-integration-integration-php7.3:latest commands: - bash tests/drone-run-integration-tests.sh || exit 0 - ./occ maintenance:install --admin-pass=admin --data-dir=/dev/shm/nc_int @@ -764,7 +764,7 @@ steps: commands: - git submodule update --init - name: integration-collaboration_features - image: ghcr.io/nextcloud/continuous-integration-integration-php7.3:integration-php7.3-2 + image: ghcr.io/nextcloud/continuous-integration-integration-php7.3:latest commands: - bash tests/drone-run-integration-tests.sh || exit 0 - ./occ maintenance:install --admin-pass=admin --data-dir=/dev/shm/nc_int @@ -789,7 +789,7 @@ steps: commands: - git submodule update --init - name: integration-federation_features - image: ghcr.io/nextcloud/continuous-integration-integration-php7.3:integration-php7.3-2 + image: ghcr.io/nextcloud/continuous-integration-integration-php7.3:latest commands: - bash tests/drone-run-integration-tests.sh || exit 0 - ./occ maintenance:install --admin-pass=admin @@ -814,7 +814,7 @@ steps: commands: - git submodule update --init - name: integration-auth - image: ghcr.io/nextcloud/continuous-integration-integration-php7.3:integration-php7.3-2 + image: ghcr.io/nextcloud/continuous-integration-integration-php7.3:latest commands: - bash tests/drone-run-integration-tests.sh || exit 0 - ./occ maintenance:install --admin-pass=admin --data-dir=/dev/shm/nc_int @@ -839,7 +839,7 @@ steps: commands: - git submodule update --init - name: integration-avatar - image: ghcr.io/nextcloud/continuous-integration-integration-php7.3:integration-php7.3-2 + image: ghcr.io/nextcloud/continuous-integration-integration-php7.3:latest commands: - bash tests/drone-run-integration-tests.sh || exit 0 - ./occ maintenance:install --admin-pass=admin --data-dir=/dev/shm/nc_int @@ -864,7 +864,7 @@ steps: commands: - git submodule update --init - name: integration-maintenance-mode - image: ghcr.io/nextcloud/continuous-integration-integration-php7.3:integration-php7.3-2 + image: ghcr.io/nextcloud/continuous-integration-integration-php7.3:latest commands: - bash tests/drone-run-integration-tests.sh || exit 0 - ./occ maintenance:install --admin-pass=admin --data-dir=/dev/shm/nc_int @@ -889,7 +889,7 @@ steps: commands: - git submodule update --init - name: integration-ratelimiting - image: ghcr.io/nextcloud/continuous-integration-integration-php7.3:integration-php7.3-2 + image: ghcr.io/nextcloud/continuous-integration-integration-php7.3:latest commands: - bash tests/drone-run-integration-tests.sh || exit 0 - ./occ maintenance:install --admin-pass=admin --data-dir=/dev/shm/nc_int @@ -924,7 +924,7 @@ steps: commands: - git submodule update --init - name: integration-carddav - image: ghcr.io/nextcloud/continuous-integration-integration-php7.3:integration-php7.3-2 + image: ghcr.io/nextcloud/continuous-integration-integration-php7.3:latest commands: - bash tests/drone-run-integration-tests.sh || exit 0 - ./occ maintenance:install --admin-pass=admin --data-dir=/dev/shm/nc_int @@ -949,7 +949,7 @@ steps: commands: - git submodule update --init - name: integration-dav-v2 - image: ghcr.io/nextcloud/continuous-integration-integration-php7.3:integration-php7.3-2 + image: ghcr.io/nextcloud/continuous-integration-integration-php7.3:latest commands: - bash tests/drone-run-integration-tests.sh || exit 0 - ./occ maintenance:install --admin-pass=admin --data-dir=/dev/shm/nc_int @@ -974,7 +974,7 @@ steps: commands: - git submodule update --init - name: integration-ocs-v1 - image: ghcr.io/nextcloud/continuous-integration-integration-php7.3:integration-php7.3-2 + image: ghcr.io/nextcloud/continuous-integration-integration-php7.3:latest commands: - bash tests/drone-run-integration-tests.sh || exit 0 - ./occ maintenance:install --admin-pass=admin --data-dir=/dev/shm/nc_int @@ -999,7 +999,7 @@ steps: commands: - git submodule update --init - name: integration-checksums-v1 - image: ghcr.io/nextcloud/continuous-integration-integration-php7.3:integration-php7.3-2 + image: ghcr.io/nextcloud/continuous-integration-integration-php7.3:latest commands: - bash tests/drone-run-integration-tests.sh || exit 0 - ./occ maintenance:install --admin-pass=admin --data-dir=/dev/shm/nc_int @@ -1024,7 +1024,7 @@ steps: commands: - git submodule update --init - name: integration-external-storage - image: ghcr.io/nextcloud/continuous-integration-integration-php7.3:integration-php7.3-2 + image: ghcr.io/nextcloud/continuous-integration-integration-php7.3:latest commands: - bash tests/drone-run-integration-tests.sh || exit 0 - ./occ maintenance:install --admin-pass=admin --data-dir=/dev/shm/nc_int @@ -1049,7 +1049,7 @@ steps: commands: - git submodule update --init - name: integration-provisioning-v1 - image: ghcr.io/nextcloud/continuous-integration-integration-php7.3:integration-php7.3-2 + image: ghcr.io/nextcloud/continuous-integration-integration-php7.3:latest commands: - bash tests/drone-run-integration-tests.sh || exit 0 - ./occ maintenance:install --admin-pass=admin --data-dir=/dev/shm/nc_int @@ -1074,7 +1074,7 @@ steps: commands: - git submodule update --init - name: integration-tags - image: ghcr.io/nextcloud/continuous-integration-integration-php7.3:integration-php7.3-2 + image: ghcr.io/nextcloud/continuous-integration-integration-php7.3:latest commands: - bash tests/drone-run-integration-tests.sh || exit 0 - ./occ maintenance:install --admin-pass=admin --data-dir=/dev/shm/nc_int @@ -1099,7 +1099,7 @@ steps: commands: - git submodule update --init - name: integration-caldav - image: ghcr.io/nextcloud/continuous-integration-integration-php7.3:integration-php7.3-2 + image: ghcr.io/nextcloud/continuous-integration-integration-php7.3:latest commands: - bash tests/drone-run-integration-tests.sh || exit 0 - ./occ maintenance:install --admin-pass=admin --data-dir=/dev/shm/nc_int @@ -1124,7 +1124,7 @@ steps: commands: - git submodule update --init - name: integration-comments - image: ghcr.io/nextcloud/continuous-integration-integration-php7.3:integration-php7.3-2 + image: ghcr.io/nextcloud/continuous-integration-integration-php7.3:latest commands: - bash tests/drone-run-integration-tests.sh || exit 0 - ./occ maintenance:install --admin-pass=admin --data-dir=/dev/shm/nc_int @@ -1149,7 +1149,7 @@ steps: commands: - git submodule update --init - name: integration-comments-search - image: ghcr.io/nextcloud/continuous-integration-integration-php7.3:integration-php7.3-2 + image: ghcr.io/nextcloud/continuous-integration-integration-php7.3:latest commands: - bash tests/drone-run-integration-tests.sh || exit 0 - ./occ maintenance:install --admin-pass=admin --data-dir=/dev/shm/nc_int @@ -1174,7 +1174,7 @@ steps: commands: - git submodule update --init - name: integration-contacts-menu - image: ghcr.io/nextcloud/continuous-integration-integration-php7.3:integration-php7.3-2 + image: ghcr.io/nextcloud/continuous-integration-integration-php7.3:latest commands: - bash tests/drone-run-integration-tests.sh || exit 0 - ./occ maintenance:install --admin-pass=admin --data-dir=/dev/shm/nc_int @@ -1199,7 +1199,7 @@ steps: commands: - git submodule update --init - name: integration-favorites - image: ghcr.io/nextcloud/continuous-integration-integration-php7.3:integration-php7.3-2 + image: ghcr.io/nextcloud/continuous-integration-integration-php7.3:latest commands: - bash tests/drone-run-integration-tests.sh || exit 0 - ./occ maintenance:install --admin-pass=admin --data-dir=/dev/shm/nc_int @@ -1224,7 +1224,7 @@ steps: commands: - git submodule update --init - name: integration-provisioning-v2 - image: ghcr.io/nextcloud/continuous-integration-integration-php7.3:integration-php7.3-2 + image: ghcr.io/nextcloud/continuous-integration-integration-php7.3:latest commands: - bash tests/drone-run-integration-tests.sh || exit 0 - ./occ maintenance:install --admin-pass=admin --data-dir=/dev/shm/nc_int @@ -1249,7 +1249,7 @@ steps: commands: - git submodule update --init - name: integration-webdav-related - image: ghcr.io/nextcloud/continuous-integration-integration-php7.3:integration-php7.3-2 + image: ghcr.io/nextcloud/continuous-integration-integration-php7.3:latest commands: - bash tests/drone-run-integration-tests.sh || exit 0 - ./occ maintenance:install --admin-pass=admin --data-dir=/dev/shm/nc_int @@ -1274,7 +1274,7 @@ steps: commands: - git submodule update --init - name: integration-sharees-features - image: ghcr.io/nextcloud/continuous-integration-integration-php7.3:integration-php7.3-2 + image: ghcr.io/nextcloud/continuous-integration-integration-php7.3:latest commands: - bash tests/drone-run-integration-tests.sh || exit 0 - ./occ maintenance:install --admin-pass=admin --data-dir=/dev/shm/nc_int @@ -1299,7 +1299,7 @@ steps: commands: - git submodule update --init - name: integration-sharees-v2-features - image: ghcr.io/nextcloud/continuous-integration-integration-php7.3:integration-php7.3-2 + image: ghcr.io/nextcloud/continuous-integration-integration-php7.3:latest commands: - bash tests/drone-run-integration-tests.sh || exit 0 - ./occ maintenance:install --admin-pass=admin --data-dir=/dev/shm/nc_int @@ -1324,7 +1324,7 @@ steps: commands: - git submodule update --init - name: integration-sharing-v1 - image: ghcr.io/nextcloud/continuous-integration-integration-php7.3:integration-php7.3-2 + image: ghcr.io/nextcloud/continuous-integration-integration-php7.3:latest commands: - bash tests/drone-run-integration-tests.sh || exit 0 - ./occ maintenance:install --admin-pass=admin --data-dir=/dev/shm/nc_int @@ -1349,7 +1349,7 @@ steps: commands: - git submodule update --init - name: integration-sharing-v1-part2 - image: ghcr.io/nextcloud/continuous-integration-integration-php7.3:integration-php7.3-2 + image: ghcr.io/nextcloud/continuous-integration-integration-php7.3:latest commands: - bash tests/drone-run-integration-tests.sh || exit 0 - ./occ maintenance:install --admin-pass=admin --data-dir=/dev/shm/nc_int @@ -1374,7 +1374,7 @@ steps: commands: - git submodule update --init - name: integration-sharing-v1-part3 - image: ghcr.io/nextcloud/continuous-integration-integration-php7.3:integration-php7.3-2 + image: ghcr.io/nextcloud/continuous-integration-integration-php7.3:latest commands: - bash tests/drone-run-integration-tests.sh || exit 0 - ./occ maintenance:install --admin-pass=admin --data-dir=/dev/shm/nc_int @@ -1405,7 +1405,7 @@ steps: # build them. - git clone --depth 1 https://github.com/nextcloud/spreed apps/spreed - name: integration-sharing-v1-video-verification - image: ghcr.io/nextcloud/continuous-integration-integration-php7.3:integration-php7.3-2 + image: ghcr.io/nextcloud/continuous-integration-integration-php7.3:latest commands: - bash tests/drone-run-integration-tests.sh || exit 0 - ./occ maintenance:install --admin-pass=admin --data-dir=/dev/shm/nc_int @@ -1430,7 +1430,7 @@ steps: commands: - git submodule update --init - name: integration-setup-features - image: ghcr.io/nextcloud/continuous-integration-integration-php7.3:integration-php7.3-2 + image: ghcr.io/nextcloud/continuous-integration-integration-php7.3:latest commands: - bash tests/drone-run-integration-tests.sh || exit 0 - cd build/integration @@ -1454,7 +1454,7 @@ steps: commands: - git submodule update --init - name: integration-filesdrop-features - image: ghcr.io/nextcloud/continuous-integration-integration-php7.3:integration-php7.3-2 + image: ghcr.io/nextcloud/continuous-integration-integration-php7.3:latest commands: - bash tests/drone-run-integration-tests.sh || exit 0 - ./occ maintenance:install --admin-pass=admin --data-dir=/dev/shm/nc_int @@ -1479,7 +1479,7 @@ steps: commands: - git submodule update --init - name: integration-transfer-ownership-features - image: ghcr.io/nextcloud/continuous-integration-integration-php7.3:integration-php7.3-2 + image: ghcr.io/nextcloud/continuous-integration-integration-php7.3:latest commands: - bash tests/drone-run-integration-tests.sh || exit 0 - ./occ maintenance:install --admin-pass=admin --data-dir=/dev/shm/nc_int @@ -1504,7 +1504,7 @@ steps: commands: - git submodule update --init - name: integration-ldap-features - image: ghcr.io/nextcloud/continuous-integration-integration-php7.3:integration-php7.3-2 + image: ghcr.io/nextcloud/continuous-integration-integration-php7.3:latest commands: - bash tests/drone-run-integration-tests.sh || exit 0 - ./occ maintenance:install --admin-pass=admin --data-dir=/dev/shm/nc_int @@ -1529,7 +1529,7 @@ steps: commands: - git submodule update --init - name: integration-ldap-openldap-features - image: ghcr.io/nextcloud/continuous-integration-integration-php7.3:integration-php7.3-2 + image: ghcr.io/nextcloud/continuous-integration-integration-php7.3:latest commands: - bash tests/drone-run-integration-tests.sh || exit 0 - ./occ maintenance:install --admin-pass=admin --data-dir=/dev/shm/nc_int @@ -1570,7 +1570,7 @@ steps: commands: - git submodule update --init - name: integration-ldap-openldap-uid-features - image: ghcr.io/nextcloud/continuous-integration-integration-php7.3:integration-php7.3-2 + image: ghcr.io/nextcloud/continuous-integration-integration-php7.3:latest commands: - bash tests/drone-run-integration-tests.sh || exit 0 - ./occ maintenance:install --admin-pass=admin --data-dir=/dev/shm/nc_int @@ -1612,7 +1612,7 @@ steps: commands: - git submodule update --init - name: integration-ldap-openldap-numerical-id-features - image: ghcr.io/nextcloud/continuous-integration-integration-php7.3:integration-php7.3-2 + image: ghcr.io/nextcloud/continuous-integration-integration-php7.3:latest commands: - bash tests/drone-run-integration-tests.sh || exit 0 - ./occ maintenance:install --admin-pass=admin --data-dir=/dev/shm/nc_int @@ -1653,7 +1653,7 @@ steps: commands: - git submodule update --init - name: integration-trashbin - image: ghcr.io/nextcloud/continuous-integration-integration-php7.3:integration-php7.3-2 + image: ghcr.io/nextcloud/continuous-integration-integration-php7.3:latest commands: - bash tests/drone-run-integration-tests.sh || exit 0 - ./occ maintenance:install --admin-pass=admin --data-dir=/dev/shm/nc_int @@ -1678,7 +1678,7 @@ steps: commands: - git submodule update --init - name: integration-remote-api - image: ghcr.io/nextcloud/continuous-integration-integration-php7.3:integration-php7.3-2 + image: ghcr.io/nextcloud/continuous-integration-integration-php7.3:latest commands: - bash tests/drone-run-integration-tests.sh || exit 0 - ./occ maintenance:install --admin-pass=admin --data-dir=/dev/shm/nc_int @@ -1703,7 +1703,7 @@ steps: commands: - git submodule update --init - name: integration-download - image: ghcr.io/nextcloud/continuous-integration-integration-php7.3:integration-php7.3-2 + image: ghcr.io/nextcloud/continuous-integration-integration-php7.3:latest commands: - bash tests/drone-run-integration-tests.sh || exit 0 - ./occ maintenance:install --admin-pass=admin --data-dir=/dev/shm/nc_int diff --git a/build/psalm-baseline.xml b/build/psalm-baseline.xml index c98f37f8290..dbea3557c13 100644 --- a/build/psalm-baseline.xml +++ b/build/psalm-baseline.xml @@ -4403,10 +4403,6 @@ </ForbiddenCode> </file> <file src="lib/private/RedisFactory.php"> - <InvalidPropertyAssignmentValue occurrences="2"> - <code>new \RedisCluster(null, $config['seeds'], $timeout, $readTimeout)</code> - <code>new \RedisCluster(null, $config['seeds'], $timeout, $readTimeout, false, $config['password'])</code> - </InvalidPropertyAssignmentValue> <InvalidScalarArgument occurrences="1"> <code>\RedisCluster::OPT_SLAVE_FAILOVER</code> </InvalidScalarArgument> diff --git a/build/stubs/redis.php b/build/stubs/redis.php index 0a37c08214d..e4872b81556 100644 --- a/build/stubs/redis.php +++ b/build/stubs/redis.php @@ -1,5 +1,7 @@ <?php +use JetBrains\PhpStorm\Deprecated; + /** * Helper autocomplete for php redis extension * @@ -39,6 +41,16 @@ class Redis const SCAN_RETRY = 1; /** + * @since 5.3.0 + */ + const SCAN_PREFIX = 2; + + /** + * @since 5.3.0 + */ + const SCAN_NOPREFIX = 3; + + /** * Serializers */ const SERIALIZER_NONE = 0; @@ -53,6 +65,7 @@ class Redis const COMPRESSION_NONE = 0; const COMPRESSION_LZF = 1; const COMPRESSION_ZSTD = 2; + const COMPRESSION_LZ4 = 3; /** * Compression ZSTD levels @@ -91,12 +104,13 @@ class Redis /** * Connects to a Redis instance. * - * @param string $host can be a host, or the path to a unix domain socket - * @param int $port optional - * @param float $timeout value in seconds (optional, default is 0.0 meaning unlimited) - * @param null $reserved should be null if $retryInterval is specified - * @param int $retryInterval retry interval in milliseconds. - * @param float $readTimeout value in seconds (optional, default is 0 meaning unlimited) + * @param string $host can be a host, or the path to a unix domain socket + * @param int $port optional + * @param float $timeout value in seconds (optional, default is 0.0 meaning unlimited) + * @param null $reserved should be null if $retryInterval is specified + * @param int $retryInterval retry interval in milliseconds. + * @param float $readTimeout value in seconds (optional, default is 0 meaning unlimited) + * @param array $connectionParameters extra config to send to redis * * @return bool TRUE on success, FALSE on error * @@ -114,7 +128,8 @@ class Redis $timeout = 0.0, $reserved = null, $retryInterval = 0, - $readTimeout = 0.0 + $readTimeout = 0.0, + $connectionParameters = [] ) { } @@ -129,10 +144,8 @@ class Redis * @param float $readTimeout value in seconds (optional, default is 0 meaning unlimited) * * @return bool TRUE on success, FALSE on error - * - * @see connect() - * @deprecated use Redis::connect() */ + #[Deprecated(replacement: '%class%->connect(%parametersList%)')] public function open( $host, $port = 6379, @@ -155,7 +168,7 @@ class Redis /** * Retrieve our host or unix socket that we're connected to * - * @return string|bool The host or unix socket we're connected to or FALSE if we're not connected + * @return string|false The host or unix socket we're connected to or FALSE if we're not connected */ public function getHost() { @@ -164,7 +177,7 @@ class Redis /** * Get the port we're connected to * - * @return int|bool Returns the port we're connected to or FALSE if we're not connected + * @return int|false Returns the port we're connected to or FALSE if we're not connected */ public function getPort() { @@ -183,7 +196,7 @@ class Redis /** * Get the (write) timeout in use for phpredis * - * @return float|bool The timeout (DOUBLE) specified in our connect call or FALSE if we're not connected + * @return float|false The timeout (DOUBLE) specified in our connect call or FALSE if we're not connected */ public function getTimeout() { @@ -279,10 +292,8 @@ class Redis * @param float $readTimeout * * @return bool - * - * @deprecated use Redis::pconnect() - * @see pconnect() */ + #[Deprecated(replacement: '%class%->pconnect(%parametersList%)')] public function popen( $host, $port = 6379, @@ -378,14 +389,14 @@ class Redis /** * Check the current connection status * - * @param string $message + * @param string $message [optional] * * @return bool|string TRUE if the command is successful or returns message * Throws a RedisException object on connectivity error, as described above. * @throws RedisException * @link https://redis.io/commands/ping */ - public function ping($message) + public function ping($message = null) { } @@ -407,7 +418,7 @@ class Redis * * @param string $key * - * @return string|mixed|bool If key didn't exist, FALSE is returned. + * @return string|mixed|false If key didn't exist, FALSE is returned. * Otherwise, the value related to this key is returned * * @link https://redis.io/commands/get @@ -545,15 +556,13 @@ class Redis } /** - * @see del() - * @deprecated use Redis::del() - * * @param string|string[] $key1 * @param string $key2 * @param string $key3 * * @return int Number of keys deleted */ + #[Deprecated(replacement: "%class%->del(%parametersList%)")] public function delete($key1, $key2 = null, $key3 = null) { } @@ -592,7 +601,7 @@ class Redis * a Redis::PIPELINE block is simply transmitted faster to the server, but without any guarantee of atomicity. * discard cancels a transaction. * - * @return Redis returns the Redis instance and enters multi-mode. + * @return static returns the Redis instance and enters multi-mode. * Once in multi-mode, all subsequent method calls return the same object until exec() is called. * * @link https://redis.io/commands/multi @@ -958,9 +967,9 @@ class Redis * If the key exists and is not a list, FALSE is returned. * * @param string $key - * @param string|mixed $value1... Variadic list of values to push in key, if dont used serialized, used string + * @param string|mixed ...$value1 Variadic list of values to push in key, if dont used serialized, used string * - * @return int|bool The new length of the list in case of success, FALSE in case of Failure + * @return int|false The new length of the list in case of success, FALSE in case of Failure * * @link https://redis.io/commands/lpush * @example @@ -986,9 +995,9 @@ class Redis * If the key exists and is not a list, FALSE is returned. * * @param string $key - * @param string|mixed $value1... Variadic list of values to push in key, if dont used serialized, used string + * @param string|mixed ...$value1 Variadic list of values to push in key, if dont used serialized, used string * - * @return int|bool The new length of the list in case of success, FALSE in case of Failure + * @return int|false The new length of the list in case of success, FALSE in case of Failure * * @link https://redis.io/commands/rpush * @example @@ -1014,7 +1023,7 @@ class Redis * @param string $key * @param string|mixed $value String, value to push in key * - * @return int|bool The new length of the list in case of success, FALSE in case of Failure. + * @return int|false The new length of the list in case of success, FALSE in case of Failure. * * @link https://redis.io/commands/lpushx * @example @@ -1037,7 +1046,7 @@ class Redis * @param string $key * @param string|mixed $value String, value to push in key * - * @return int|bool The new length of the list in case of success, FALSE in case of Failure. + * @return int|false The new length of the list in case of success, FALSE in case of Failure. * * @link https://redis.io/commands/rpushx * @example @@ -1208,14 +1217,13 @@ class Redis } /** - * @see lLen() * @link https://redis.io/commands/llen - * @deprecated use Redis::lLen() * * @param string $key * * @return int The size of the list identified by Key exists */ + #[Deprecated(replacement: '%class%->lLen(%parametersList%)')] public function lSize($key) { } @@ -1248,14 +1256,13 @@ class Redis } /** - * @see lIndex() * @link https://redis.io/commands/lindex - * @deprecated use Redis::lIndex() * * @param string $key * @param int $index * @return mixed|bool the element at this index */ + #[Deprecated(replacement: '%class%->lIndex(%parametersList%)')] public function lGet($key, $index) { } @@ -1310,15 +1317,14 @@ class Redis } /** - * @see lRange() * @link https://redis.io/commands/lrange - * @deprecated use Redis::lRange() * * @param string $key * @param int $start * @param int $end * @return array */ + #[Deprecated(replacement: '%class%->lRange(%parametersList%)')] public function lGetRange($key, $start, $end) { } @@ -1330,7 +1336,7 @@ class Redis * @param int $start * @param int $stop * - * @return array|bool Bool return FALSE if the key identify a non-list value + * @return array|false Bool return FALSE if the key identify a non-list value * * @link https://redis.io/commands/ltrim * @example @@ -1348,14 +1354,13 @@ class Redis } /** - * @see lTrim() * @link https://redis.io/commands/ltrim - * @deprecated use Redis::lTrim() * * @param string $key * @param int $start * @param int $stop */ + #[Deprecated(replacement: '%class%->lTrim(%parametersList%)')] public function listTrim($key, $start, $stop) { } @@ -1391,14 +1396,13 @@ class Redis } /** - * @see lRem * @link https://redis.io/commands/lremove - * @deprecated use Redis::lRem() * * @param string $key * @param string $value * @param int $count */ + #[Deprecated(replacement: '%class%->lRem(%parametersList%)')] public function lRemove($key, $value, $count) { } @@ -1483,13 +1487,12 @@ class Redis } /** - * @see sRem() * @link https://redis.io/commands/srem - * @deprecated use Redis::sRem() * * @param string $key * @param string|mixed ...$member1 */ + #[Deprecated(replacement: '%class%->sRem(%parametersList%)')] public function sRemove($key, ...$member1) { } @@ -1544,13 +1547,12 @@ class Redis } /** - * @see sIsMember() * @link https://redis.io/commands/sismember - * @deprecated use Redis::sIsMember() * * @param string $key * @param string|mixed $value */ + #[Deprecated(replacement: '%class%->sIsMember(%parametersList%)')] public function sContains($key, $value) { } @@ -1649,7 +1651,7 @@ class Redis * @param string $key1 keys identifying the different sets on which we will apply the intersection. * @param string ...$otherKeys variadic list of keys * - * @return array contain the result of the intersection between those keys + * @return array|false contain the result of the intersection between those keys * If the intersection between the different sets is empty, the return value will be empty array. * * @link https://redis.io/commands/sinter @@ -1687,7 +1689,7 @@ class Redis * @param string $key1 keys identifying the different sets on which we will apply the intersection. * @param string ...$otherKeys variadic list of keys * - * @return int|bool The cardinality of the resulting set, or FALSE in case of a missing key + * @return int|false The cardinality of the resulting set, or FALSE in case of a missing key * * @link https://redis.io/commands/sinterstore * @example @@ -1839,7 +1841,7 @@ class Redis * @param string $key1 first key for diff * @param string ...$otherKeys variadic list of keys corresponding to sets in redis * - * @return int|bool The cardinality of the resulting set, or FALSE in case of a missing key + * @return int|false The cardinality of the resulting set, or FALSE in case of a missing key * * @link https://redis.io/commands/sdiffstore * @example @@ -1903,13 +1905,12 @@ class Redis } /** - * @see sMembers() * @link https://redis.io/commands/smembers - * @deprecated use Redis::sMembers() * * @param string $key * @return array An array of elements, the contents of the set */ + #[Deprecated(replacement: '%class%->sMembers(%parametersList%)')] public function sGetMembers($key) { } @@ -1918,11 +1919,11 @@ class Redis * Scan a set for members * * @param string $key The set to search. - * @param int $iterator LONG (reference) to the iterator as we go. + * @param int &$iterator LONG (reference) to the iterator as we go. * @param string $pattern String, optional pattern to match against. * @param int $count How many members to return at a time (Redis might return a different amount) * - * @return array|bool PHPRedis will return an array of keys or FALSE when we're done iterating + * @return array|false PHPRedis will return an array of keys or FALSE when we're done iterating * * @link https://redis.io/commands/sscan * @example @@ -2040,13 +2041,12 @@ class Redis } /** - * @see rename() * @link https://redis.io/commands/rename - * @deprecated use Redis::rename() * * @param string $srcKey * @param string $dstKey */ + #[Deprecated(replacement: '%class%->rename(%parametersList%)')] public function renameKey($srcKey, $dstKey) { } @@ -2118,14 +2118,13 @@ class Redis } /** - * @see expire() * @link https://redis.io/commands/expire - * @deprecated use Redis::expire() * * @param string $key * @param int $ttl * @return bool */ + #[Deprecated(replacement: '%class%->expire(%parametersList%)')] public function setTimeout($key, $ttl) { } @@ -2192,12 +2191,10 @@ class Redis } /** - * @see keys() - * @deprecated use Redis::keys() - * * @param string $pattern * @link https://redis.io/commands/keys */ + #[Deprecated(replacement: '%class%->keys(%parametersList%)')] public function getKeys($pattern) { } @@ -2222,7 +2219,7 @@ class Redis * Authenticate the connection using a password. * Warning: The password is sent in plain-text over the network. * - * @param string $password + * @param string|string[] $password * * @return bool TRUE if the connection is authenticated, FALSE otherwise * @@ -2309,7 +2306,7 @@ class Redis * @param string $string * @param string $key * - * @return string|int|bool for "encoding", int for "refcount" and "idletime", FALSE if the key doesn't exist. + * @return string|int|false for "encoding", int for "refcount" and "idletime", FALSE if the key doesn't exist. * * @link https://redis.io/commands/object * @example @@ -2445,11 +2442,11 @@ class Redis /** * Return a substring of a larger string * - * @deprecated * @param string $key * @param int $start * @param int $end */ + #[Deprecated] public function substr($key, $start, $end) { } @@ -2725,7 +2722,7 @@ class Redis * - vm_enabled * - role * - * @return string + * @return array * * @link https://redis.io/commands/info * @example @@ -2843,7 +2840,6 @@ class Redis * * @return array Array containing the values related to keys in argument * - * @deprecated use Redis::mGet() * @example * <pre> * $redis->set('key1', 'value1'); @@ -2853,6 +2849,7 @@ class Redis * $redis->getMultiple(array('key0', 'key1', 'key5')); // array(`FALSE`, 'value2', `FALSE`); * </pre> */ + #[Deprecated(replacement: '%class%->mGet(%parametersList%)')] public function getMultiple(array $keys) { } @@ -2907,7 +2904,7 @@ class Redis * @param string $srcKey * @param string $dstKey * - * @return string|mixed|bool The element that was moved in case of success, FALSE in case of failure. + * @return string|mixed|false The element that was moved in case of success, FALSE in case of failure. * * @link https://redis.io/commands/rpoplpush * @example @@ -2977,7 +2974,6 @@ class Redis * @link https://redis.io/commands/zadd * @example * <pre> - * <pre> * $redis->zAdd('z', 1, 'v1', 2, 'v2', 3, 'v3', 4, 'v4' ); // int(2) * $redis->zRem('z', 'v2', 'v3'); // int(2) * $redis->zAdd('z', ['NX'], 5, 'v5'); // int(1) @@ -3002,7 +2998,6 @@ class Redis * // ["v5"]=> float(5) * // ["v6"]=> float(8) * </pre> - * </pre> */ public function zAdd($key, $options, $score1, $value1 = null, $score2 = null, $value2 = null, $scoreN = null, $valueN = null) { @@ -3065,9 +3060,7 @@ class Redis } /** - * @see zRem() * @link https://redis.io/commands/zrem - * @deprecated use Redis::zRem() * * @param string $key * @param string|mixed $member1 @@ -3075,6 +3068,7 @@ class Redis * * @return int Number of deleted values */ + #[Deprecated(replacement: '%class%->zRem(%parametersList%)')] public function zDelete($key, $member1, ...$otherMembers) { } @@ -3167,7 +3161,7 @@ class Redis * @param int $offset Optional argument if you wish to start somewhere other than the first element. * @param int $limit Optional argument if you wish to limit the number of elements returned. * - * @return array|bool Array containing the values in the specified range. + * @return array|false Array containing the values in the specified range. * * @link https://redis.io/commands/zrangebylex * @example @@ -3248,13 +3242,11 @@ class Redis } /** - * @see zRemRangeByScore() - * @deprecated use Redis::zRemRangeByScore() - * * @param string $key * @param float $start * @param float $end */ + #[Deprecated(replacement: '%class%->zRemRangeByScore(%parametersList%)')] public function zDeleteRangeByScore($key, $start, $end) { } @@ -3283,14 +3275,13 @@ class Redis } /** - * @see zRemRangeByRank() * @link https://redis.io/commands/zremrangebyscore - * @deprecated use Redis::zRemRangeByRank() * * @param string $key * @param int $start * @param int $end */ + #[Deprecated(replacement: '%class%->zRemRangeByRank(%parametersList%)')] public function zDeleteRangeByRank($key, $start, $end) { } @@ -3316,12 +3307,10 @@ class Redis } /** - * @see zCard() - * @deprecated use Redis::zCard() - * * @param string $key * @return int */ + #[Deprecated(replacement: '%class%->zCard(%parametersList%)')] public function zSize($key) { } @@ -3352,7 +3341,7 @@ class Redis * @param string $key * @param string|mixed $member * - * @return int|bool the item's score, or false if key or member is not exists + * @return int|false the item's score, or false if key or member is not exists * * @link https://redis.io/commands/zrank * @example @@ -3375,7 +3364,7 @@ class Redis * @param string $key * @param string|mixed $member * - * @return int|bool the item's score, false - if key or member is not exists + * @return int|false the item's score, false - if key or member is not exists * * @link https://redis.io/commands/zrevrank */ @@ -3415,7 +3404,7 @@ class Redis * * @param string $output * @param array $zSetKeys - * @param array $weights + * @param null|array $weights * @param string $aggregateFunction Either "SUM", "MIN", or "MAX": defines the behaviour to use on * duplicate entries during the zUnionStore * @@ -3444,19 +3433,17 @@ class Redis * $redis->zUnionStore('ko3', array('k1', 'k2'), array(5, 1)); // 4, 'ko3' => array('val0', 'val2', 'val3', 'val1') * </pre> */ - public function zUnionStore($output, $zSetKeys, array $weights = null, $aggregateFunction = 'SUM') + public function zUnionStore($output, $zSetKeys, ?array $weights = null, $aggregateFunction = 'SUM') { } /** - * @see zUnionStore - * @deprecated use Redis::zUnionStore() - * * @param string $Output * @param array $ZSetKeys * @param array|null $Weights * @param string $aggregateFunction */ + #[Deprecated(replacement: '%class%->zUnionStore(%parametersList%)')] public function zUnion($Output, $ZSetKeys, array $Weights = null, $aggregateFunction = 'SUM') { } @@ -3471,7 +3458,7 @@ class Redis * * @param string $output * @param array $zSetKeys - * @param array $weights + * @param null|array $weights * @param string $aggregateFunction Either "SUM", "MIN", or "MAX": * defines the behaviour to use on duplicate entries during the zInterStore. * @@ -3509,14 +3496,12 @@ class Redis } /** - * @see zInterStore - * @deprecated use Redis::zInterStore() - * * @param $Output * @param $ZSetKeys * @param array|null $Weights * @param string $aggregateFunction */ + #[Deprecated(replacement: '%class%->zInterStore(%parametersList%)')] public function zInter($Output, $ZSetKeys, array $Weights = null, $aggregateFunction = 'SUM') { } @@ -3525,11 +3510,11 @@ class Redis * Scan a sorted set for members, with optional pattern and count * * @param string $key String, the set to scan. - * @param int $iterator Long (reference), initialized to NULL. + * @param int &$iterator Long (reference), initialized to NULL. * @param string $pattern String (optional), the pattern to match. * @param int $count How many keys to return per iteration (Redis might return a different number). * - * @return array|bool PHPRedis will return matching keys from Redis, or FALSE when iteration is complete + * @return array|false PHPRedis will return matching keys from Redis, or FALSE when iteration is complete * * @link https://redis.io/commands/zscan * @example @@ -3691,7 +3676,7 @@ class Redis * @param string $key * @param string $hashKey * - * @return string The value, if the command executed successfully BOOL FALSE in case of failure + * @return string|false The value, if the command executed successfully BOOL FALSE in case of failure * * @link https://redis.io/commands/hget */ @@ -3704,7 +3689,7 @@ class Redis * * @param string $key * - * @return int|bool the number of items in a hash, FALSE if the key doesn't exist or isn't a hash + * @return int|false the number of items in a hash, FALSE if the key doesn't exist or isn't a hash * * @link https://redis.io/commands/hlen * @example @@ -3955,7 +3940,7 @@ class Redis } /** - * Retirieve the values associated to the specified fields in the hash. + * Retrieve the values associated to the specified fields in the hash. * * @param string $key * @param array $hashKeys @@ -3980,7 +3965,7 @@ class Redis * Scan a HASH value for members, with an optional pattern and count. * * @param string $key - * @param int $iterator + * @param int &$iterator * @param string $pattern Optional pattern to match against. * @param int $count How many keys to return in a go (only a sugestion to Redis). * @@ -4029,7 +4014,7 @@ class Redis * @return int The number of elements added to the geospatial key * * @link https://redis.io/commands/geoadd - * @since >=3.2 + * @since >= 3.2 * * @example * <pre> @@ -4056,7 +4041,7 @@ class Redis * @return array One or more Redis Geohash encoded strings * * @link https://redis.io/commands/geohash - * @since >=3.2 + * @since >= 3.2 * * @example * <pre> @@ -4083,7 +4068,7 @@ class Redis * @return array One or more longitude/latitude positions * * @link https://redis.io/commands/geopos - * @since >=3.2 + * @since >= 3.2 * * @example * <pre> @@ -4125,7 +4110,7 @@ class Redis * @return float The distance between the two passed members in the units requested (meters by default) * * @link https://redis.io/commands/geodist - * @since >=3.2 + * @since >= 3.2 * * @example * <pre> @@ -4355,14 +4340,12 @@ class Redis } /** - * @see eval() - * @deprecated use Redis::eval() - * * @param string $script * @param array $args * @param int $numKeys * @return mixed @see eval() */ + #[Deprecated(replacement: '%class%->eval(%parametersList%)')] public function evaluate($script, $args = array(), $numKeys = 0) { } @@ -4392,13 +4375,11 @@ class Redis } /** - * @see evalSha() - * @deprecated use Redis::evalSha() - * * @param string $scriptSha * @param array $args * @param int $numKeys */ + #[Deprecated(replacement: '%class%->evalSha(%parametersList%)')] public function evaluateSha($scriptSha, $args = array(), $numKeys = 0) { } @@ -4568,7 +4549,7 @@ class Redis * The data that comes out of DUMP is a binary representation of the key as Redis stores it. * @param string $key * - * @return string|bool The Redis encoded value of the key, or FALSE if the key doesn't exist + * @return string|false The Redis encoded value of the key, or FALSE if the key doesn't exist * * @link https://redis.io/commands/dump * @example @@ -4648,11 +4629,11 @@ class Redis /** * Scan the keyspace for keys * - * @param int $iterator Iterator, initialized to NULL. + * @param int &$iterator Iterator, initialized to NULL. * @param string $pattern Pattern to match. * @param int $count Count of keys per iteration (only a suggestion to Redis). * - * @return array|bool This function will return an array of keys or FALSE if there are no more keys. + * @return array|false This function will return an array of keys or FALSE if there are no more keys. * * @link https://redis.io/commands/scan * @example @@ -4699,6 +4680,7 @@ class Redis * $redis->pfAdd('key2', array('elem3', 'elem2')); * $redis->pfCount('key1'); // int(2) * $redis->pfCount(array('key1', 'key2')); // int(3) + * </pre> */ public function pfCount($key) { @@ -4720,6 +4702,7 @@ class Redis * $redis->pfAdd('key2', array('elem3', 'elem2')); * $redis->pfMerge('key3', array('key1', 'key2')); * $redis->pfCount('key3'); // int(3) + * </pre> */ public function pfMerge($destKey, array $sourceKeys) { @@ -5078,12 +5061,12 @@ class RedisArray /** * Constructor * - * @param string|array $hosts Name of the redis array from redis.ini or array of hosts to construct the array with - * @param array $opts Array of options + * @param string|string[] $hosts Name of the redis array from redis.ini or array of hosts to construct the array with + * @param null|array $opts Array of options * * @link https://github.com/nicolasff/phpredis/blob/master/arrays.markdown */ - public function __construct($hosts, array $opts = null) + public function __construct($hosts, ?array $opts = null) { } @@ -5111,6 +5094,15 @@ class RedisArray } /** + * @param string $host The host you want to retrieve the instance for + * + * @return Redis a redis instance connected to a specific node + */ + public function _instance($host) + { + } + + /** * Use this function when a new node is added and keys need to be rehashed. */ public function _rehash() diff --git a/build/stubs/redis_cluster.php b/build/stubs/redis_cluster.php index 5e14570f3bf..fdabba76553 100644 --- a/build/stubs/redis_cluster.php +++ b/build/stubs/redis_cluster.php @@ -38,6 +38,16 @@ class RedisCluster { const SCAN_RETRY = 1; /** + * @since 5.3.0 + */ + const SCAN_PREFIX = 2; + + /** + * @since 5.3.0 + */ + const SCAN_NOPREFIX = 3; + + /** * Serializers */ const SERIALIZER_NONE = 0; @@ -66,12 +76,13 @@ class RedisCluster { /** * Creates a Redis Cluster client * - * @param string|null $name - * @param array $seeds - * @param float $timeout - * @param float $readTimeout - * @param bool $persistent - * @param string|null $auth + * @param string|null $name + * @param array $seeds + * @param float $timeout + * @param float $readTimeout + * @param bool $persistent + * @param string|string[]|null $auth + * @param array $connectionParameters extra config to send to redis * @throws RedisClusterException * * @example @@ -94,7 +105,7 @@ class RedisCluster { * $redisClusterDev = new RedisCluster('test'); * </pre> */ - public function __construct($name, $seeds, $timeout = null, $readTimeout = null, $persistent = false, $auth = null) { } + public function __construct($name, $seeds, $timeout = null, $readTimeout = null, $persistent = false, $auth = null, $connectionParameters = []) { } /** * Disconnects from the Redis instance, except when pconnect is used. @@ -1565,7 +1576,7 @@ class RedisCluster { public function hSetNx($key, $hashKey, $value) { } /** - * Retirieve the values associated to the specified fields in the hash. + * Retrieve the values associated to the specified fields in the hash. * * @param string $key * @param array $hashKeys @@ -2162,6 +2173,7 @@ class RedisCluster { * $redisCluster->pfAdd('key2', array('elem3', 'elem2')); * $redisCluster->pfCount('key1'); // int(2) * $redisCluster->pfCount(array('key1', 'key2')); // int(3) + * </pre> */ public function pfCount($key) { } @@ -2192,6 +2204,7 @@ class RedisCluster { * $redisCluster->pfAdd('key2', array('elem3', 'elem2')); * $redisCluster->pfMerge('key3', array('key1', 'key2')); * $redisCluster->pfCount('key3'); // int(3) + * </pre> */ public function pfMerge($destKey, array $sourceKeys) { } @@ -2439,7 +2452,7 @@ class RedisCluster { * * @param string $Output * @param array $ZSetKeys - * @param array $Weights + * @param null|array $Weights * @param string $aggregateFunction Either "SUM", "MIN", or "MAX": defines the behaviour to use on * duplicate entries during the zUnion. * @@ -2467,14 +2480,14 @@ class RedisCluster { * $redisCluster->zUnionStore('ko3', array('k1', 'k2'), array(5, 1)); // 4, 'ko3' => array('val0', 'val2', 'val3','val1') * </pre> */ - public function zUnionStore($Output, $ZSetKeys, array $Weights = null, $aggregateFunction = 'SUM') { } + public function zUnionStore($Output, $ZSetKeys, ?array $Weights = null, $aggregateFunction = 'SUM') { } /** * Intersect multiple sorted sets and store the resulting sorted set in a new key * * @param string $Output * @param array $ZSetKeys - * @param array $Weights + * @param null|array $Weights * @param string $aggregateFunction Either "SUM", "MIN", or "MAX": * defines the behaviour to use on duplicate entries during the zInterStore. * @@ -2703,7 +2716,7 @@ class RedisCluster { * Scan a set for members. * * @param string $key The set to search. - * @param int $iterator LONG (reference) to the iterator as we go. + * @param int &$iterator LONG (reference) to the iterator as we go. * @param null $pattern String, optional pattern to match against. * @param int $count How many members to return at a time (Redis might return a different amount). * @@ -2725,7 +2738,7 @@ class RedisCluster { * Scan a sorted set for members, with optional pattern and count. * * @param string $key String, the set to scan. - * @param int $iterator Long (reference), initialized to NULL. + * @param int &$iterator Long (reference), initialized to NULL. * @param string $pattern String (optional), the pattern to match. * @param int $count How many keys to return per iteration (Redis might return a different number). * @@ -2747,7 +2760,7 @@ class RedisCluster { * Scan a HASH value for members, with an optional pattern and count. * * @param string $key - * @param int $iterator + * @param int &$iterator * @param string $pattern Optional pattern to match against. * @param int $count How many keys to return in a go (only a sugestion to Redis). * @@ -3425,10 +3438,10 @@ class RedisCluster { /** * Returns members of a geospatial index as standard geohash strings * - * @param $key string - * @param $member1 string - * @param $member2 string - * @param $memberN string + * @param string $key + * @param string $member1 + * @param string $member2 + * @param string $memberN * * @example * <pre> @@ -3442,11 +3455,10 @@ class RedisCluster { /** * Returns longitude and latitude of members of a geospatial index * - * @param $key string - * @param $member1 string - * @param $member2 string - * @param $memberN string - * + * @param string $key + * @param string $member1 + * @param string $member2 + * @param string $memberN * @example * <pre> * $redisCluster->geoAdd('Sicily', 15.087269, 37.502669, "Catania"); // int(1) diff --git a/config/config.sample.php b/config/config.sample.php index e21d18e6eaa..4fcfc5fb6fd 100644 --- a/config/config.sample.php +++ b/config/config.sample.php @@ -1221,13 +1221,25 @@ $CONFIG = [ * For enhanced security it is recommended to configure Redis * to require a password. See http://redis.io/topics/security * for more information. + * + * We also support redis SSL/TLS encryption as of version 6. + * See https://redis.io/topics/encryption for more information. */ 'redis' => [ 'host' => 'localhost', // can also be a unix domain socket: '/tmp/redis.sock' 'port' => 6379, 'timeout' => 0.0, + 'read_timeout' => 0.0, + 'user' => '', // Optional, if not defined no password will be used. 'password' => '', // Optional, if not defined no password will be used. 'dbindex' => 0, // Optional, if undefined SELECT will not run and will use Redis Server's default DB Index. + // If redis in-transit encryption is enabled, provide certificates + // SSL context https://www.php.net/manual/en/context.ssl.php + 'ssl_context' => [ + 'local_cert' => '/certs/redis.crt', + 'local_pk' => '/certs/redis.key', + 'cafile' => '/certs/ca.crt' + ] ], /** @@ -1263,7 +1275,15 @@ $CONFIG = [ 'timeout' => 0.0, 'read_timeout' => 0.0, 'failover_mode' => \RedisCluster::FAILOVER_ERROR, + 'user' => '', // Optional, if not defined no password will be used. 'password' => '', // Optional, if not defined no password will be used. + // If redis in-transit encryption is enabled, provide certificates + // SSL context https://www.php.net/manual/en/context.ssl.php + 'ssl_context' => [ + 'local_cert' => '/certs/redis.crt', + 'local_pk' => '/certs/redis.key', + 'cafile' => '/certs/ca.crt' + ] ], diff --git a/lib/private/RedisFactory.php b/lib/private/RedisFactory.php index 61168c3dd86..7609a75d52d 100644 --- a/lib/private/RedisFactory.php +++ b/lib/private/RedisFactory.php @@ -27,7 +27,10 @@ namespace OC; class RedisFactory { - /** @var \Redis */ + public const REDIS_MINIMAL_VERSION = '2.2.5'; + public const REDIS_EXTRA_PARAMETERS_MINIMAL_VERSION = '5.3.0'; + + /** @var \Redis|\RedisCluster */ private $instance; /** @var SystemConfig */ @@ -43,25 +46,51 @@ class RedisFactory { } private function create() { - if ($config = $this->config->getValue('redis.cluster', [])) { - if (!class_exists('RedisCluster')) { - throw new \Exception('Redis Cluster support is not available'); - } - // cluster config - if (isset($config['timeout'])) { - $timeout = $config['timeout']; - } else { - $timeout = null; - } - if (isset($config['read_timeout'])) { - $readTimeout = $config['read_timeout']; + $isCluster = in_array('redis.cluster', $this->config->getKeys()); + $config = $isCluster + ? $this->config->getValue('redis.cluster', []) + : $this->config->getValue('redis', []); + + if (empty($config)) { + throw new \Exception('Redis config is empty'); + } + + if ($isCluster && !class_exists('RedisCluster')) { + throw new \Exception('Redis Cluster support is not available'); + } + + if (isset($config['timeout'])) { + $timeout = $config['timeout']; + } else { + $timeout = 0.0; + } + + if (isset($config['read_timeout'])) { + $readTimeout = $config['read_timeout']; + } else { + $readTimeout = 0.0; + } + + $auth = null; + if (isset($config['password']) && $config['password'] !== '') { + if (isset($config['user']) && $config['user'] !== '') { + $auth = [$config['user'], $config['password']]; } else { - $readTimeout = null; + $auth = $config['password']; } - if (isset($config['password']) && $config['password'] !== '') { - $this->instance = new \RedisCluster(null, $config['seeds'], $timeout, $readTimeout, false, $config['password']); + } + + // # TLS support + // # https://github.com/phpredis/phpredis/issues/1600 + $connectionParameters = $this->getSslContext($config); + + // cluster config + if ($isCluster) { + // Support for older phpredis versions not supporting connectionParameters + if ($connectionParameters !== null) { + $this->instance = new \RedisCluster(null, $config['seeds'], $timeout, $readTimeout, false, $auth, $connectionParameters); } else { - $this->instance = new \RedisCluster(null, $config['seeds'], $timeout, $readTimeout); + $this->instance = new \RedisCluster(null, $config['seeds'], $timeout, $readTimeout, false, $auth); } if (isset($config['failover_mode'])) { @@ -69,12 +98,13 @@ class RedisFactory { } } else { $this->instance = new \Redis(); - $config = $this->config->getValue('redis', []); + if (isset($config['host'])) { $host = $config['host']; } else { $host = '127.0.0.1'; } + if (isset($config['port'])) { $port = $config['port']; } elseif ($host[0] !== '/') { @@ -82,15 +112,22 @@ class RedisFactory { } else { $port = null; } - if (isset($config['timeout'])) { - $timeout = $config['timeout']; + + // Support for older phpredis versions not supporting connectionParameters + if ($connectionParameters !== null) { + // Non-clustered redis requires connection parameters to be wrapped inside `stream` + $connectionParameters = [ + 'stream' => $this->getSslContext($config) + ]; + $this->instance->connect($host, $port, $timeout, null, 0, $readTimeout, $connectionParameters); } else { - $timeout = 0.0; // unlimited + $this->instance->connect($host, $port, $timeout, null, 0, $readTimeout); } - $this->instance->connect($host, $port, $timeout); - if (isset($config['password']) && $config['password'] !== '') { - $this->instance->auth($config['password']); + + // Auth if configured + if ($auth !== null) { + $this->instance->auth($auth); } if (isset($config['dbindex'])) { @@ -99,6 +136,26 @@ class RedisFactory { } } + /** + * Get the ssl context config + * + * @param Array $config the current config + * @return Array|null + * @throws \UnexpectedValueException + */ + private function getSslContext($config) { + if (isset($config['ssl_context'])) { + if (!$this->isConnectionParametersSupported()) { + throw new \UnexpectedValueException(\sprintf( + 'php-redis extension must be version %s or higher to support ssl context', + self::REDIS_EXTRA_PARAMETERS_MINIMAL_VERSION + )); + } + return $config['ssl_context']; + } + return null; + } + public function getInstance() { if (!$this->isAvailable()) { throw new \Exception('Redis support is not available'); @@ -114,4 +171,15 @@ class RedisFactory { return extension_loaded('redis') && version_compare(phpversion('redis'), '2.2.5', '>='); } + + /** + * Php redis does support configurable extra parameters since version 5.3.0, see: https://github.com/phpredis/phpredis#connect-open. + * We need to check if the current version supports extra connection parameters, otherwise the connect method will throw an exception + * + * @return boolean + */ + private function isConnectionParametersSupported(): bool { + return \extension_loaded('redis') && + \version_compare(\phpversion('redis'), self::REDIS_EXTRA_PARAMETERS_MINIMAL_VERSION, '>='); + } } |