X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fceph%2Fsrc%2Frgw%2Frgw_op.h;fp=src%2Fceph%2Fsrc%2Frgw%2Frgw_op.h;h=0000000000000000000000000000000000000000;hb=7da45d65be36d36b880cc55c5036e96c24b53f00;hp=68b83a45f13388d6d3e7bba5cc6406d882a6914a;hpb=691462d09d0987b47e112d6ee8740375df3c51b2;p=stor4nfv.git diff --git a/src/ceph/src/rgw/rgw_op.h b/src/ceph/src/rgw/rgw_op.h deleted file mode 100644 index 68b83a4..0000000 --- a/src/ceph/src/rgw/rgw_op.h +++ /dev/null @@ -1,2194 +0,0 @@ -// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- -// vim: ts=8 sw=2 smarttab -/** - * All operations via the rados gateway are carried out by - * small classes known as RGWOps. This class contains a req_state - * and each possible command is a subclass of this with a defined - * execute() method that does whatever the subclass name implies. - * These subclasses must be further subclassed (by interface type) - * to provide additional virtual methods such as send_response or get_params. - */ -#ifndef CEPH_RGW_OP_H -#define CEPH_RGW_OP_H - -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "common/armor.h" -#include "common/mime.h" -#include "common/utf8.h" -#include "common/ceph_json.h" -#include "common/utf8.h" -#include "common/ceph_time.h" - -#include "rgw_common.h" -#include "rgw_rados.h" -#include "rgw_user.h" -#include "rgw_bucket.h" -#include "rgw_acl.h" -#include "rgw_cors.h" -#include "rgw_quota.h" - -#include "rgw_lc.h" -#include "rgw_torrent.h" -#include "rgw_tag.h" -#include "cls/lock/cls_lock_client.h" -#include "cls/rgw/cls_rgw_client.h" - -#include "include/assert.h" - -using ceph::crypto::SHA1; - -struct req_state; -class RGWOp; - - -namespace rgw { -namespace auth { -namespace registry { - -class StrategyRegistry; - -} -} -} - - -class RGWHandler { -protected: - RGWRados* store; - struct req_state* s; - - int do_init_permissions(); - int do_read_permissions(RGWOp* op, bool only_bucket); - -public: - RGWHandler() - : store(nullptr), - s(nullptr) { - } - virtual ~RGWHandler(); - - virtual int init(RGWRados* store, - struct req_state* _s, - rgw::io::BasicClient* cio); - - virtual int init_permissions(RGWOp*) { - return 0; - } - - virtual int retarget(RGWOp* op, RGWOp** new_op) { - *new_op = op; - return 0; - } - - virtual int read_permissions(RGWOp* op) = 0; - virtual int authorize() = 0; - virtual int postauth_init() = 0; - virtual int error_handler(int err_no, std::string* error_content); - virtual void dump(const string& code, const string& message) const {} -}; - - - -void rgw_bucket_object_pre_exec(struct req_state *s); - -/** - * Provide the base class for all ops. - */ -class RGWOp { -protected: - struct req_state *s; - RGWHandler *dialect_handler; - RGWRados *store; - RGWCORSConfiguration bucket_cors; - bool cors_exist; - RGWQuotaInfo bucket_quota; - RGWQuotaInfo user_quota; - int op_ret; - - int do_aws4_auth_completion(); - - virtual int init_quota(); -public: - RGWOp() - : s(nullptr), - dialect_handler(nullptr), - store(nullptr), - cors_exist(false), - op_ret(0) { - } - - virtual ~RGWOp() = default; - - int get_ret() const { return op_ret; } - - virtual int init_processing() { - op_ret = init_quota(); - if (op_ret < 0) - return op_ret; - - return 0; - } - - virtual void init(RGWRados *store, struct req_state *s, RGWHandler *dialect_handler) { - this->store = store; - this->s = s; - this->dialect_handler = dialect_handler; - } - int read_bucket_cors(); - bool generate_cors_headers(string& origin, string& method, string& headers, string& exp_headers, unsigned *max_age); - - virtual int verify_params() { return 0; } - virtual bool prefetch_data() { return false; } - - /* Authenticate requester -- verify its identity. - * - * NOTE: typically the procedure is common across all operations of the same - * dialect (S3, Swift API). However, there are significant exceptions in - * both APIs: browser uploads, /info and OPTIONS handlers. All of them use - * different, specific authentication schema driving the need for per-op - * authentication. The alternative is to duplicate parts of the method- - * dispatch logic in RGWHandler::authorize() and pollute it with a lot - * of special cases. */ - virtual int verify_requester(const rgw::auth::StrategyRegistry& auth_registry) { - /* TODO(rzarzynski): rename RGWHandler::authorize to generic_authenticate. */ - return dialect_handler->authorize(); - } - virtual int verify_permission() = 0; - virtual int verify_op_mask(); - virtual void pre_exec() {} - virtual void execute() = 0; - virtual void send_response() {} - virtual void complete() { - send_response(); - } - virtual const string name() = 0; - virtual RGWOpType get_type() { return RGW_OP_UNKNOWN; } - - virtual uint32_t op_mask() { return 0; } - - virtual int error_handler(int err_no, string *error_content); -}; - -class RGWGetObj : public RGWOp { -protected: - seed torrent; // get torrent - const char *range_str; - const char *if_mod; - const char *if_unmod; - const char *if_match; - const char *if_nomatch; - uint32_t mod_zone_id; - uint64_t mod_pg_ver; - off_t ofs; - uint64_t total_len; - off_t start; - off_t end; - ceph::real_time mod_time; - ceph::real_time lastmod; - ceph::real_time unmod_time; - ceph::real_time *mod_ptr; - ceph::real_time *unmod_ptr; - map attrs; - bool get_data; - bool partial_content; - bool range_parsed; - bool skip_manifest; - bool skip_decrypt{false}; - rgw_obj obj; - utime_t gc_invalidate_time; - bool is_slo; - string lo_etag; - bool rgwx_stat; /* extended rgw stat operation */ - string version_id; - - // compression attrs - RGWCompressionInfo cs_info; - off_t first_block, last_block; - off_t q_ofs, q_len; - bool first_data; - uint64_t cur_ofs; - bufferlist waiting; - uint64_t action = 0; - - int init_common(); -public: - RGWGetObj() { - range_str = NULL; - if_mod = NULL; - if_unmod = NULL; - if_match = NULL; - if_nomatch = NULL; - mod_zone_id = 0; - mod_pg_ver = 0; - start = 0; - ofs = 0; - total_len = 0; - end = -1; - mod_ptr = NULL; - unmod_ptr = NULL; - get_data = false; - partial_content = false; - range_parsed = false; - skip_manifest = false; - is_slo = false; - first_block = 0; - last_block = 0; - q_ofs = 0; - q_len = 0; - first_data = true; - cur_ofs = 0; - } - - bool prefetch_data() override; - - void set_get_data(bool get_data) { - this->get_data = get_data; - } - int verify_permission() override; - void pre_exec() override; - void execute() override; - int read_user_manifest_part( - rgw_bucket& bucket, - const rgw_bucket_dir_entry& ent, - RGWAccessControlPolicy * const bucket_acl, - const boost::optional& bucket_policy, - const off_t start_ofs, - const off_t end_ofs); - int handle_user_manifest(const char *prefix); - int handle_slo_manifest(bufferlist& bl); - - int get_data_cb(bufferlist& bl, off_t ofs, off_t len); - - virtual int get_params() = 0; - virtual int send_response_data_error() = 0; - virtual int send_response_data(bufferlist& bl, off_t ofs, off_t len) = 0; - - const string name() override { return "get_obj"; } - RGWOpType get_type() override { return RGW_OP_GET_OBJ; } - uint32_t op_mask() override { return RGW_OP_TYPE_READ; } - virtual bool need_object_expiration() { return false; } - /** - * calculates filter used to decrypt RGW objects data - */ - virtual int get_decrypt_filter(std::unique_ptr* filter, RGWGetDataCB* cb, bufferlist* manifest_bl) { - *filter = nullptr; - return 0; - } -}; - -class RGWGetObj_CB : public RGWGetDataCB -{ - RGWGetObj *op; -public: - explicit RGWGetObj_CB(RGWGetObj *_op) : op(_op) {} - ~RGWGetObj_CB() override {} - - int handle_data(bufferlist& bl, off_t bl_ofs, off_t bl_len) override { - return op->get_data_cb(bl, bl_ofs, bl_len); - } -}; - -class RGWGetObj_Filter : public RGWGetDataCB -{ -protected: - RGWGetDataCB* next; -public: - RGWGetObj_Filter(RGWGetDataCB* next): next(next) {} - ~RGWGetObj_Filter() override {} - /** - * Passes data through filter. - * Filter can modify content of bl. - * When bl_len == 0 , it means 'flush - */ - int handle_data(bufferlist& bl, off_t bl_ofs, off_t bl_len) override { - return next->handle_data(bl, bl_ofs, bl_len); - } - /** - * Flushes any cached data. Used by RGWGetObjFilter. - * Return logic same as handle_data. - */ - int flush() override { - return next->flush(); - } - /** - * Allows filter to extend range required for successful filtering - */ - int fixup_range(off_t& ofs, off_t& end) override { - return next->fixup_range(ofs, end); - } -}; - -class RGWGetObjTags : public RGWOp { - protected: - bufferlist tags_bl; - bool has_tags{false}; - public: - int verify_permission(); - void execute(); - void pre_exec(); - - virtual void send_response_data(bufferlist& bl) = 0; - virtual const string name() noexcept override { return "get_obj_tags"; } - virtual uint32_t op_mask() { return RGW_OP_TYPE_READ; } - RGWOpType get_type() { return RGW_OP_GET_OBJ_TAGGING; } - -}; - -class RGWPutObjTags : public RGWOp { - protected: - bufferlist tags_bl; - public: - int verify_permission(); - void execute(); - - virtual void send_response() = 0; - virtual int get_params() = 0; - virtual const string name() { return "put_obj_tags"; } - virtual uint32_t op_mask() { return RGW_OP_TYPE_WRITE; } - RGWOpType get_type() { return RGW_OP_PUT_OBJ_TAGGING; } - -}; - -class RGWDeleteObjTags: public RGWOp { - public: - void pre_exec(); - int verify_permission(); - void execute(); - - virtual void send_response() = 0; - virtual const string name() { return "delete_obj_tags"; } - virtual uint32_t op_mask() { return RGW_OP_TYPE_DELETE; } - RGWOpType get_type() { return RGW_OP_DELETE_OBJ_TAGGING;} -}; - -class RGWBulkDelete : public RGWOp { -public: - struct acct_path_t { - std::string bucket_name; - rgw_obj_key obj_key; - }; - - struct fail_desc_t { - int err; - acct_path_t path; - }; - - class Deleter { - protected: - unsigned int num_deleted; - unsigned int num_unfound; - std::list failures; - - RGWRados * const store; - req_state * const s; - - public: - Deleter(RGWRados * const str, req_state * const s) - : num_deleted(0), - num_unfound(0), - store(str), - s(s) { - } - - unsigned int get_num_deleted() const { - return num_deleted; - } - - unsigned int get_num_unfound() const { - return num_unfound; - } - - const std::list get_failures() const { - return failures; - } - - bool verify_permission(RGWBucketInfo& binfo, - map& battrs, - ACLOwner& bucket_owner /* out */); - bool delete_single(const acct_path_t& path); - bool delete_chunk(const std::list& paths); - }; - /* End of Deleter subclass */ - - static const size_t MAX_CHUNK_ENTRIES = 1024; - -protected: - std::unique_ptr deleter; - -public: - RGWBulkDelete() - : deleter(nullptr) { - } - - int verify_permission() override; - void pre_exec() override; - void execute() override; - - virtual int get_data(std::list& items, - bool * is_truncated) = 0; - void send_response() override = 0; - - const string name() override { return "bulk_delete"; } - RGWOpType get_type() override { return RGW_OP_BULK_DELETE; } - uint32_t op_mask() override { return RGW_OP_TYPE_DELETE; } -}; - -inline ostream& operator<<(ostream& out, const RGWBulkDelete::acct_path_t &o) { - return out << o.bucket_name << "/" << o.obj_key; -} - - -class RGWBulkUploadOp : public RGWOp { - boost::optional dir_ctx; - -protected: - class fail_desc_t { - public: - fail_desc_t(const int err, std::string path) - : err(err), - path(std::move(path)) { - } - - const int err; - const std::string path; - }; - - static constexpr std::array terminal_errors = { - { -EACCES, -EPERM } - }; - - /* FIXME: boost::container::small_vector failures; */ - std::vector failures; - size_t num_created; - - class StreamGetter; - class DecoratedStreamGetter; - class AlignedStreamGetter; - - virtual std::unique_ptr create_stream() = 0; - virtual void send_response() = 0; - - boost::optional> - parse_path(const boost::string_ref& path); - - std::pair - handle_upload_path(struct req_state *s); - - bool handle_file_verify_permission(RGWBucketInfo& binfo, - const rgw_obj& obj, - std::map& battrs, - ACLOwner& bucket_owner /* out */); - int handle_file(boost::string_ref path, - size_t size, - AlignedStreamGetter& body); - - int handle_dir_verify_permission(); - int handle_dir(boost::string_ref path); - -public: - RGWBulkUploadOp() - : num_created(0) { - } - - void init(RGWRados* const store, - struct req_state* const s, - RGWHandler* const h) override { - RGWOp::init(store, s, h); - dir_ctx.emplace(store); - } - - int verify_permission() override; - void pre_exec() override; - void execute() override; - - const std::string name() override { - return "bulk_upload"; - } - - RGWOpType get_type() override { - return RGW_OP_BULK_UPLOAD; - } - - uint32_t op_mask() override { - return RGW_OP_TYPE_WRITE; - } -}; /* RGWBulkUploadOp */ - - -class RGWBulkUploadOp::StreamGetter { -public: - StreamGetter() = default; - virtual ~StreamGetter() = default; - - virtual ssize_t get_at_most(size_t want, ceph::bufferlist& dst) = 0; - virtual ssize_t get_exactly(size_t want, ceph::bufferlist& dst) = 0; -}; /* End of nested subclass StreamGetter */ - - -class RGWBulkUploadOp::DecoratedStreamGetter : public StreamGetter { - StreamGetter& decoratee; - -protected: - StreamGetter& get_decoratee() { - return decoratee; - } - -public: - DecoratedStreamGetter(StreamGetter& decoratee) - : decoratee(decoratee) { - } - virtual ~DecoratedStreamGetter() = default; - - ssize_t get_at_most(const size_t want, ceph::bufferlist& dst) override { - return get_decoratee().get_at_most(want, dst); - } - - ssize_t get_exactly(const size_t want, ceph::bufferlist& dst) override { - return get_decoratee().get_exactly(want, dst); - } -}; /* RGWBulkUploadOp::DecoratedStreamGetter */ - - -class RGWBulkUploadOp::AlignedStreamGetter - : public RGWBulkUploadOp::DecoratedStreamGetter { - size_t position; - size_t length; - size_t alignment; - -public: - template - AlignedStreamGetter(const size_t position, - const size_t length, - const size_t alignment, - U&& decoratee) - : DecoratedStreamGetter(std::forward(decoratee)), - position(position), - length(length), - alignment(alignment) { - } - virtual ~AlignedStreamGetter(); - ssize_t get_at_most(size_t want, ceph::bufferlist& dst) override; - ssize_t get_exactly(size_t want, ceph::bufferlist& dst) override; -}; /* RGWBulkUploadOp::AlignedStreamGetter */ - - -struct RGWUsageStats { - uint64_t bytes_used = 0; - uint64_t bytes_used_rounded = 0; - uint64_t buckets_count = 0; - uint64_t objects_count = 0; -}; - -#define RGW_LIST_BUCKETS_LIMIT_MAX 10000 - -class RGWListBuckets : public RGWOp { -protected: - bool sent_data; - std::string marker; - std::string end_marker; - int64_t limit; - uint64_t limit_max; - std::map attrs; - bool is_truncated; - - RGWUsageStats global_stats; - std::map policies_stats; - - virtual uint64_t get_default_max() const { - return 1000; - } - -public: - RGWListBuckets() - : sent_data(false), - limit(RGW_LIST_BUCKETS_LIMIT_MAX), - limit_max(RGW_LIST_BUCKETS_LIMIT_MAX), - is_truncated(false) { - } - - int verify_permission() override; - void execute() override; - - virtual int get_params() = 0; - virtual void handle_listing_chunk(RGWUserBuckets&& buckets) { - /* The default implementation, used by e.g. S3, just generates a new - * part of listing and sends it client immediately. Swift can behave - * differently: when the reverse option is requested, all incoming - * instances of RGWUserBuckets are buffered and finally reversed. */ - return send_response_data(buckets); - } - virtual void send_response_begin(bool has_buckets) = 0; - virtual void send_response_data(RGWUserBuckets& buckets) = 0; - virtual void send_response_end() = 0; - void send_response() override {} - - virtual bool should_get_stats() { return false; } - virtual bool supports_account_metadata() { return false; } - - const string name() override { return "list_buckets"; } - RGWOpType get_type() override { return RGW_OP_LIST_BUCKETS; } - uint32_t op_mask() override { return RGW_OP_TYPE_READ; } -}; - -class RGWGetUsage : public RGWOp { -protected: - bool sent_data; - string start_date; - string end_date; - int show_log_entries; - int show_log_sum; - map categories; - map usage; - map summary_map; - map buckets_usage; - cls_user_header header; -public: - RGWGetUsage() : sent_data(false), show_log_entries(true), show_log_sum(true){ - } - - int verify_permission() override; - void execute() override; - - virtual int get_params() = 0; - void send_response() override {} - - virtual bool should_get_stats() { return false; } - - const string name() override { return "get_usage"; } - uint32_t op_mask() override { return RGW_OP_TYPE_READ; } -}; - -class RGWStatAccount : public RGWOp { -protected: - RGWUsageStats global_stats; - std::map policies_stats; - -public: - RGWStatAccount() = default; - - int verify_permission() override; - void execute() override; - - void send_response() override = 0; - const std::string name() override { return "stat_account"; } - RGWOpType get_type() override { return RGW_OP_STAT_ACCOUNT; } - uint32_t op_mask() override { return RGW_OP_TYPE_READ; } -}; - -class RGWListBucket : public RGWOp { -protected: - RGWBucketEnt bucket; - string prefix; - rgw_obj_key marker; - rgw_obj_key next_marker; - rgw_obj_key end_marker; - string max_keys; - string delimiter; - string encoding_type; - bool list_versions; - int max; - vector objs; - map common_prefixes; - - int default_max; - bool is_truncated; - - int shard_id; - - int parse_max_keys(); - -public: - RGWListBucket() : list_versions(false), max(0), - default_max(0), is_truncated(false), shard_id(-1) {} - int verify_permission() override; - void pre_exec() override; - void execute() override; - - virtual int get_params() = 0; - void send_response() override = 0; - const string name() override { return "list_bucket"; } - RGWOpType get_type() override { return RGW_OP_LIST_BUCKET; } - uint32_t op_mask() override { return RGW_OP_TYPE_READ; } - virtual bool need_container_stats() { return false; } -}; - -class RGWGetBucketLogging : public RGWOp { -public: - RGWGetBucketLogging() {} - int verify_permission() override; - void execute() override { } - - void send_response() override = 0; - const string name() override { return "get_bucket_logging"; } - RGWOpType get_type() override { return RGW_OP_GET_BUCKET_LOGGING; } - uint32_t op_mask() override { return RGW_OP_TYPE_READ; } -}; - -class RGWGetBucketLocation : public RGWOp { -public: - RGWGetBucketLocation() {} - ~RGWGetBucketLocation() override {} - int verify_permission() override; - void execute() override { } - - void send_response() override = 0; - const string name() override { return "get_bucket_location"; } - RGWOpType get_type() override { return RGW_OP_GET_BUCKET_LOCATION; } - uint32_t op_mask() override { return RGW_OP_TYPE_READ; } -}; - -class RGWGetBucketVersioning : public RGWOp { -protected: - bool versioned; - bool versioning_enabled; -public: - RGWGetBucketVersioning() : versioned(false), versioning_enabled(false) {} - - int verify_permission() override; - void pre_exec() override; - void execute() override; - - void send_response() override = 0; - const string name() override { return "get_bucket_versioning"; } - RGWOpType get_type() override { return RGW_OP_GET_BUCKET_VERSIONING; } - uint32_t op_mask() override { return RGW_OP_TYPE_READ; } -}; - -class RGWSetBucketVersioning : public RGWOp { -protected: - bool enable_versioning; - bufferlist in_data; -public: - RGWSetBucketVersioning() : enable_versioning(false) {} - - int verify_permission() override; - void pre_exec() override; - void execute() override; - - virtual int get_params() { return 0; } - - void send_response() override = 0; - const string name() override { return "set_bucket_versioning"; } - RGWOpType get_type() override { return RGW_OP_SET_BUCKET_VERSIONING; } - uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; } -}; - -class RGWGetBucketWebsite : public RGWOp { -public: - RGWGetBucketWebsite() {} - - int verify_permission() override; - void pre_exec() override; - void execute() override; - - void send_response() override = 0; - const string name() override { return "get_bucket_website"; } - RGWOpType get_type() override { return RGW_OP_GET_BUCKET_WEBSITE; } - uint32_t op_mask() override { return RGW_OP_TYPE_READ; } -}; - -class RGWSetBucketWebsite : public RGWOp { -protected: - bufferlist in_data; - RGWBucketWebsiteConf website_conf; -public: - RGWSetBucketWebsite() {} - - int verify_permission() override; - void pre_exec() override; - void execute() override; - - virtual int get_params() { return 0; } - - void send_response() override = 0; - const string name() override { return "set_bucket_website"; } - RGWOpType get_type() override { return RGW_OP_SET_BUCKET_WEBSITE; } - uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; } -}; - -class RGWDeleteBucketWebsite : public RGWOp { -public: - RGWDeleteBucketWebsite() {} - - int verify_permission() override; - void pre_exec() override; - void execute() override; - - void send_response() override = 0; - const string name() override { return "delete_bucket_website"; } - RGWOpType get_type() override { return RGW_OP_SET_BUCKET_WEBSITE; } - uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; } -}; - -class RGWStatBucket : public RGWOp { -protected: - RGWBucketEnt bucket; - -public: - RGWStatBucket() {} - ~RGWStatBucket() override {} - - int verify_permission() override; - void pre_exec() override; - void execute() override; - - void send_response() override = 0; - const string name() override { return "stat_bucket"; } - RGWOpType get_type() override { return RGW_OP_STAT_BUCKET; } - uint32_t op_mask() override { return RGW_OP_TYPE_READ; } -}; - -class RGWCreateBucket : public RGWOp { -protected: - RGWAccessControlPolicy policy; - string location_constraint; - string placement_rule; - RGWBucketInfo info; - obj_version ep_objv; - bool has_cors; - RGWCORSConfiguration cors_config; - boost::optional swift_ver_location; - map attrs; - set rmattr_names; - - bufferlist in_data; - - virtual bool need_metadata_upload() const { return false; } - -public: - RGWCreateBucket() : has_cors(false) {} - - void emplace_attr(std::string&& key, buffer::list&& bl) { - attrs.emplace(std::move(key), std::move(bl)); /* key and bl are r-value refs */ - } - - int verify_permission() override; - void pre_exec() override; - void execute() override; - void init(RGWRados *store, struct req_state *s, RGWHandler *h) override { - RGWOp::init(store, s, h); - policy.set_ctx(s->cct); - } - virtual int get_params() { return 0; } - void send_response() override = 0; - const string name() override { return "create_bucket"; } - RGWOpType get_type() override { return RGW_OP_CREATE_BUCKET; } - uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; } -}; - -class RGWDeleteBucket : public RGWOp { -protected: - RGWObjVersionTracker objv_tracker; - -public: - RGWDeleteBucket() {} - - int verify_permission() override; - void pre_exec() override; - void execute() override; - - void send_response() override = 0; - const string name() override { return "delete_bucket"; } - RGWOpType get_type() override { return RGW_OP_DELETE_BUCKET; } - uint32_t op_mask() override { return RGW_OP_TYPE_DELETE; } -}; - -struct rgw_slo_entry { - string path; - string etag; - uint64_t size_bytes; - - rgw_slo_entry() : size_bytes(0) {} - - void encode(bufferlist& bl) const { - ENCODE_START(1, 1, bl); - ::encode(path, bl); - ::encode(etag, bl); - ::encode(size_bytes, bl); - ENCODE_FINISH(bl); - } - - void decode(bufferlist::iterator& bl) { - DECODE_START(1, bl); - ::decode(path, bl); - ::decode(etag, bl); - ::decode(size_bytes, bl); - DECODE_FINISH(bl); - } - - void decode_json(JSONObj *obj); -}; -WRITE_CLASS_ENCODER(rgw_slo_entry) - -struct RGWSLOInfo { - vector entries; - uint64_t total_size; - - /* in memory only */ - char *raw_data; - int raw_data_len; - - RGWSLOInfo() : total_size(0), raw_data(NULL), raw_data_len(0) {} - ~RGWSLOInfo() { - free(raw_data); - } - - void encode(bufferlist& bl) const { - ENCODE_START(1, 1, bl); - ::encode(entries, bl); - ::encode(total_size, bl); - ENCODE_FINISH(bl); - } - - void decode(bufferlist::iterator& bl) { - DECODE_START(1, bl); - ::decode(entries, bl); - ::decode(total_size, bl); - DECODE_FINISH(bl); - } -}; -WRITE_CLASS_ENCODER(RGWSLOInfo) - -class RGWPutObj : public RGWOp { - - friend class RGWPutObjProcessor; - -protected: - seed torrent; - off_t ofs; - const char *supplied_md5_b64; - const char *supplied_etag; - const char *if_match; - const char *if_nomatch; - const char *copy_source; - const char *copy_source_range; - RGWBucketInfo copy_source_bucket_info; - string copy_source_tenant_name; - string copy_source_bucket_name; - string copy_source_object_name; - string copy_source_version_id; - off_t copy_source_range_fst; - off_t copy_source_range_lst; - string etag; - bool chunked_upload; - RGWAccessControlPolicy policy; - std::unique_ptr obj_tags; - const char *dlo_manifest; - RGWSLOInfo *slo_info; - map attrs; - ceph::real_time mtime; - uint64_t olh_epoch; - string version_id; - bufferlist bl_aux; - map crypt_http_responses; - string user_data; - - boost::optional delete_at; - -public: - RGWPutObj() : ofs(0), - supplied_md5_b64(NULL), - supplied_etag(NULL), - if_match(NULL), - if_nomatch(NULL), - copy_source(NULL), - copy_source_range(NULL), - copy_source_range_fst(0), - copy_source_range_lst(0), - chunked_upload(0), - dlo_manifest(NULL), - slo_info(NULL), - olh_epoch(0) {} - - ~RGWPutObj() override { - delete slo_info; - } - - void init(RGWRados *store, struct req_state *s, RGWHandler *h) override { - RGWOp::init(store, s, h); - policy.set_ctx(s->cct); - } - - void emplace_attr(std::string&& key, buffer::list&& bl) { - attrs.emplace(std::move(key), std::move(bl)); /* key and bl are r-value refs */ - } - - virtual RGWPutObjProcessor *select_processor(RGWObjectCtx& obj_ctx, bool *is_multipart); - void dispose_processor(RGWPutObjDataProcessor *processor); - - int verify_permission() override; - void pre_exec() override; - void execute() override; - - /* this is for cases when copying data from other object */ - virtual int get_decrypt_filter(std::unique_ptr* filter, - RGWGetDataCB* cb, - map& attrs, - bufferlist* manifest_bl) { - *filter = nullptr; - return 0; - } - virtual int get_encrypt_filter(std::unique_ptr *filter, RGWPutObjDataProcessor* cb) { - *filter = nullptr; - return 0; - } - - int get_data_cb(bufferlist& bl, off_t bl_ofs, off_t bl_len); - int get_data(const off_t fst, const off_t lst, bufferlist& bl); - - virtual int get_params() = 0; - virtual int get_data(bufferlist& bl) = 0; - void send_response() override = 0; - const string name() override { return "put_obj"; } - RGWOpType get_type() override { return RGW_OP_PUT_OBJ; } - uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; } -}; - -class RGWPutObj_Filter : public RGWPutObjDataProcessor -{ -protected: - RGWPutObjDataProcessor* next; -public: - RGWPutObj_Filter(RGWPutObjDataProcessor* next) : - next(next){} - ~RGWPutObj_Filter() override {} - int handle_data(bufferlist& bl, off_t ofs, void **phandle, rgw_raw_obj *pobj, bool *again) override { - return next->handle_data(bl, ofs, phandle, pobj, again); - } - int throttle_data(void *handle, const rgw_raw_obj& obj, uint64_t size, bool need_to_wait) override { - return next->throttle_data(handle, obj, size, need_to_wait); - } -}; /* RGWPutObj_Filter */ - -class RGWPostObj : public RGWOp { -protected: - off_t min_len; - off_t max_len; - int len; - off_t ofs; - const char *supplied_md5_b64; - const char *supplied_etag; - string etag; - RGWAccessControlPolicy policy; - map attrs; - boost::optional delete_at; - - /* Must be called after get_data() or the result is undefined. */ - virtual std::string get_current_filename() const = 0; - virtual std::string get_current_content_type() const = 0; - virtual bool is_next_file_to_upload() { - return false; - } -public: - RGWPostObj() : min_len(0), - max_len(LLONG_MAX), - len(0), - ofs(0), - supplied_md5_b64(nullptr), - supplied_etag(nullptr) { - } - - void emplace_attr(std::string&& key, buffer::list&& bl) { - attrs.emplace(std::move(key), std::move(bl)); /* key and bl are r-value refs */ - } - - void init(RGWRados *store, struct req_state *s, RGWHandler *h) override { - RGWOp::init(store, s, h); - policy.set_ctx(s->cct); - } - - int verify_permission() override; - void pre_exec() override; - void execute() override; - - virtual int get_encrypt_filter(std::unique_ptr *filter, RGWPutObjDataProcessor* cb) { - *filter = nullptr; - return 0; - } - virtual int get_params() = 0; - virtual int get_data(ceph::bufferlist& bl, bool& again) = 0; - void send_response() override = 0; - const std::string name() override { return "post_obj"; } - RGWOpType get_type() override { return RGW_OP_POST_OBJ; } - uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; } -}; - -class RGWPutMetadataAccount : public RGWOp { -protected: - std::set rmattr_names; - std::map attrs, orig_attrs; - std::map temp_url_keys; - RGWQuotaInfo new_quota; - bool new_quota_extracted; - - RGWObjVersionTracker acct_op_tracker; - - RGWAccessControlPolicy policy; - bool has_policy; - -public: - RGWPutMetadataAccount() - : new_quota_extracted(false), - has_policy(false) { - } - - void init(RGWRados *store, struct req_state *s, RGWHandler *h) override { - RGWOp::init(store, s, h); - policy.set_ctx(s->cct); - } - int init_processing() override; - int verify_permission() override; - void pre_exec() override { } - void execute() override; - - virtual int get_params() = 0; - void send_response() override = 0; - virtual void filter_out_temp_url(map& add_attrs, - const set& rmattr_names, - map& temp_url_keys); - const string name() override { return "put_account_metadata"; } - RGWOpType get_type() override { return RGW_OP_PUT_METADATA_ACCOUNT; } - uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; } -}; - -class RGWPutMetadataBucket : public RGWOp { -protected: - map attrs; - set rmattr_names; - bool has_policy, has_cors; - uint32_t policy_rw_mask; - RGWAccessControlPolicy policy; - RGWCORSConfiguration cors_config; - string placement_rule; - boost::optional swift_ver_location; - -public: - RGWPutMetadataBucket() - : has_policy(false), has_cors(false), policy_rw_mask(0) - {} - - void emplace_attr(std::string&& key, buffer::list&& bl) { - attrs.emplace(std::move(key), std::move(bl)); /* key and bl are r-value refs */ - } - - void init(RGWRados *store, struct req_state *s, RGWHandler *h) override { - RGWOp::init(store, s, h); - policy.set_ctx(s->cct); - } - - int verify_permission() override; - void pre_exec() override; - void execute() override; - - virtual int get_params() = 0; - void send_response() override = 0; - const string name() override { return "put_bucket_metadata"; } - RGWOpType get_type() override { return RGW_OP_PUT_METADATA_BUCKET; } - uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; } -}; - -class RGWPutMetadataObject : public RGWOp { -protected: - RGWAccessControlPolicy policy; - string placement_rule; - boost::optional delete_at; - const char *dlo_manifest; - -public: - RGWPutMetadataObject() - : dlo_manifest(NULL) - {} - - void init(RGWRados *store, struct req_state *s, RGWHandler *h) override { - RGWOp::init(store, s, h); - policy.set_ctx(s->cct); - } - int verify_permission() override; - void pre_exec() override; - void execute() override; - - virtual int get_params() = 0; - void send_response() override = 0; - const string name() override { return "put_obj_metadata"; } - RGWOpType get_type() override { return RGW_OP_PUT_METADATA_OBJECT; } - uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; } - virtual bool need_object_expiration() { return false; } -}; - -class RGWDeleteObj : public RGWOp { -protected: - bool delete_marker; - bool multipart_delete; - string version_id; - ceph::real_time unmod_since; /* if unmodified since */ - bool no_precondition_error; - std::unique_ptr deleter; - -public: - RGWDeleteObj() - : delete_marker(false), - multipart_delete(false), - no_precondition_error(false), - deleter(nullptr) { - } - - int verify_permission() override; - void pre_exec() override; - void execute() override; - int handle_slo_manifest(bufferlist& bl); - - virtual int get_params() { return 0; } - void send_response() override = 0; - const string name() override { return "delete_obj"; } - RGWOpType get_type() override { return RGW_OP_DELETE_OBJ; } - uint32_t op_mask() override { return RGW_OP_TYPE_DELETE; } - virtual bool need_object_expiration() { return false; } -}; - -class RGWCopyObj : public RGWOp { -protected: - RGWAccessControlPolicy dest_policy; - const char *if_mod; - const char *if_unmod; - const char *if_match; - const char *if_nomatch; - off_t ofs; - off_t len; - off_t end; - ceph::real_time mod_time; - ceph::real_time unmod_time; - ceph::real_time *mod_ptr; - ceph::real_time *unmod_ptr; - map attrs; - string src_tenant_name, src_bucket_name; - rgw_bucket src_bucket; - rgw_obj_key src_object; - string dest_tenant_name, dest_bucket_name; - rgw_bucket dest_bucket; - string dest_object; - ceph::real_time src_mtime; - ceph::real_time mtime; - RGWRados::AttrsMod attrs_mod; - RGWBucketInfo src_bucket_info; - RGWBucketInfo dest_bucket_info; - string source_zone; - string client_id; - string op_id; - ceph::buffer::list etag; - - off_t last_ofs; - - string version_id; - uint64_t olh_epoch; - - boost::optional delete_at; - bool copy_if_newer; - - int init_common(); - -public: - RGWCopyObj() { - if_mod = NULL; - if_unmod = NULL; - if_match = NULL; - if_nomatch = NULL; - ofs = 0; - len = 0; - end = -1; - mod_ptr = NULL; - unmod_ptr = NULL; - attrs_mod = RGWRados::ATTRSMOD_NONE; - last_ofs = 0; - olh_epoch = 0; - copy_if_newer = false; - } - - static bool parse_copy_location(const string& src, - string& bucket_name, - rgw_obj_key& object); - - void emplace_attr(std::string&& key, buffer::list&& bl) { - attrs.emplace(std::move(key), std::move(bl)); - } - - void init(RGWRados *store, struct req_state *s, RGWHandler *h) override { - RGWOp::init(store, s, h); - dest_policy.set_ctx(s->cct); - } - int verify_permission() override; - void pre_exec() override; - void execute() override; - void progress_cb(off_t ofs); - - virtual int init_dest_policy() { return 0; } - virtual int get_params() = 0; - virtual void send_partial_response(off_t ofs) {} - void send_response() override = 0; - const string name() override { return "copy_obj"; } - RGWOpType get_type() override { return RGW_OP_COPY_OBJ; } - uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; } -}; - -class RGWGetACLs : public RGWOp { -protected: - string acls; - -public: - RGWGetACLs() {} - - int verify_permission() override; - void pre_exec() override; - void execute() override; - - void send_response() override = 0; - const string name() override { return "get_acls"; } - RGWOpType get_type() override { return RGW_OP_GET_ACLS; } - uint32_t op_mask() override { return RGW_OP_TYPE_READ; } -}; - -class RGWPutACLs : public RGWOp { -protected: - int len; - char *data; - ACLOwner owner; - -public: - RGWPutACLs() { - len = 0; - data = NULL; - } - ~RGWPutACLs() override { - free(data); - } - - int verify_permission() override; - void pre_exec() override; - void execute() override; - - virtual int get_policy_from_state(RGWRados *store, struct req_state *s, stringstream& ss) { return 0; } - virtual int get_params() = 0; - void send_response() override = 0; - const string name() override { return "put_acls"; } - RGWOpType get_type() override { return RGW_OP_PUT_ACLS; } - uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; } -}; - -class RGWGetLC : public RGWOp { -protected: - -public: - RGWGetLC() { } - ~RGWGetLC() override { } - - int verify_permission() override; - void pre_exec() override; - void execute() override = 0; - - void send_response() override = 0; - const string name() override { return "get_lifecycle"; } - RGWOpType get_type() override { return RGW_OP_GET_LC; } - uint32_t op_mask() override { return RGW_OP_TYPE_READ; } -}; - -class RGWPutLC : public RGWOp { -protected: - int len; - char *data; - string cookie; - -public: - RGWPutLC() { - len = 0; - data = NULL; - } - ~RGWPutLC() override { - free(data); - } - - void init(RGWRados *store, struct req_state *s, RGWHandler *dialect_handler) override { -#define COOKIE_LEN 16 - char buf[COOKIE_LEN + 1]; - - RGWOp::init(store, s, dialect_handler); - gen_rand_alphanumeric(s->cct, buf, sizeof(buf) - 1); - cookie = buf; - } - - int verify_permission() override; - void pre_exec() override; - void execute() override; - -// virtual int get_policy_from_state(RGWRados *store, struct req_state *s, stringstream& ss) { return 0; } - virtual int get_params() = 0; - void send_response() override = 0; - const string name() override { return "put_lifecycle"; } - RGWOpType get_type() override { return RGW_OP_PUT_LC; } - uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; } -}; - -class RGWDeleteLC : public RGWOp { -protected: - size_t len; - char *data; - -public: - RGWDeleteLC() { - len = 0; - data = NULL; - } - ~RGWDeleteLC() override { - free(data); - } - - int verify_permission() override; - void pre_exec() override; - void execute() override; - - void send_response() override = 0; - const string name() override { return "delete_lifecycle"; } - RGWOpType get_type() override { return RGW_OP_DELETE_LC; } - uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; } -}; - -class RGWGetCORS : public RGWOp { -protected: - -public: - RGWGetCORS() {} - - int verify_permission() override; - void execute() override; - - void send_response() override = 0; - const string name() override { return "get_cors"; } - RGWOpType get_type() override { return RGW_OP_GET_CORS; } - uint32_t op_mask() override { return RGW_OP_TYPE_READ; } -}; - -class RGWPutCORS : public RGWOp { -protected: - bufferlist cors_bl; - bufferlist in_data; - -public: - RGWPutCORS() {} - ~RGWPutCORS() override {} - - int verify_permission() override; - void execute() override; - - virtual int get_params() = 0; - void send_response() override = 0; - const string name() override { return "put_cors"; } - RGWOpType get_type() override { return RGW_OP_PUT_CORS; } - uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; } -}; - -class RGWDeleteCORS : public RGWOp { -protected: - -public: - RGWDeleteCORS() {} - - int verify_permission() override; - void execute() override; - - void send_response() override = 0; - const string name() override { return "delete_cors"; } - RGWOpType get_type() override { return RGW_OP_DELETE_CORS; } - uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; } -}; - -class RGWOptionsCORS : public RGWOp { -protected: - RGWCORSRule *rule; - const char *origin, *req_hdrs, *req_meth; - -public: - RGWOptionsCORS() : rule(NULL), origin(NULL), - req_hdrs(NULL), req_meth(NULL) { - } - - int verify_permission() override {return 0;} - int validate_cors_request(RGWCORSConfiguration *cc); - void execute() override; - void get_response_params(string& allowed_hdrs, string& exp_hdrs, unsigned *max_age); - void send_response() override = 0; - const string name() override { return "options_cors"; } - RGWOpType get_type() override { return RGW_OP_OPTIONS_CORS; } - uint32_t op_mask() override { return RGW_OP_TYPE_READ; } -}; - -class RGWGetRequestPayment : public RGWOp { -protected: - bool requester_pays; - -public: - RGWGetRequestPayment() : requester_pays(0) {} - - int verify_permission() override; - void pre_exec() override; - void execute() override; - - void send_response() override = 0; - const string name() override { return "get_request_payment"; } - RGWOpType get_type() override { return RGW_OP_GET_REQUEST_PAYMENT; } - uint32_t op_mask() override { return RGW_OP_TYPE_READ; } -}; - -class RGWSetRequestPayment : public RGWOp { -protected: - bool requester_pays; -public: - RGWSetRequestPayment() : requester_pays(false) {} - - int verify_permission() override; - void pre_exec() override; - void execute() override; - - virtual int get_params() { return 0; } - - void send_response() override = 0; - const string name() override { return "set_request_payment"; } - RGWOpType get_type() override { return RGW_OP_SET_REQUEST_PAYMENT; } - uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; } -}; - -class RGWInitMultipart : public RGWOp { -protected: - string upload_id; - RGWAccessControlPolicy policy; - -public: - RGWInitMultipart() {} - - void init(RGWRados *store, struct req_state *s, RGWHandler *h) override { - RGWOp::init(store, s, h); - policy.set_ctx(s->cct); - } - int verify_permission() override; - void pre_exec() override; - void execute() override; - - virtual int get_params() = 0; - void send_response() override = 0; - const string name() override { return "init_multipart"; } - RGWOpType get_type() override { return RGW_OP_INIT_MULTIPART; } - uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; } - virtual int prepare_encryption(map& attrs) { return 0; } -}; - -class RGWCompleteMultipart : public RGWOp { -protected: - string upload_id; - string etag; - char *data; - int len; - - struct MPSerializer { - librados::IoCtx ioctx; - rados::cls::lock::Lock lock; - librados::ObjectWriteOperation op; - std::string oid; - bool locked; - - MPSerializer() : lock("RGWCompleteMultipart"), locked(false) - {} - - int try_lock(const std::string& oid, utime_t dur); - - int unlock() { - return lock.unlock(&ioctx, oid); - } - - void clear_locked() { - locked = false; - } - } serializer; - -public: - RGWCompleteMultipart() { - data = NULL; - len = 0; - } - ~RGWCompleteMultipart() override { - free(data); - } - - int verify_permission() override; - void pre_exec() override; - void execute() override; - void complete() override; - - virtual int get_params() = 0; - void send_response() override = 0; - const string name() override { return "complete_multipart"; } - RGWOpType get_type() override { return RGW_OP_COMPLETE_MULTIPART; } - uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; } -}; - -class RGWAbortMultipart : public RGWOp { -public: - RGWAbortMultipart() {} - - int verify_permission() override; - void pre_exec() override; - void execute() override; - - void send_response() override = 0; - const string name() override { return "abort_multipart"; } - RGWOpType get_type() override { return RGW_OP_ABORT_MULTIPART; } - uint32_t op_mask() override { return RGW_OP_TYPE_DELETE; } -}; - -class RGWListMultipart : public RGWOp { -protected: - string upload_id; - map parts; - int max_parts; - int marker; - RGWAccessControlPolicy policy; - bool truncated; - -public: - RGWListMultipart() { - max_parts = 1000; - marker = 0; - truncated = false; - } - - void init(RGWRados *store, struct req_state *s, RGWHandler *h) override { - RGWOp::init(store, s, h); - policy = RGWAccessControlPolicy(s->cct); - } - int verify_permission() override; - void pre_exec() override; - void execute() override; - - virtual int get_params() = 0; - void send_response() override = 0; - const string name() override { return "list_multipart"; } - RGWOpType get_type() override { return RGW_OP_LIST_MULTIPART; } - uint32_t op_mask() override { return RGW_OP_TYPE_READ; } -}; - -struct RGWMultipartUploadEntry { - rgw_bucket_dir_entry obj; - RGWMPObj mp; -}; - -class RGWListBucketMultiparts : public RGWOp { -protected: - string prefix; - RGWMPObj marker; - RGWMultipartUploadEntry next_marker; - int max_uploads; - string delimiter; - vector uploads; - map common_prefixes; - bool is_truncated; - int default_max; - -public: - RGWListBucketMultiparts() { - max_uploads = 0; - is_truncated = false; - default_max = 0; - } - - void init(RGWRados *store, struct req_state *s, RGWHandler *h) override { - RGWOp::init(store, s, h); - max_uploads = default_max; - } - - int verify_permission() override; - void pre_exec() override; - void execute() override; - - virtual int get_params() = 0; - void send_response() override = 0; - const string name() override { return "list_bucket_multiparts"; } - RGWOpType get_type() override { return RGW_OP_LIST_BUCKET_MULTIPARTS; } - uint32_t op_mask() override { return RGW_OP_TYPE_READ; } -}; - - -class RGWGetCrossDomainPolicy : public RGWOp { -public: - RGWGetCrossDomainPolicy() = default; - ~RGWGetCrossDomainPolicy() override = default; - - int verify_permission() override { - return 0; - } - - void execute() override { - op_ret = 0; - } - - const string name() override { - return "get_crossdomain_policy"; - } - - RGWOpType get_type() override { - return RGW_OP_GET_CROSS_DOMAIN_POLICY; - } - - uint32_t op_mask() override { - return RGW_OP_TYPE_READ; - } -}; - - -class RGWGetHealthCheck : public RGWOp { -public: - RGWGetHealthCheck() = default; - ~RGWGetHealthCheck() override = default; - - int verify_permission() override { - return 0; - } - - void execute() override; - - const string name() override { - return "get_health_check"; - } - - RGWOpType get_type() override { - return RGW_OP_GET_HEALTH_CHECK; - } - - uint32_t op_mask() override { - return RGW_OP_TYPE_READ; - } -}; - - -class RGWDeleteMultiObj : public RGWOp { -protected: - int max_to_delete; - int len; - char *data; - rgw_bucket bucket; - bool quiet; - bool status_dumped; - bool acl_allowed = false; - -public: - RGWDeleteMultiObj() { - max_to_delete = 1000; - len = 0; - data = NULL; - quiet = false; - status_dumped = false; - } - int verify_permission() override; - void pre_exec() override; - void execute() override; - - virtual int get_params() = 0; - virtual void send_status() = 0; - virtual void begin_response() = 0; - virtual void send_partial_response(rgw_obj_key& key, bool delete_marker, - const string& marker_version_id, int ret) = 0; - virtual void end_response() = 0; - const string name() override { return "multi_object_delete"; } - RGWOpType get_type() override { return RGW_OP_DELETE_MULTI_OBJ; } - uint32_t op_mask() override { return RGW_OP_TYPE_DELETE; } -}; - -class RGWInfo: public RGWOp { -public: - RGWInfo() = default; - ~RGWInfo() override = default; - - int verify_permission() override { return 0; } - const string name() override { return "get info"; } - RGWOpType get_type() override { return RGW_OP_GET_INFO; } - uint32_t op_mask() override { return RGW_OP_TYPE_READ; } -}; - -extern int rgw_build_bucket_policies(RGWRados* store, struct req_state* s); -extern int rgw_build_object_policies(RGWRados *store, struct req_state *s, - bool prefetch_data); -extern rgw::IAM::Environment rgw_build_iam_environment(RGWRados* store, - struct req_state* s); - -static inline int put_data_and_throttle(RGWPutObjDataProcessor *processor, - bufferlist& data, off_t ofs, - bool need_to_wait) -{ - bool again = false; - do { - void *handle = nullptr; - rgw_raw_obj obj; - - uint64_t size = data.length(); - - int ret = processor->handle_data(data, ofs, &handle, &obj, &again); - if (ret < 0) - return ret; - if (handle != nullptr) - { - ret = processor->throttle_data(handle, obj, size, need_to_wait); - if (ret < 0) - return ret; - } - else - break; - need_to_wait = false; /* the need to wait only applies to the first - * iteration */ - } while (again); - - return 0; -} /* put_data_and_throttle */ - - - - - -static inline int get_system_versioning_params(req_state *s, - uint64_t *olh_epoch, - string *version_id) -{ - if (!s->system_request) { - return 0; - } - - if (olh_epoch) { - string epoch_str = s->info.args.get(RGW_SYS_PARAM_PREFIX "versioned-epoch"); - if (!epoch_str.empty()) { - string err; - *olh_epoch = strict_strtol(epoch_str.c_str(), 10, &err); - if (!err.empty()) { - lsubdout(s->cct, rgw, 0) << "failed to parse versioned-epoch param" - << dendl; - return -EINVAL; - } - } - } - - if (version_id) { - *version_id = s->info.args.get(RGW_SYS_PARAM_PREFIX "version-id"); - } - - return 0; -} /* get_system_versioning_params */ - -static inline void format_xattr(std::string &xattr) -{ - /* If the extended attribute is not valid UTF-8, we encode it using - * quoted-printable encoding. - */ - if ((check_utf8(xattr.c_str(), xattr.length()) != 0) || - (check_for_control_characters(xattr.c_str(), xattr.length()) != 0)) { - static const char MIME_PREFIX_STR[] = "=?UTF-8?Q?"; - static const int MIME_PREFIX_LEN = sizeof(MIME_PREFIX_STR) - 1; - static const char MIME_SUFFIX_STR[] = "?="; - static const int MIME_SUFFIX_LEN = sizeof(MIME_SUFFIX_STR) - 1; - int mlen = mime_encode_as_qp(xattr.c_str(), NULL, 0); - char *mime = new char[MIME_PREFIX_LEN + mlen + MIME_SUFFIX_LEN + 1]; - strcpy(mime, MIME_PREFIX_STR); - mime_encode_as_qp(xattr.c_str(), mime + MIME_PREFIX_LEN, mlen); - strcpy(mime + MIME_PREFIX_LEN + (mlen - 1), MIME_SUFFIX_STR); - xattr.assign(mime); - delete [] mime; - } -} /* format_xattr */ - -/** - * Get the HTTP request metadata out of the req_state as a - * map(, where attr_name is RGW_ATTR_PREFIX.HTTP_NAME) - * s: The request state - * attrs: will be filled up with attrs mapped as - * On success returns 0. - * On failure returns a negative error code. - * - */ -static inline int rgw_get_request_metadata(CephContext* const cct, - struct req_info& info, - std::map& attrs, - const bool allow_empty_attrs = true) -{ - static const std::set blacklisted_headers = { - "x-amz-server-side-encryption-customer-algorithm", - "x-amz-server-side-encryption-customer-key", - "x-amz-server-side-encryption-customer-key-md5" - }; - - size_t valid_meta_count = 0; - for (auto& kv : info.x_meta_map) { - const std::string& name = kv.first; - std::string& xattr = kv.second; - - if (blacklisted_headers.count(name) == 1) { - lsubdout(cct, rgw, 10) << "skipping x>> " << name << dendl; - continue; - } else if (allow_empty_attrs || !xattr.empty()) { - lsubdout(cct, rgw, 10) << "x>> " << name << ":" << xattr << dendl; - format_xattr(xattr); - - std::string attr_name(RGW_ATTR_PREFIX); - attr_name.append(name); - - /* Check roughly whether we aren't going behind the limit on attribute - * name. Passing here doesn't guarantee that an OSD will accept that - * as ObjectStore::get_max_attr_name_length() can set the limit even - * lower than the "osd_max_attr_name_len" configurable. */ - const size_t max_attr_name_len = \ - cct->_conf->get_val("rgw_max_attr_name_len"); - if (max_attr_name_len && attr_name.length() > max_attr_name_len) { - return -ENAMETOOLONG; - } - - /* Similar remarks apply to the check for value size. We're veryfing - * it early at the RGW's side as it's being claimed in /info. */ - const size_t max_attr_size = \ - cct->_conf->get_val("rgw_max_attr_size"); - if (max_attr_size && xattr.length() > max_attr_size) { - return -EFBIG; - } - - /* Swift allows administrators to limit the number of metadats items - * send _in a single request_. */ - const auto rgw_max_attrs_num_in_req = \ - cct->_conf->get_val("rgw_max_attrs_num_in_req"); - if (rgw_max_attrs_num_in_req && - ++valid_meta_count > rgw_max_attrs_num_in_req) { - return -E2BIG; - } - - auto rval = attrs.emplace(std::move(attr_name), ceph::bufferlist()); - /* At the moment the value of the freshly created attribute key-value - * pair is an empty bufferlist. */ - - ceph::bufferlist& bl = rval.first->second; - bl.append(xattr.c_str(), xattr.size() + 1); - } - } - - return 0; -} /* rgw_get_request_metadata */ - -static inline void encode_delete_at_attr(boost::optional delete_at, - map& attrs) -{ - if (delete_at == boost::none) { - return; - } - - bufferlist delatbl; - ::encode(*delete_at, delatbl); - attrs[RGW_ATTR_DELETE_AT] = delatbl; -} /* encode_delete_at_attr */ - -static inline void encode_obj_tags_attr(RGWObjTags* obj_tags, map& attrs) -{ - if (obj_tags == nullptr){ - // we assume the user submitted a tag format which we couldn't parse since - // this wouldn't be parsed later by get/put obj tags, lets delete if the - // attr was populated - return; - } - - bufferlist tagsbl; - obj_tags->encode(tagsbl); - attrs[RGW_ATTR_TAGS] = tagsbl; -} - -static inline int encode_dlo_manifest_attr(const char * const dlo_manifest, - map& attrs) -{ - string dm = dlo_manifest; - - if (dm.find('/') == string::npos) { - return -EINVAL; - } - - bufferlist manifest_bl; - manifest_bl.append(dlo_manifest, strlen(dlo_manifest) + 1); - attrs[RGW_ATTR_USER_MANIFEST] = manifest_bl; - - return 0; -} /* encode_dlo_manifest_attr */ - -static inline void complete_etag(MD5& hash, string *etag) -{ - char etag_buf[CEPH_CRYPTO_MD5_DIGESTSIZE]; - char etag_buf_str[CEPH_CRYPTO_MD5_DIGESTSIZE * 2 + 16]; - - hash.Final((byte *)etag_buf); - buf_to_hex((const unsigned char *)etag_buf, CEPH_CRYPTO_MD5_DIGESTSIZE, - etag_buf_str); - - *etag = etag_buf_str; -} /* complete_etag */ - -class RGWSetAttrs : public RGWOp { -protected: - map attrs; - -public: - RGWSetAttrs() {} - ~RGWSetAttrs() override {} - - void emplace_attr(std::string&& key, buffer::list&& bl) { - attrs.emplace(std::move(key), std::move(bl)); - } - - int verify_permission() override; - void pre_exec() override; - void execute() override; - - virtual int get_params() = 0; - void send_response() override = 0; - const string name() override { return "set_attrs"; } - RGWOpType get_type() override { return RGW_OP_SET_ATTRS; } - uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; } -}; - -class RGWGetObjLayout : public RGWOp { -protected: - RGWObjManifest *manifest{nullptr}; - rgw_raw_obj head_obj; - -public: - RGWGetObjLayout() { - } - - int check_caps(RGWUserCaps& caps) { - return caps.check_cap("admin", RGW_CAP_READ); - } - int verify_permission() { - return check_caps(s->user->caps); - } - void pre_exec(); - void execute(); - - virtual void send_response() = 0; - virtual const string name() { return "get_obj_layout"; } - virtual RGWOpType get_type() { return RGW_OP_GET_OBJ_LAYOUT; } - virtual uint32_t op_mask() { return RGW_OP_TYPE_READ; } -}; - -class RGWPutBucketPolicy : public RGWOp { - int len; - char *data = nullptr; -public: - RGWPutBucketPolicy() = default; - ~RGWPutBucketPolicy() { - if (data) { - free(static_cast(data)); - } - } - void send_response() override; - int verify_permission() override; - uint32_t op_mask() override { - return RGW_OP_TYPE_WRITE; - } - void execute() override; - int get_params(); - const std::string name() override { - return "put_bucket_policy"; - } - RGWOpType get_type() override { - return RGW_OP_PUT_BUCKET_POLICY; - } -}; - -class RGWGetBucketPolicy : public RGWOp { - buffer::list policy; -public: - RGWGetBucketPolicy() = default; - void send_response() override; - int verify_permission() override; - uint32_t op_mask() override { - return RGW_OP_TYPE_READ; - } - void execute() override; - const std::string name() override { - return "get_bucket_policy"; - } - RGWOpType get_type() override { - return RGW_OP_GET_BUCKET_POLICY; - } -}; - -class RGWDeleteBucketPolicy : public RGWOp { -public: - RGWDeleteBucketPolicy() = default; - void send_response() override; - int verify_permission() override; - uint32_t op_mask() override { - return RGW_OP_TYPE_WRITE; - } - void execute() override; - int get_params(); - const std::string name() override { - return "delete_bucket_policy"; - } - RGWOpType get_type() override { - return RGW_OP_DELETE_BUCKET_POLICY; - } -}; - - -class RGWConfigBucketMetaSearch : public RGWOp { -protected: - std::map mdsearch_config; -public: - RGWConfigBucketMetaSearch() {} - - int verify_permission(); - void pre_exec(); - void execute(); - - virtual int get_params() = 0; - virtual void send_response() = 0; - virtual const string name() { return "config_bucket_meta_search"; } - virtual RGWOpType get_type() { return RGW_OP_CONFIG_BUCKET_META_SEARCH; } - virtual uint32_t op_mask() { return RGW_OP_TYPE_WRITE; } -}; - -class RGWGetBucketMetaSearch : public RGWOp { -public: - RGWGetBucketMetaSearch() {} - - int verify_permission(); - void pre_exec(); - void execute() {} - - virtual void send_response() = 0; - virtual const string name() { return "get_bucket_meta_search"; } - virtual RGWOpType get_type() { return RGW_OP_GET_BUCKET_META_SEARCH; } - virtual uint32_t op_mask() { return RGW_OP_TYPE_READ; } -}; - -class RGWDelBucketMetaSearch : public RGWOp { -public: - RGWDelBucketMetaSearch() {} - - int verify_permission(); - void pre_exec(); - void execute(); - - virtual void send_response() = 0; - virtual const string name() { return "delete_bucket_meta_search"; } - virtual RGWOpType delete_type() { return RGW_OP_DEL_BUCKET_META_SEARCH; } - virtual uint32_t op_mask() { return RGW_OP_TYPE_WRITE; } -}; - -#endif /* CEPH_RGW_OP_H */