From 2caa2b0df2b74223bbed4965932afdb891cf5353 Mon Sep 17 00:00:00 2001 From: Ali-Akber Saifee Date: Mon, 6 Jun 2022 08:17:40 -0700 Subject: [PATCH] Update response to HELLO command (#102) * Update response to HELLO command Update response from HELLO command to match the api of redis. Notes: - For any protocol version other than 2 an error matching what redis returns for !2,3 is returned * Add test for redis HELLO command * Extract version building to GetVersion function * Update contributors file * Add HELLO command to README readiness matrix * Revert "Add HELLO command to README readiness matrix" This reverts commit 069f590ad0d95a3494a0eba242c1c7027c340f66. * Add HELLO command to api_status document --- CONTRIBUTORS.md | 3 ++- doc/api_status.md | 1 + src/facade/dragonfly_connection.cc | 4 ++++ src/facade/dragonfly_connection.h | 1 + src/server/dragonfly_test.cc | 14 ++++++++++++++ src/server/server_family.cc | 26 ++++++++++++++++++++++++-- src/server/version.cc.in | 2 ++ src/server/version.h | 2 ++ 8 files changed, 50 insertions(+), 3 deletions(-) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 1ba3e70c6..71e7e0bb6 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -3,4 +3,5 @@ * **[Philipp Born](https://github.com/tamcore)** * Helm Chart * **[Ryan Russell](https://github.com/ryanrussell)** - * Docs & Code Readability \ No newline at end of file + * Docs & Code Readability +* **[Ali-Akber Saifee](https://github.com/alisaifee)** diff --git a/doc/api_status.md b/doc/api_status.md index e29fb0aa0..e21979ace 100644 --- a/doc/api_status.md +++ b/doc/api_status.md @@ -57,6 +57,7 @@ with respect to Memcached and Redis APIs. - [X] EXEC - [X] FLUSHALL - [X] FLUSHDB + - [X] HELLO - [X] INFO - [X] MULTI - [X] SHUTDOWN diff --git a/src/facade/dragonfly_connection.cc b/src/facade/dragonfly_connection.cc index e68497494..d426ef35e 100644 --- a/src/facade/dragonfly_connection.cc +++ b/src/facade/dragonfly_connection.cc @@ -284,6 +284,10 @@ string Connection::GetClientInfo() const { return res; } +uint32 Connection::GetClientId() const { + return id_; +} + io::Result Connection::CheckForHttpProto(FiberSocketBase* peer) { size_t last_len = 0; do { diff --git a/src/facade/dragonfly_connection.h b/src/facade/dragonfly_connection.h index dbee2a47e..67d29dd69 100644 --- a/src/facade/dragonfly_connection.h +++ b/src/facade/dragonfly_connection.h @@ -70,6 +70,7 @@ class Connection : public util::Connection { } std::string GetClientInfo() const; + uint32 GetClientId() const; protected: void OnShutdown() override; diff --git a/src/server/dragonfly_test.cc b/src/server/dragonfly_test.cc index c3b90ee18..7d7334a0d 100644 --- a/src/server/dragonfly_test.cc +++ b/src/server/dragonfly_test.cc @@ -294,6 +294,20 @@ TEST_F(DflyEngineTest, EvalResp) { EXPECT_THAT(resp.GetVec(), ElementsAre(IntArg(5), "foo", "17.5")); } +TEST_F(DflyEngineTest, Hello) { + auto resp_no_param = Run({"hello"}); + ASSERT_THAT(resp_no_param, ArrLen(12)); + + auto resp = Run({"hello", "2"}); + ASSERT_THAT(resp, ArrLen(12)); + EXPECT_THAT(resp.GetVec(), + ElementsAre("server", "redis", "version", "df-dev", "proto", + IntArg(2), "id", ArgType(RespExpr::INT64), "mode", + "standalone", "role", "master")); + + EXPECT_THAT(Run({"hello", "3"}), ErrArg("ERR NOPROTO unsupported protocol")); +} + TEST_F(DflyEngineTest, EvalSha) { auto resp = Run({"script", "load", "return 5"}); EXPECT_THAT(resp, ArgType(RespExpr::STRING)); diff --git a/src/server/server_family.cc b/src/server/server_family.cc index 2be50f1ff..3eea82d53 100644 --- a/src/server/server_family.cc +++ b/src/server/server_family.cc @@ -777,7 +777,7 @@ void ServerFamily::Info(CmdArgList args, ConnectionContext* cntx) { if (should_enter("SERVER")) { ADD_HEADER("# Server"); - append("redis_version", StrCat("df-", kGitTag)); + append("redis_version", GetVersion()); append("redis_mode", "standalone"); append("arch_bits", 64); append("multiplexing_api", "iouring"); @@ -950,7 +950,29 @@ void ServerFamily::Info(CmdArgList args, ConnectionContext* cntx) { } void ServerFamily::Hello(CmdArgList args, ConnectionContext* cntx) { - return (*cntx)->SendOk(); + if (args.size() > 1) { + string_view proto_version = ArgS(args, 1); + + if (proto_version != "2") { + (*cntx)->SendError("NOPROTO unsupported protocol version"); + return; + } + } + + (*cntx)->StartArray(12); + (*cntx)->SendBulkString("server"); + (*cntx)->SendBulkString("redis"); + (*cntx)->SendBulkString("version"); + (*cntx)->SendBulkString(GetVersion()); + (*cntx)->SendBulkString("proto"); + (*cntx)->SendLong(2); + (*cntx)->SendBulkString("id"); + (*cntx)->SendLong(cntx->owner()->GetClientId()); + (*cntx)->SendBulkString("mode"); + (*cntx)->SendBulkString("standalone"); + (*cntx)->SendBulkString("role"); + (*cntx)->SendBulkString((*ServerState::tlocal()).is_master ? "master" : "slave"); + } void ServerFamily::ReplicaOf(CmdArgList args, ConnectionContext* cntx) { diff --git a/src/server/version.cc.in b/src/server/version.cc.in index d090924a8..37753b281 100644 --- a/src/server/version.cc.in +++ b/src/server/version.cc.in @@ -13,4 +13,6 @@ const char kGitSha[] = "@GIT_SHA1@"; const char kGitClean[] = "@GIT_CLEAN_DIRTY@"; const char kBuildTime[] = "@PRJ_BUILD_TIME@"; +const char* GetVersion() { return "df-@GIT_VER@"; } + } // namespace dfly diff --git a/src/server/version.h b/src/server/version.h index 38bbf1a4a..5ea3a5839 100644 --- a/src/server/version.h +++ b/src/server/version.h @@ -11,4 +11,6 @@ extern const char kGitSha[]; extern const char kGitClean[]; extern const char kBuildTime[]; +const char* GetVersion(); + } // namespace dfly