diff options
author | michael-grunder <michael.grunder@gmail.com> | 2022-10-08 21:36:23 +0300 |
---|---|---|
committer | Michael Grunder <michael.grunder@gmail.com> | 2022-10-08 21:49:40 +0300 |
commit | 114d79d15bd21264127e1a8c73e3d7e541fbaac7 (patch) | |
tree | ac38bfed35ba6a9a76b1c53d3f8ceec1e0ba4a10 | |
parent | 6b34d17fc480c99f7c7c9c8fae1a55c13b7e94f3 (diff) |
Implement AUTH/AUTH2 arguments for MIGRATE
-rw-r--r-- | common.h | 2 | ||||
-rw-r--r-- | redis.stub.php | 4 | ||||
-rw-r--r-- | redis_arginfo.h | 11 | ||||
-rw-r--r-- | redis_commands.c | 99 | ||||
-rw-r--r-- | redis_legacy_arginfo.h | 5 |
5 files changed, 71 insertions, 50 deletions
@@ -151,6 +151,8 @@ typedef enum { Z_PARAM_ARRAY_HT_EX(dest, 1, 0) #define Z_PARAM_STR_OR_NULL(dest) \ Z_PARAM_STR_EX(dest, 1, 0) +#define Z_PARAM_ZVAL_OR_NULL(dest) \ + Z_PARAM_ZVAL_EX(dest, 1, 0) #endif #if PHPREDIS_DEBUG_LOGGING == 1 diff --git a/redis.stub.php b/redis.stub.php index 89e6f0c9..55605e96 100644 --- a/redis.stub.php +++ b/redis.stub.php @@ -293,7 +293,9 @@ class Redis { /** @return array|Redis */ public function mget(array $keys); - public function migrate(string $host, int $port, string $key, string $dst, int $timeout, bool $copy = false, bool $replace = false): bool; + public function migrate(string $host, int $port, string|array $key, int $dstdb, int $timeout, + bool $copy = false, bool $replace = false, + #[\SensitiveParameter] ?mixed $credentials = NULL): Redis|bool; public function move(string $key, int $index): bool; diff --git a/redis_arginfo.h b/redis_arginfo.h index acd15086..37265f10 100644 --- a/redis_arginfo.h +++ b/redis_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 0ace014dc4f3f94eedd835f1d6895703aea3e607 */ + * Stub hash: a39dd09e86258566f2eae441d920ef280f8a3e72 */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Redis___construct, 0, 0, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, options, IS_ARRAY, 0, "null") @@ -514,14 +514,15 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Redis_mget, 0, 0, 1) ZEND_ARG_TYPE_INFO(0, keys, IS_ARRAY, 0) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Redis_migrate, 0, 5, _IS_BOOL, 0) +ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_Redis_migrate, 0, 5, Redis, MAY_BE_BOOL) ZEND_ARG_TYPE_INFO(0, host, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, port, IS_LONG, 0) - ZEND_ARG_TYPE_INFO(0, key, IS_STRING, 0) - ZEND_ARG_TYPE_INFO(0, dst, IS_STRING, 0) + ZEND_ARG_TYPE_MASK(0, key, MAY_BE_STRING|MAY_BE_ARRAY, NULL) + ZEND_ARG_TYPE_INFO(0, dstdb, IS_LONG, 0) ZEND_ARG_TYPE_INFO(0, timeout, IS_LONG, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, copy, _IS_BOOL, 0, "false") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, replace, _IS_BOOL, 0, "false") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, credentials, IS_MIXED, 1, "NULL") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Redis_move, 0, 2, _IS_BOOL, 0) @@ -1569,6 +1570,8 @@ static zend_class_entry *register_class_Redis(void) zend_add_parameter_attribute(zend_hash_str_find_ptr(&class_entry->function_table, "auth", sizeof("auth") - 1), 0, ZSTR_KNOWN(ZEND_STR_SENSITIVEPARAMETER), 0); + + zend_add_parameter_attribute(zend_hash_str_find_ptr(&class_entry->function_table, "migrate", sizeof("migrate") - 1), 7, ZSTR_KNOWN(ZEND_STR_SENSITIVEPARAMETER), 0); #endif return class_entry; diff --git a/redis_commands.c b/redis_commands.c index 867ad15e..a3dc4c9e 100644 --- a/redis_commands.c +++ b/redis_commands.c @@ -4257,61 +4257,70 @@ redis_geosearchstore_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, return SUCCESS; } +/* MIGRATE host port <key | ""> destination-db timeout [COPY] [REPLACE] + [[AUTH password] | [AUTH2 username password]] [KEYS key [key ...]] + + Starting with Redis version 3.0.0: Added the COPY and REPLACE options. + Starting with Redis version 3.0.6: Added the KEYS option. + Starting with Redis version 4.0.7: Added the AUTH option. + Starting with Redis version 6.0.0: Added the AUTH2 option. +*/ + /* MIGRATE */ int redis_migrate_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, char **cmd, int *cmd_len, short *slot, void **ctx) { - smart_string cmdstr = {0}; - char *host, *key; - int argc, keyfree; - zval *z_keys, *z_key; - size_t hostlen, keylen; - zend_long destdb, port, timeout; + zend_string *host = NULL, *key = NULL, *user = NULL, *pass = NULL; + zend_long destdb = 0, port = 0, timeout = 0; + zval *zkeys = NULL, *zkey, *zauth = NULL; zend_bool copy = 0, replace = 0; - zend_string *zstr; + smart_string cmdstr = {0}; + int argc; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "slzll|bb", &host, &hostlen, &port, - &z_keys, &destdb, &timeout, ©, &replace) == FAILURE) - { - return FAILURE; + ZEND_PARSE_PARAMETERS_START(5, 8) + Z_PARAM_STR(host) + Z_PARAM_LONG(port) + Z_PARAM_ZVAL(zkeys) + Z_PARAM_LONG(destdb) + Z_PARAM_LONG(timeout) + Z_PARAM_OPTIONAL + Z_PARAM_BOOL(copy) + Z_PARAM_BOOL(replace) + Z_PARAM_ZVAL_OR_NULL(zauth) + ZEND_PARSE_PARAMETERS_END_EX(return FAILURE); + + /* Sanity check on our optional AUTH argument */ + if (zauth && redis_extract_auth_info(zauth, &user, &pass) == FAILURE) { + php_error_docref(NULL, E_WARNING, "AUTH must be a string or an array with one or two strings"); + user = pass = NULL; } /* Protect against being passed an array with zero elements */ - if (Z_TYPE_P(z_keys) == IS_ARRAY && zend_hash_num_elements(Z_ARRVAL_P(z_keys)) == 0) { + if (Z_TYPE_P(zkeys) == IS_ARRAY && zend_hash_num_elements(Z_ARRVAL_P(zkeys)) == 0) { php_error_docref(NULL, E_WARNING, "Keys array cannot be empty"); return FAILURE; } /* host, port, key|"", dest-db, timeout, [copy, replace] [KEYS key1..keyN] */ - argc = 5 + copy + replace; - if (Z_TYPE_P(z_keys) == IS_ARRAY) { + argc = 5 + copy + replace + (user||pass ? 1 : 0) + (user != NULL) + (pass != NULL); + if (Z_TYPE_P(zkeys) == IS_ARRAY) { /* +1 for the "KEYS" argument itself */ - argc += 1 + zend_hash_num_elements(Z_ARRVAL_P(z_keys)); + argc += 1 + zend_hash_num_elements(Z_ARRVAL_P(zkeys)); } /* Initialize MIGRATE command with host and port */ REDIS_CMD_INIT_SSTR_STATIC(&cmdstr, argc, "MIGRATE"); - redis_cmd_append_sstr(&cmdstr, host, hostlen); + redis_cmd_append_sstr_zstr(&cmdstr, host); redis_cmd_append_sstr_long(&cmdstr, port); /* If passed a keys array the keys come later, otherwise pass the key to * migrate here */ - if (Z_TYPE_P(z_keys) == IS_ARRAY) { + if (Z_TYPE_P(zkeys) == IS_ARRAY) { REDIS_CMD_APPEND_SSTR_STATIC(&cmdstr, ""); } else { - /* Grab passed value as a string */ - zstr = zval_get_string(z_keys); - - /* We may need to prefix our string */ - key = ZSTR_VAL(zstr); - keylen = ZSTR_LEN(zstr); - keyfree = redis_key_prefix(redis_sock, &key, &keylen); - - /* Add key to migrate */ - redis_cmd_append_sstr(&cmdstr, key, keylen); - - zend_string_release(zstr); - if (keyfree) efree(key); + key = redis_key_prefix_zval(redis_sock, zkeys); + redis_cmd_append_sstr_zstr(&cmdstr, key); + zend_string_release(key); } redis_cmd_append_sstr_long(&cmdstr, destdb); @@ -4319,25 +4328,29 @@ int redis_migrate_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, REDIS_CMD_APPEND_SSTR_OPT_STATIC(&cmdstr, copy, "COPY"); REDIS_CMD_APPEND_SSTR_OPT_STATIC(&cmdstr, replace, "REPLACE"); + if (user && pass) { + REDIS_CMD_APPEND_SSTR_STATIC(&cmdstr, "AUTH2"); + redis_cmd_append_sstr_zstr(&cmdstr, user); + redis_cmd_append_sstr_zstr(&cmdstr, pass); + } else if (pass) { + REDIS_CMD_APPEND_SSTR_STATIC(&cmdstr, "AUTH"); + redis_cmd_append_sstr_zstr(&cmdstr, pass); + } + /* Append actual keys if we've got a keys array */ - if (Z_TYPE_P(z_keys) == IS_ARRAY) { + if (Z_TYPE_P(zkeys) == IS_ARRAY) { REDIS_CMD_APPEND_SSTR_STATIC(&cmdstr, "KEYS"); - ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(z_keys), z_key) { - zstr = zval_get_string(z_key); - - key = ZSTR_VAL(zstr); - keylen = ZSTR_LEN(zstr); - keyfree = redis_key_prefix(redis_sock, &key, &keylen); - - /* Append the key */ - redis_cmd_append_sstr(&cmdstr, key, keylen); - - zend_string_release(zstr); - if (keyfree) efree(key); + ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(zkeys), zkey) { + key = redis_key_prefix_zval(redis_sock, zkey); + redis_cmd_append_sstr_zstr(&cmdstr, key); + zend_string_release(key); } ZEND_HASH_FOREACH_END(); } + if (user) zend_string_release(user); + if (pass) zend_string_release(pass); + *cmd = cmdstr.c; *cmd_len = cmdstr.len; return SUCCESS; diff --git a/redis_legacy_arginfo.h b/redis_legacy_arginfo.h index b68b5367..b3b61151 100644 --- a/redis_legacy_arginfo.h +++ b/redis_legacy_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 0ace014dc4f3f94eedd835f1d6895703aea3e607 */ + * Stub hash: a39dd09e86258566f2eae441d920ef280f8a3e72 */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Redis___construct, 0, 0, 0) ZEND_ARG_INFO(0, options) @@ -450,10 +450,11 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Redis_migrate, 0, 0, 5) ZEND_ARG_INFO(0, host) ZEND_ARG_INFO(0, port) ZEND_ARG_INFO(0, key) - ZEND_ARG_INFO(0, dst) + ZEND_ARG_INFO(0, dstdb) ZEND_ARG_INFO(0, timeout) ZEND_ARG_INFO(0, copy) ZEND_ARG_INFO(0, replace) + ZEND_ARG_INFO(0, credentials) ZEND_END_ARG_INFO() #define arginfo_class_Redis_move arginfo_class_Redis_lindex |