Skip to content

Commit 8c98aea

Browse files
committed
fix: Extract validate_key() and validate_size() in gRPC handlers
1 parent a8df4f1 commit 8c98aea

1 file changed

Lines changed: 47 additions & 41 deletions

File tree

‎src/grpc_server.cpp‎

Lines changed: 47 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,11 @@ namespace kv {
66
namespace {
77
constexpr std::size_t max_key_size = 64 * 1024; // 64 KiB
88
constexpr 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 *,
4261
grpc::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 *,
7082
grpc::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
9398
KvStoreServiceImpl::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

Comments
 (0)