8000 Introduce `Redis::serverName` and `Redis::serverVersion` methods · phpredis/phpredis@056c2db · GitHub
[go: up one dir, main page]

Skip to content

Commit 056c2db

Browse files
yatsukhnenkomichael-grunder
authored andcommitted
Introduce Redis::serverName and Redis::serverVersion methods
Right now we can't implement `HELLO` command to switch protocol because we don't support new reply types that come with RESP3. But we can use `HELLO` reply to expose some server information.
1 parent f73f5fc commit 056c2db

File tree

7 files changed

+150
-7
lines changed

7 files changed

+150
-7
lines changed

common.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,11 @@ static inline int redis_strncmp(const char *s1, const char *s2, size_t n) {
287287
#define RESP_EXEC_CMD "*1\r\n$4\r\nEXEC\r\n"
288288
#define RESP_DISCARD_CMD "*1\r\n$7\r\nDISCARD\r\n"
289289

290+
typedef struct RedisHello {
291+
zend_string *server;
292+
zend_string *version;
293+
} RedisHello;
294+
290295
/* {{{ struct RedisSock */
291296
typedef struct {
292297
php_stream *stream;
@@ -310,17 +315,15 @@ typedef struct {
310315
int compression;
311316
int compression_level;
312317
long dbNumber;
313-
314318
zend_string *prefix;
315-
319+
struct RedisHello hello;
316320
short mode;
317321
struct fold_item *reply_callback;
318322
size_t reply_callback_count;
319323
size_t reply_callback_capacity;
320324
smart_string pipeline_cmd;
321325

322326
zend_string *err;
323-
324327
int scan;
325328

326329
int readonly;

library.c

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2046,6 +2046,75 @@ redis_client_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval
20462046
}
20472047
}
20482048

2049+
static int
2050+
redis_hello_response(INTERNAL_FUNCTION_PARAMETERS,
2051+
RedisSock *redis_sock, zval *z_tab, void *ctx)
2052+
{
2053+
int numElems;
2054+
zval z_ret, *zv;
2055+
2056+
if (read_mbulk_header(redis_sock, &numElems) < 0) {
2057+
if (IS_ATOMIC(redis_sock)) {
2058+
RETVAL_FALSE;
2059+
} else {
2060+
add_next_index_bool(z_tab, 0);
2061+
}
2062+
return FAILURE;
2063+
}
2064+
2065+
array_init(&z_ret);
2066+
redis_mbulk_reply_zipped_raw_variant(redis_sock, &z_ret, numElems);
2067+
2068+
if (redis_sock->hello.server) {
2069+
zend_string_release(redis_sock->hello.server);
2070+
}
2071+
zv = zend_hash_str_find(Z_ARRVAL(z_ret), ZEND_STRL("server"));
2072+
redis_sock->hello.server = zv ? zval_get_string(zv) : ZSTR_EMPTY_ALLOC();
2073+
2074+
if (redis_sock->hello.version) {
2075+
zend_string_release(redis_sock->hello.version);
2076+
}
2077+
zv = zend_hash_str_find(Z_ARRVAL(z_ret), ZEND_STRL("version"));
2078+
redis_sock->hello.version = zv ? zval_get_string(zv) : ZSTR_EMPTY_ALLOC();
2079+
2080+
if (ctx != NULL) {
2081+
zval_dtor(&z_ret);
2082+
if (ctx == PHPREDIS_CTX_PTR) {
2083+
ZVAL_STR_COPY(&z_ret, redis_sock->hello.server);
2084+
} else if (ctx == PHPREDIS_CTX_PTR + 1) {
2085+
ZVAL_STR_COPY(&z_ret, redis_sock->hello.version);
2086+
} else {
2087+
ZEND_ASSERT(!"memory corruption?");
2088+
return FAILURE;
2089+
}
2090+
}
2091+
2092+
if (IS_ATOMIC(redis_sock)) {
2093+
RETVAL_ZVAL(&z_ret, 0, 1);
2094+
} else {
2095+
add_next_index_zval(z_tab, &z_ret);
2096+
}
2097+
2098+
return SUCCESS;
2099+
}
2100+
2101+
2102+
PHP_REDIS_API int
2103+
redis_hello_server_response(INTERNAL_FUNCTION_PARAMETERS,
2104+
RedisSock *redis_sock, zval *z_tab, void *ctx)
2105+
{
2106+
return redis_hello_response(INTERNAL_FUNCTION_PARAM_PASSTHRU, redis_sock,
2107+
z_tab, PHPREDIS_CTX_PTR);
2108+
}
2109+
2110+
PHP_REDIS_API int
2111+
redis_hello_version_response(INTERNAL_FUNCTION_PARAMETERS,
2112+
RedisSock *redis_sock, zval *z_tab, void *ctx)
2113+
{
2114+
return redis_hello_response(INTERNAL_FUNCTION_PARAM_PASSTHRU, redis_sock,
2115+
z_tab, PHPREDIS_CTX_PTR + 1);
2116+
}
2117+
20492118
static int
20502119
redis_function_reply(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx)
20512120
{
@@ -3578,6 +3647,19 @@ redis_free_reply_callbacks(RedisSock *redis_sock)
35783647
}
35793648
}
35803649

