diff --git a/src/redis-cli.c b/src/redis-cli.c index de34965b4..b80e45ab8 100644 --- a/src/redis-cli.c +++ b/src/redis-cli.c @@ -2291,8 +2291,12 @@ static int cliReadReply(int output_raw_strings) { slot = atoi(s+1); s = strrchr(p+1,':'); /* MOVED 3999[P]127.0.0.1[S]6381 */ *s = '\0'; - sdsfree(config.conn_info.hostip); - config.conn_info.hostip = sdsnew(p+1); + if (p+1 != s) { + /* Host might be empty, like 'MOVED 3999 :6381', if endpoint type is unknown. Only update the + * host if it's non-empty. */ + sdsfree(config.conn_info.hostip); + config.conn_info.hostip = sdsnew(p+1); + } config.conn_info.hostport = atoi(s+1); if (config.interactive) printf("-> Redirected to slot [%d] located at %s:%d\n", diff --git a/tests/unit/cluster/cli.tcl b/tests/unit/cluster/cli.tcl index 5b7f24927..76e97210f 100644 --- a/tests/unit/cluster/cli.tcl +++ b/tests/unit/cluster/cli.tcl @@ -81,6 +81,23 @@ start_multiple_servers 3 [list overrides $base_conf] { set node1_rd [redis_deferring_client 0] + test "use previous hostip in \"cluster-preferred-endpoint-type unknown-endpoint\" mode" { + + # backup and set cluster-preferred-endpoint-type unknown-endpoint + set endpoint_type_before_set [lindex [split [$node1 CONFIG GET cluster-preferred-endpoint-type] " "] 1] + $node1 CONFIG SET cluster-preferred-endpoint-type unknown-endpoint + + # when redis-cli not in cluster mode, return MOVE with empty host + set slot_for_foo [$node1 CLUSTER KEYSLOT foo] + assert_error "*MOVED $slot_for_foo :*" {$node1 set foo bar} + + # when in cluster mode, redirect using previous hostip + assert_equal "[exec src/redis-cli -h 127.0.0.1 -p [srv 0 port] -c set foo bar]" {OK} + assert_match "[exec src/redis-cli -h 127.0.0.1 -p [srv 0 port] -c get foo]" {bar} + + assert_equal [$node1 CONFIG SET cluster-preferred-endpoint-type "$endpoint_type_before_set"] {OK} + } + test "Sanity test push cmd after resharding" { assert_error {*MOVED*} {$node3 lpush key9184688 v1}