From 81589be00a60e16348c65918459e201decdeb768 Mon Sep 17 00:00:00 2001 From: Nadav Har'El Date: Mon, 20 Jul 2020 16:29:29 +0300 Subject: [PATCH] alternator: use api_error factory functions in server.cc All the places in server.cc where we constructed an api_error with inline strings now use api_error factory functions - we needed to add a few more. Interestingly, we had a wrong type string for "Internal Server Error", which we fix in this patch. We wrote the type string like that - with spaces - because this is how it was listed in the DynamoDB documentation at https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Programming.Errors.html But this was in fact wrong, and it should be without spaces: "InternalServerError". The botocore library (for example) recognizes it this way, and this string can also be seen in other online DynamoDB examples. Signed-off-by: Nadav Har'El --- alternator/error.hh | 12 ++++++++++++ alternator/server.cc | 19 ++++++++----------- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/alternator/error.hh b/alternator/error.hh index ca9deca0c5..77278f122c 100644 --- a/alternator/error.hh +++ b/alternator/error.hh @@ -53,6 +53,18 @@ public: static api_error resource_not_found(std::string msg) { return api_error("ResourceNotFoundException", std::move(msg)); } + static api_error invalid_signature(std::string msg) { + return api_error("InvalidSignatureException", std::move(msg)); + } + static api_error unrecognized_client(std::string msg) { + return api_error("UnrecognizedClientException", std::move(msg)); + } + static api_error unknown_operation(std::string msg) { + return api_error("UnknownOperationException", std::move(msg)); + } + static api_error internal(std::string msg) { + return api_error("InternalServerError", std::move(msg), reply::status_type::internal_server_error); + } }; } diff --git a/alternator/server.cc b/alternator/server.cc index 6e5a251cb2..4ed2cce7e2 100644 --- a/alternator/server.cc +++ b/alternator/server.cc @@ -81,12 +81,10 @@ public: generate_error_reply(*rep, ae); } catch (rjson::error & re) { generate_error_reply(*rep, - api_error("ValidationException", re.what())); + api_error::validation(re.what())); } catch (...) { generate_error_reply(*rep, - api_error("Internal Server Error", - format("Internal server error: {}", std::current_exception()), - reply::status_type::internal_server_error)); + api_error::internal(format("Internal server error: {}", std::current_exception()))); } return make_ready_future>(std::move(rep)); } @@ -187,11 +185,11 @@ future<> server::verify_signature(const request& req) { } auto host_it = req._headers.find("Host"); if (host_it == req._headers.end()) { - throw api_error("InvalidSignatureException", "Host header is mandatory for signature verification"); + throw api_error::invalid_signature("Host header is mandatory for signature verification"); } auto authorization_it = req._headers.find("Authorization"); if (authorization_it == req._headers.end()) { - throw api_error("InvalidSignatureException", "Authorization header is mandatory for signature verification"); + throw api_error::invalid_signature("Authorization header is mandatory for signature verification"); } std::string host = host_it->second; std::vector credentials_raw = split(authorization_it->second, ' '); @@ -203,7 +201,7 @@ future<> server::verify_signature(const request& req) { std::vector entry_split = split(entry, '='); if (entry_split.size() != 2) { if (entry != "AWS4-HMAC-SHA256") { - throw api_error("InvalidSignatureException", format("Only AWS4-HMAC-SHA256 algorithm is supported. Found: {}", entry)); + throw api_error::invalid_signature(format("Only AWS4-HMAC-SHA256 algorithm is supported. Found: {}", entry)); } continue; } @@ -224,7 +222,7 @@ future<> server::verify_signature(const request& req) { } std::vector credential_split = split(credential, '/'); if (credential_split.size() != 5) { - throw api_error("ValidationException", format("Incorrect credential information format: {}", credential)); + throw api_error::validation(format("Incorrect credential information format: {}", credential)); } std::string user(credential_split[0]); std::string datestamp(credential_split[1]); @@ -262,7 +260,7 @@ future<> server::verify_signature(const request& req) { if (signature != std::string_view(user_signature)) { _key_cache.remove(user); - throw api_error("UnrecognizedClientException", "The security token included in the request is invalid."); + throw api_error::unrecognized_client("The security token included in the request is invalid."); } }); } @@ -278,8 +276,7 @@ future server::handle_api_request(std::unique_ptr auto callback_it = _callbacks.find(op); if (callback_it == _callbacks.end()) { _executor._stats.unsupported_operations++; - throw api_error("UnknownOperationException", - format("Unsupported operation {}", op)); + throw api_error::unknown_operation(format("Unsupported operation {}", op)); } return with_gate(_pending_requests, [this, callback_it = std::move(callback_it), op = std::move(op), req = std::move(req)] () mutable { //FIXME: Client state can provide more context, e.g. client's endpoint address