3650+
static void
3651+
redis_sock_release_hello(struct RedisHello *hello) {
3652+
if (hello->server) {
3653+
zend_string_release(hello->server);
3654+
hello->server = NULL;
3655+
}
3656+
3657+
if (hello->version) {
3658+
zend_string_release(hello->version);
3659+
hello->version = NULL;
3660+
}
3661+
}
3662+
35813663
/**
35823664
* redis_free_socket
35833665
*/
@@ -3607,6 +3689,7 @@ PHP_REDIS_API void redis_free_socket(RedisSock *redis_sock)
36073689
}
36083690
redis_sock_free_auth(redis_sock);
36093691
redis_free_reply_callbacks(redis_sock);
3692+
redis_sock_release_hello(&redis_sock->hello);
36103693
efree(redis_sock);
36113694
}
36123695

library.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,9 @@ PHP_REDIS_API int redis_function_response(INTERNAL_FUNCTION_PARAMETERS, RedisSoc
211211
PHP_REDIS_API int redis_command_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
212212
PHP_REDIS_API int redis_select_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
213213

214+
PHP_REDIS_API int redis_hello_server_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
215+
PHP_REDIS_API int redis_hello_version_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
216+
214217
/* Helper methods to get configuration values from a HashTable. */
215218

216219
#define REDIS_HASH_STR_FIND_STATIC(ht, sstr) \

redis.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2577,6 +2577,30 @@ PHP_METHOD(Redis, getPort) {
25772577
}
25782578
}
25792579

2580+
PHP_METHOD(Redis, serverName) {
2581+
RedisSock *rs;
2582+
2583+
if ((rs = redis_sock_get_connected(INTERNAL_FUNCTION_PARAM_PASSTHRU)) == NULL) {
2584+
RETURN_FALSE;
2585+
} else if (rs->hello.server != NULL) {
2586+
RETURN_STR_COPY(rs->hello.server);
2587+
}
2588+
2589+
REDIS_PROCESS_KW_CMD("HELLO", redis_empty_cmd, redis_hello_server_response);
2590+
}
2591+
2592+
PHP_METHOD(Redis, serverVersion) {
2593+
RedisSock *rs;
2594+
2595+
if ((rs = redis_sock_get_connected(INTERNAL_FUNCTION_PARAM_PASSTHRU)) == NULL) {
2596+
RETURN_FALSE;
2597+
} else if (rs->hello.version != NULL) {
2598+
RETURN_STR_COPY(rs->hello.version);
2599+
}
2600+
2601+
REDIS_PROCESS_KW_CMD("HELLO", redis_empty_cmd, redis_hello_version_response);
2602+
}
2603+
25802604
/* {{{ proto Redis::getDBNum */
25812605
PHP_METHOD(Redis, getDBNum) {
25822606
RedisSock *redis_sock;

redis.stub.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1590,6 +1590,20 @@ public function getPersistentID(): ?string;
15901590
*/
15911591
public function getPort(): int;
15921592

1593+
/**
1594+
* Get the server name as reported by the `HELLO` response.
1595+
*
1596+
* @return string|false
1597+
*/
1598+
public function serverName(): Redis|string|false;
1599+
1600+
/**
1601+
* Get the server version as reported by the `HELLO` response.
1602+
*
1603+
* @return string|false
1604+
*/
1605+
public function serverVersion(): Redis|string|false;
1606+
15931607
/**
15941608
* Retrieve a substring of a string by index.
15951609
*

redis_arginfo.h

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* This is a generated file, edit the .stub.php file instead.
2-
* Stub hash: 6dd5a9e9d1d5ed8a78e248c99352232e30046f28 */
2+
* Stub hash: 79376d7ada29d6f9bb873e7c59e64e22af3ca559 */
33

44
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Redis___construct, 0, 0, 0)
55
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, options, IS_ARRAY, 1, "null")
@@ -363,6 +363,11 @@ ZEND_END_ARG_INFO()
363363

364364
#define arginfo_class_Redis_getPort arginfo_class_Redis_getDBNum
365365

366+
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_Redis_serverName, 0, 0, Redis, MAY_BE_STRING|MAY_BE_FALSE)
367+
ZEND_END_ARG_INFO()
368+
369+
#define arginfo_class_Redis_serverVersion arginfo_class_Redis_serverName
370+
366371
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_Redis_getRange, 0, 3, Redis, MAY_BE_STRING|MAY_BE_FALSE)
367372
ZEND_ARG_TYPE_INFO(0, key, IS_STRING, 0)
368373
ZEND_ARG_TYPE_INFO(0, start, IS_LONG, 0)
@@ -681,8 +686,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_Redis_rPop, 0, 1, Redi
681686
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, count, IS_LONG, 0, "0")
682687
ZEND_END_ARG_INFO()
683688

