#include "include/types.h"
#include "rgw_common.h"
+
+class RGWRestfulIO;
+
namespace rgw {
namespace io {
template <typename DecorateeT>
class DecoratedRestfulClient : public RestfulClient {
template<typename T> friend class DecoratedRestfulClient;
+ friend RGWRestfulIO;
typedef typename std::remove_pointer<DecorateeT>::type DerefedDecorateeT;
* code base between dynamic and static decorators. The difference is about
* what we store internally: pointer to a decorated object versus the whole
* object itself. */
+ template <typename T = void,
+ typename std::enable_if<
+ ! std::is_pointer<DecorateeT>::value, T>::type* = nullptr>
+ DerefedDecorateeT& get_decoratee() {
+ return decoratee;
+ }
+
+protected:
template <typename T = void,
typename std::enable_if<
std::is_pointer<DecorateeT>::value, T>::type* = nullptr>
return *decoratee;
}
+ /* Dynamic decorators (those storing a pointer instead of the decorated
+ * object itself) can be reconfigured on-the-fly. HOWEVER: there are no
+ * facilities for orchestrating such changes. Callers must take care of
+ * atomicity and thread-safety. */
template <typename T = void,
typename std::enable_if<
- ! std::is_pointer<DecorateeT>::value, T>::type* = nullptr>
- DerefedDecorateeT& get_decoratee() {
- return decoratee;
+ std::is_pointer<DecorateeT>::value, T>::type* = nullptr>
+ void set_decoratee(DerefedDecorateeT& new_dec) {
+ decoratee = &new_dec;
}
-protected:
void init_env(CephContext *cct) override {
return get_decoratee().init_env(cct);
}
if (! sync()) {
/* No error, the buffer has been successfully synchronized. */
return c;
- } else {
+ } else {
return std::streambuf::traits_type::eof();
}
}
* 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 {}
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);
+ filters.emplace_back(std::move(new_filter));
+ }
}; /* RGWRestfulIO */