From: Radoslaw Zarzynski Date: Sun, 23 Apr 2017 03:09:43 +0000 (+0200) Subject: rgw: turn AWSv4Completer into a filter over rgw::io::RestfulClient. X-Git-Tag: v12.1.0~155^2~30 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=2778a8ac6dcb93da9cd5e6f402d9087d742b4367;p=ceph.git rgw: turn AWSv4Completer into a filter over rgw::io::RestfulClient. Signed-off-by: Radoslaw Zarzynski --- diff --git a/src/rgw/rgw_auth_s3.cc b/src/rgw/rgw_auth_s3.cc index dd75d0fae4b8..896a6025d501 100644 --- a/src/rgw/rgw_auth_s3.cc +++ b/src/rgw/rgw_auth_s3.cc @@ -812,7 +812,15 @@ std::string get_v4_signature(CephContext* const cct, } -void AWSv4Completer::modify_request_state(req_state* const s_rw) const +size_t AWSv4Completer::recv_body(char* const buf, const size_t max) +{ + const auto received = io_base_t::recv_body(buf, max); + calc_hash_sha256_update_stream(sha256_hash, buf, received); + + return received; +} + +void AWSv4Completer::modify_request_state(req_state* const s_rw) { /* TODO(rzarzynski): switch to the dedicated filter over RestfulClient. */ s_rw->aws4_auth_needs_complete = aws4_auth_needs_complete; @@ -835,6 +843,10 @@ void AWSv4Completer::modify_request_state(req_state* const s_rw) const * the streamed upload. */ throw -ERR_NOT_IMPLEMENTED; } + + /* Install the filter over rgw::io::RestfulClient. */ + AWS_AUTHv4_IO(s_rw)->add_filter( + std::static_pointer_cast(shared_from_this())); } bool AWSv4Completer::complete() @@ -854,7 +866,7 @@ bool AWSv4Completer::complete() /* The completer is only for the cases where signed payload has been * requested. It won't be used, for instance, during the query string-based * authentication. */ - const auto payload_hash = AWS_AUTHv4_IO(s)->grab_aws4_sha256_hash(); + const auto payload_hash = calc_hash_sha256_close_stream(&sha256_hash); /* Validate x-amz-sha256 */ if (payload_hash.compare(expected_request_payload_hash) == 0) { diff --git a/src/rgw/rgw_auth_s3.h b/src/rgw/rgw_auth_s3.h index 3a1de854523b..f9945638b850 100644 --- a/src/rgw/rgw_auth_s3.h +++ b/src/rgw/rgw_auth_s3.h @@ -5,6 +5,7 @@ #define CEPH_RGW_AUTH_S3_H #include +#include #include #include @@ -127,11 +128,14 @@ public: }; -/* TODO(rzarzynski): make the completer to be additionally a decorator over - * rgw::io::RestfulClient (see rgw::io::DecoratedRestfulClient). This would - * allow to eradicate req_state::aws4 and friends. */ -class AWSv4Completer : public rgw::auth::Completer { +class AWSv4Completer : public rgw::auth::Completer, + public rgw::io::DecoratedRestfulClient, + public std::enable_shared_from_this { private: + using io_base_t = rgw::io::DecoratedRestfulClient; + + SHA256* sha256_hash = nullptr; + const bool aws4_auth_needs_complete = true; const bool aws4_auth_streaming_mode = false; @@ -155,7 +159,8 @@ private: std::string credential_scope, std::string seed_signature, const signing_key_t& signing_key) - : aws4_auth_needs_complete(false), + : io_base_t(nullptr), + aws4_auth_needs_complete(false), aws4_auth_streaming_mode(true), date(std::move(date)), credential_scope(std::move(credential_scope)), @@ -165,11 +170,17 @@ private: } AWSv4Completer(const req_state* const s) - : s(s) { + : io_base_t(nullptr), + sha256_hash(calc_hash_sha256_open_stream()), + s(s) { } public: - void modify_request_state(req_state* s) const override; + /* rgw::io::DecoratedRestfulClient. */ + size_t recv_body(char* buf, size_t max) override; + + /* rgw::auth::Completer. */ + void modify_request_state(req_state* s) override; bool complete() override; /* Factories. */ diff --git a/src/rgw/rgw_client_io.cc b/src/rgw/rgw_client_io.cc index 80b181893f3d..dd116c427a8e 100644 --- a/src/rgw/rgw_client_io.cc +++ b/src/rgw/rgw_client_io.cc @@ -28,25 +28,3 @@ void BasicClient::init(CephContext *cct) { } /* namespace io */ } /* namespace rgw */ - -int RGWRestfulIO::recv_body(char *buf, size_t max, bool calculate_hash) -{ - try { - const auto sent = recv_body(buf, max); - - if (calculate_hash) { - if (! sha256_hash) { - sha256_hash = calc_hash_sha256_open_stream(); - } - calc_hash_sha256_update_stream(sha256_hash, buf, sent); - } - return sent; - } catch (rgw::io::Exception& e) { - return -e.code().value(); - } -} - -string RGWRestfulIO::grab_aws4_sha256_hash() -{ - return calc_hash_sha256_close_stream(&sha256_hash); -} diff --git a/src/rgw/rgw_client_io.h b/src/rgw/rgw_client_io.h index 305fb5013a3a..d06eaea3c2d1 100644 --- a/src/rgw/rgw_client_io.h +++ b/src/rgw/rgw_client_io.h @@ -334,21 +334,15 @@ public: * * rgw::io::Accounter came in as a part of rgw::io::AccountingFilter. */ class RGWRestfulIO : public rgw::io::AccountingFilter { - SHA256 *sha256_hash; std::vector> filters; public: - ~RGWRestfulIO() override {} + ~RGWRestfulIO() override = default; RGWRestfulIO(rgw::io::RestfulClient* engine) - : AccountingFilter(std::move(engine)), - sha256_hash(nullptr) { + : AccountingFilter(std::move(engine)) { } - using DecoratedRestfulClient::recv_body; - virtual int recv_body(char* buf, size_t max, bool calculate_hash); - std::string grab_aws4_sha256_hash(); - void add_filter(std::shared_ptr new_filter) { new_filter->set_decoratee(this->get_decoratee()); this->set_decoratee(*new_filter); @@ -414,8 +408,13 @@ public: start = base; } - const int read_len = rio.recv_body(base, window_size, false); - if (read_len < 0 || 0 == read_len) { + size_t read_len = 0; + try { + read_len = rio.recv_body(base, window_size); + } catch (rgw::io::Exception&) { + return traits_type::eof(); + } + if (0 == read_len) { return traits_type::eof(); } diff --git a/src/rgw/rgw_rest.cc b/src/rgw/rgw_rest.cc index 42cc7d7404d8..f3d3d2b55c97 100644 --- a/src/rgw/rgw_rest.cc +++ b/src/rgw/rgw_rest.cc @@ -862,7 +862,7 @@ int recv_body(struct req_state* const s, const size_t max) { try { - return AWS_AUTHv4_IO(s)->recv_body(buf, max, s->aws4_auth_needs_complete); + return RESTFUL_IO(s)->recv_body(buf, max); } catch (rgw::io::Exception& e) { return -e.code().value(); }