684-
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_Redis_randomKey, 0, 0, Redis, M 10000 AY_BE_STRING|MAY_BE_FALSE)
685-
ZEND_END_ARG_INFO()
689+
#define arginfo_class_Redis_randomKey arginfo_class_Redis_serverName
686690

687691
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Redis_rawcommand, 0, 1, IS_MIXED, 0)
688692
ZEND_ARG_TYPE_INFO(0, command, IS_STRING, 0)
@@ -1263,6 +1267,8 @@ ZEND_METHOD(Redis, getMode);
12631267
ZEND_METHOD(Redis, getOption);
12641268
ZEND_METHOD(Redis, getPersistentID);
12651269
ZEND_METHOD(Redis, getPort);
1270+
ZEND_METHOD(Redis, serverName);
1271+
ZEND_METHOD(Redis, serverVersion);
12661272
ZEND_METHOD(Redis, getRange);
12671273
ZEND_METHOD(Redis, lcs);
12681274
ZEND_METHOD(Redis, getReadTimeout);
@@ -1522,6 +1528,8 @@ static const zend_function_entry class_Redis_methods[] = {
15221528
ZEND_ME(Redis, getOption, arginfo_class_Redis_getOption, ZEND_ACC_PUBLIC)
15231529
ZEND_ME(Redis, getPersistentID, arginfo_class_Redis_getPersistentID, ZEND_ACC_PUBLIC)
15241530
ZEND_ME(Redis, getPort, arginfo_class_Redis_getPort, ZEND_ACC_PUBLIC)
1531+
ZEND_ME(Redis, serverName, arginfo_class_Redis_serverName, ZEND_ACC_PUBLIC)
1532+
ZEND_ME(Redis, serverVersion, arginfo_class_Redis_serverVersion, ZEND_ACC_PUBLIC)
15251533
ZEND_ME(Redis, getRange, arginfo_class_Redis_getRange, ZEND_ACC_PUBLIC)
15261534
ZEND_ME(Redis, lcs, arginfo_class_Redis_lcs, ZEND_ACC_PUBLIC)
15271535
ZEND_ME(Redis, getReadTimeout, arginfo_class_Redis_getReadTimeout, ZEND_ACC_PUBLIC)

redis_legacy_arginfo.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* This is a generated file, edit the .stub.php file instead.
2-
* Stub hash: 6dd5a9e9d1d5ed8a78e248c99352232e30046f28 */
2+
* Stub hash: 79376d7ada29d6f9bb873e7c59e64e22af3ca559 */
33

44
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Redis___construct, 0, 0, 0)
55
ZEND_ARG_INFO(0, options)
@@ -333,6 +333,10 @@ ZEND_END_ARG_INFO()
333333

334334
#define arginfo_class_Redis_getPort arginfo_class_Redis___destruct
335335

336+
#define arginfo_class_Redis_serverName arginfo_class_Redis___destruct
337+
338+
#define arginfo_class_Redis_serverVersion arginfo_class_Redis___destruct
339+
336340
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Redis_getRange, 0, 0, 3)
337341
ZEND_ARG_INFO(0, key)
338342
ZEND_ARG_INFO(0, start)
@@ -1106,6 +1110,8 @@ ZEND_METHOD(Redis, getMode);
11061110
ZEND_METHOD(Redis, getOption);
11071111
ZEND_METHOD(Redis, getPersistentID);
11081112
ZEND_METHOD(Redis, getPort);
1113+
ZEND_METHOD(Redis, serverName);
1114+
ZEND_METHOD(Redis, serverVersion);
11091115
ZEND_METHOD(Redis, getRange);
11101116
ZEND_METHOD(Redis, lcs);
11111117
ZEND_METHOD(Redis, getReadTimeout);
@@ -1365,6 +1371,8 @@ static const zend_function_entry class_Redis_methods[] = {
13651371
ZEND_ME(Redis, getOption, arginfo_class_Redis_getOption, ZEND_ACC_PUBLIC)
13661372
ZEND_ME(Redis, getPersistentID, arginfo_class_Redis_getPersistentID, ZEND_ACC_PUBLIC)
13671373
ZEND_ME(Redis, getPort, arginfo_class_Redis_getPort, ZEND_ACC_PUBLIC)
1374+
ZEND_ME(Redis, serverName, arginfo_class_Redis_serverName, ZEND_ACC_PUBLIC)
1375+
ZEND_ME(Redis, serverVersion, arginfo_class_Redis_serverVersion, ZEND_ACC_PUBLIC)
13681376
ZEND_ME(Redis, getRange, arginfo_class_Redis_getRange, ZEND_ACC_PUBLIC)
13691377
ZEND_ME(Redis, lcs, arginfo_class_Redis_lcs, ZEND_ACC_PUBLIC)
13701378
ZEND_ME(Redis, getReadTimeout, arginfo_class_Redis_getReadTimeout, ZEND_ACC_PUBLIC)

0 commit comments

Comments
 (0)
0