@@ -6,14 +6,11 @@ namespace kv {
66namespace {
77constexpr std::size_t max_key_size = 64 * 1024 ; // 64 KiB
88constexpr std::size_t max_value_size = 1024 * 1024 ; // 1 MiB
9- } // namespace
10-
11- KvStoreServiceImpl::KvStoreServiceImpl (Engine *engine) : engine_(engine) {}
129
13- grpc::Status KvStoreServiceImpl:: Put(grpc::ServerContext *,
14- const kv::v1::PutRequest *request,
15- kv::v1::PutResponse *) {
16- const std::string &key = request-> key ();
10+ // Check a key passed to Put / Get / Delete: must be non-empty and within
11+ // the size cap. Returns OK if valid, otherwise INVALID_ARGUMENT with a
12+ // descriptive message.
13+ grpc::Status validate_key ( const std::string &key) {
1714 if (key.empty ()) {
1815 return grpc::Status (grpc::StatusCode::INVALID_ARGUMENT ,
1916 " Key cannot be empty" );
@@ -23,16 +20,38 @@ grpc::Status KvStoreServiceImpl::Put(grpc::ServerContext *,
2320 " Key size exceeds maximum allowed size of " +
2421 std::to_string (max_key_size) + " bytes" );
2522 }
23+ return grpc::Status::OK ;
24+ }
2625
27- const std::string &value = request->value ();
28- if (value.size () > max_value_size) {
26+ // Generic size check with a customisable field name for the error message.
27+ // Used for Scan's start_key / end_key (empty is allowed) and Put's value.
28+ grpc::Status validate_size (const std::string &field_name, std::size_t actual,
29+ std::size_t max) {
30+ if (actual > max) {
2931 return grpc::Status (grpc::StatusCode::INVALID_ARGUMENT ,
30- " Value size exceeds maximum allowed size of " +
31- std::to_string (max_value_size) + " bytes" );
32+ field_name + " size exceeds maximum allowed size of " +
33+ std::to_string (max) + " bytes" );
34+ }
35+ return grpc::Status::OK ;
36+ }
37+ } // namespace
38+
39+ KvStoreServiceImpl::KvStoreServiceImpl (Engine *engine) : engine_(engine) {}
40+
41+ grpc::Status KvStoreServiceImpl::Put (grpc::ServerContext *,
42+ const kv::v1::PutRequest *request,
43+ kv::v1::PutResponse *) {
44+ if (auto status = validate_key (request->key ()); !status.ok ()) {
45+ return status;
46+ }
47+ if (auto status =
48+ validate_size (" Value" , request->value ().size (), max_value_size);
49+ !status.ok ()) {
50+ return status;
3251 }
3352
3453 try {
35- engine_->put (key, value);
54+ engine_->put (request-> key (), request-> value () );
3655 } catch (const std::exception &e) {
3756 return grpc::Status (grpc::StatusCode::INTERNAL , e.what ());
3857 }
@@ -42,20 +61,13 @@ grpc::Status KvStoreServiceImpl::Put(grpc::ServerContext *,
4261grpc::Status KvStoreServiceImpl::Get (grpc::ServerContext *,
4362 const kv::v1::GetRequest *request,
4463 kv::v1::GetResponse *response) {
45- const std::string &key = request->key ();
46- if (key.empty ()) {
47- return grpc::Status (grpc::StatusCode::INVALID_ARGUMENT ,
48- " Key cannot be empty" );
49- }
50- if (key.size () > max_key_size) {
51- return grpc::Status (grpc::StatusCode::INVALID_ARGUMENT ,
52- " Key size exceeds maximum allowed size of " +
53- std::to_string (max_key_size) + " bytes" );
64+ if (auto status = validate_key (request->key ()); !status.ok ()) {
65+ return status;
5466 }
5567
5668 std::optional<std::string> value;
5769 try {
58- value = engine_->get (key);
70+ value = engine_->get (request-> key () );
5971 } catch (const std::exception &e) {
6072 return grpc::Status (grpc::StatusCode::INTERNAL , e.what ());
6173 }
@@ -70,19 +82,12 @@ grpc::Status KvStoreServiceImpl::Get(grpc::ServerContext *,
7082grpc::Status KvStoreServiceImpl::Delete (grpc::ServerContext *,
7183 const kv::v1::DeleteRequest *request,
7284 kv::v1::DeleteResponse *) {
73- const std::string &key = request->key ();
74- if (key.empty ()) {
75- return grpc::Status (grpc::StatusCode::INVALID_ARGUMENT ,
76- " Key cannot be empty" );
77- }
78- if (key.size () > max_key_size) {
79- return grpc::Status (grpc::StatusCode::INVALID_ARGUMENT ,
80- " Key size exceeds maximum allowed size of " +
81- std::to_string (max_key_size) + " bytes" );
85+ if (auto status = validate_key (request->key ()); !status.ok ()) {
86+ return status;
8287 }
8388
8489 try {
85- engine_->remove (key);
90+ engine_->remove (request-> key () );
8691 } catch (const std::exception &e) {
8792 return grpc::Status (grpc::StatusCode::INTERNAL , e.what ());
8893 }
@@ -93,16 +98,17 @@ grpc::Status
9398KvStoreServiceImpl::Scan (grpc::ServerContext *,
9499 const kv::v1::ScanRequest *request,
95100 grpc::ServerWriter<kv::v1::ScanResponse> *writer) {
96- // Empty start_key / end_key are allowed (mean unbounded).
97- if (request->start_key ().size () > max_key_size) {
98- return grpc::Status (grpc::StatusCode::INVALID_ARGUMENT ,
99- " start_key size exceeds maximum allowed size of " +
100- std::to_string (max_key_size) + " bytes" );
101+ // Empty start_key / end_key are allowed (mean unbounded), so size-only
102+ // validation rather than validate_key.
103+ if (auto status =
104+ validate_size (" start_key" , request->start_key ().size (), max_key_size);
105+ !status.ok ()) {
106+ return status;
101107 }
102- if (request-> end_key (). size () > max_key_size) {
103- return grpc::Status (grpc::StatusCode:: INVALID_ARGUMENT ,
104- " end_key size exceeds maximum allowed size of " +
105- std::to_string (max_key_size) + " bytes " ) ;
108+ if (auto status =
109+ validate_size ( " end_key " , request-> end_key (). size (), max_key_size);
110+ !status. ok ()) {
111+ return status ;
106112 }
107113
108114 try {
0 commit comments