}
-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;
* 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<io_base_t>(shared_from_this()));
}
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) {
#define CEPH_RGW_AUTH_S3_H
#include <array>
+#include <memory>
#include <string>
#include <tuple>
};
-/* 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<rgw::io::RestfulClient*>,
+ public std::enable_shared_from_this<AWSv4Completer> {
private:
+ using io_base_t = rgw::io::DecoratedRestfulClient<rgw::io::RestfulClient*>;
+
+ SHA256* sha256_hash = nullptr;
+
const bool aws4_auth_needs_complete = true;
const bool aws4_auth_streaming_mode = false;
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)),
}
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. */
} /* 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);
-}
*
* rgw::io::Accounter came in as a part of rgw::io::AccountingFilter. */
class RGWRestfulIO : public rgw::io::AccountingFilter<rgw::io::RestfulClient*> {
- SHA256 *sha256_hash;
std::vector<std::shared_ptr<DecoratedRestfulClient>> filters;
public:
- ~RGWRestfulIO() override {}
+ ~RGWRestfulIO() override = default;
RGWRestfulIO(rgw::io::RestfulClient* engine)
- : AccountingFilter<rgw::io::RestfulClient*>(std::move(engine)),
- sha256_hash(nullptr) {
+ : AccountingFilter<rgw::io::RestfulClient*>(std::move(engine)) {
}
- using DecoratedRestfulClient<RestfulClient*>::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<DecoratedRestfulClient> new_filter) {
new_filter->set_decoratee(this->get_decoratee());
this->set_decoratee(*new_filter);
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();
}
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();
}