1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
5 * All operations via the rados gateway are carried out by
6 * small classes known as RGWOps. This class contains a req_state
7 * and each possible command is a subclass of this with a defined
8 * execute() method that does whatever the subclass name implies.
9 * These subclasses must be further subclassed (by interface type)
10 * to provide additional virtual methods such as send_response or get_params.
25 #include <boost/optional.hpp>
26 #include <boost/utility/in_place_factory.hpp>
27 #include <boost/function.hpp>
29 #include "common/armor.h"
30 #include "common/mime.h"
31 #include "common/utf8.h"
32 #include "common/ceph_json.h"
33 #include "common/ceph_time.h"
35 #include "rgw_common.h"
36 #include "rgw_dmclock.h"
37 #include "rgw_rados.h"
39 #include "rgw_bucket.h"
42 #include "rgw_quota.h"
43 #include "rgw_putobj.h"
46 #include "rgw_torrent.h"
48 #include "cls/lock/cls_lock_client.h"
49 #include "cls/rgw/cls_rgw_client.h"
51 #include "services/svc_sys_obj.h"
53 #include "include/ceph_assert.h"
55 using ceph::crypto::SHA1
;
65 class StrategyRegistry
;
71 int rgw_op_get_bucket_policy_from_attr(CephContext
*cct
,
73 RGWBucketInfo
& bucket_info
,
74 map
<string
, bufferlist
>& bucket_attrs
,
75 RGWAccessControlPolicy
*policy
);
82 int do_init_permissions();
83 int do_read_permissions(RGWOp
* op
, bool only_bucket
);
90 virtual ~RGWHandler();
92 virtual int init(RGWRados
* store
,
94 rgw::io::BasicClient
* cio
);
96 virtual int init_permissions(RGWOp
*) {
100 virtual int retarget(RGWOp
* op
, RGWOp
** new_op
) {
105 virtual int read_permissions(RGWOp
* op
) = 0;
106 virtual int authorize(const DoutPrefixProvider
* dpp
) = 0;
107 virtual int postauth_init() = 0;
108 virtual int error_handler(int err_no
, std::string
* error_content
);
109 virtual void dump(const string
& code
, const string
& message
) const {}
111 virtual bool supports_quota() {
118 void rgw_bucket_object_pre_exec(struct req_state
*s
);
120 namespace dmc
= rgw::dmclock
;
123 * Provide the base class for all ops.
125 class RGWOp
: public DoutPrefixProvider
{
128 RGWHandler
*dialect_handler
;
130 RGWCORSConfiguration bucket_cors
;
132 RGWQuotaInfo bucket_quota
;
133 RGWQuotaInfo user_quota
;
135 int do_aws4_auth_completion();
137 virtual int init_quota();
142 dialect_handler(nullptr),
148 virtual ~RGWOp() = default;
150 int get_ret() const { return op_ret
; }
152 virtual int init_processing() {
153 if (dialect_handler
->supports_quota()) {
154 op_ret
= init_quota();
162 virtual void init(RGWRados
*store
, struct req_state
*s
, RGWHandler
*dialect_handler
) {
165 this->dialect_handler
= dialect_handler
;
167 int read_bucket_cors();
168 bool generate_cors_headers(string
& origin
, string
& method
, string
& headers
, string
& exp_headers
, unsigned *max_age
);
170 virtual int verify_params() { return 0; }
171 virtual bool prefetch_data() { return false; }
173 /* Authenticate requester -- verify its identity.
175 * NOTE: typically the procedure is common across all operations of the same
176 * dialect (S3, Swift API). However, there are significant exceptions in
177 * both APIs: browser uploads, /info and OPTIONS handlers. All of them use
178 * different, specific authentication schema driving the need for per-op
179 * authentication. The alternative is to duplicate parts of the method-
180 * dispatch logic in RGWHandler::authorize() and pollute it with a lot
181 * of special cases. */
182 virtual int verify_requester(const rgw::auth::StrategyRegistry
& auth_registry
) {
183 /* TODO(rzarzynski): rename RGWHandler::authorize to generic_authenticate. */
184 return dialect_handler
->authorize(this);
186 virtual int verify_permission() = 0;
187 virtual int verify_op_mask();
188 virtual void pre_exec() {}
189 virtual void execute() = 0;
190 virtual void send_response() {}
191 virtual void complete() {
194 virtual const char* name() const = 0;
195 virtual RGWOpType
get_type() { return RGW_OP_UNKNOWN
; }
197 virtual uint32_t op_mask() { return 0; }
199 virtual int error_handler(int err_no
, string
*error_content
);
201 // implements DoutPrefixProvider
202 std::ostream
& gen_prefix(std::ostream
& out
) const override
;
203 CephContext
* get_cct() const override
{ return s
->cct
; }
204 unsigned get_subsys() const override
{ return ceph_subsys_rgw
; }
206 virtual dmc::client_id
dmclock_client() { return dmc::client_id::metadata
; }
207 virtual dmc::Cost
dmclock_cost() { return 1; }
210 class RGWDefaultResponseOp
: public RGWOp
{
212 void send_response() override
;
215 class RGWGetObj_Filter
: public RGWGetDataCB
218 RGWGetObj_Filter
*next
{nullptr};
220 RGWGetObj_Filter() {}
221 explicit RGWGetObj_Filter(RGWGetObj_Filter
*next
): next(next
) {}
222 ~RGWGetObj_Filter() override
{}
224 * Passes data through filter.
225 * Filter can modify content of bl.
226 * When bl_len == 0 , it means 'flush
228 int handle_data(bufferlist
& bl
, off_t bl_ofs
, off_t bl_len
) override
{
230 return next
->handle_data(bl
, bl_ofs
, bl_len
);
235 * Flushes any cached data. Used by RGWGetObjFilter.
236 * Return logic same as handle_data.
238 virtual int flush() {
240 return next
->flush();
245 * Allows filter to extend range required for successful filtering
247 virtual int fixup_range(off_t
& ofs
, off_t
& end
) {
249 return next
->fixup_range(ofs
, end
);
255 class RGWGetObj
: public RGWOp
{
257 seed torrent
; // get torrent
258 const char *range_str
;
260 const char *if_unmod
;
261 const char *if_match
;
262 const char *if_nomatch
;
263 uint32_t mod_zone_id
;
269 ceph::real_time mod_time
;
270 ceph::real_time lastmod
;
271 ceph::real_time unmod_time
;
272 ceph::real_time
*mod_ptr
;
273 ceph::real_time
*unmod_ptr
;
274 map
<string
, bufferlist
> attrs
;
276 bool partial_content
;
277 bool ignore_invalid_range
;
280 bool skip_decrypt
{false};
282 utime_t gc_invalidate_time
;
285 bool rgwx_stat
; /* extended rgw stat operation */
289 RGWCompressionInfo cs_info
;
290 off_t first_block
, last_block
;
314 partial_content
= false;
315 range_parsed
= false;
316 skip_manifest
= false;
326 bool prefetch_data() override
;
328 void set_get_data(bool get_data
) {
329 this->get_data
= get_data
;
332 int verify_permission() override
;
333 void pre_exec() override
;
334 void execute() override
;
336 int read_user_manifest_part(
338 const rgw_bucket_dir_entry
& ent
,
339 RGWAccessControlPolicy
* const bucket_acl
,
340 const boost::optional
<rgw::IAM::Policy
>& bucket_policy
,
341 const off_t start_ofs
,
344 int handle_user_manifest(const char *prefix
);
345 int handle_slo_manifest(bufferlist
& bl
);
347 int get_data_cb(bufferlist
& bl
, off_t ofs
, off_t len
);
349 virtual int get_params() = 0;
350 virtual int send_response_data_error() = 0;
351 virtual int send_response_data(bufferlist
& bl
, off_t ofs
, off_t len
) = 0;
353 const char* name() const override
{ return "get_obj"; }
354 RGWOpType
get_type() override
{ return RGW_OP_GET_OBJ
; }
355 uint32_t op_mask() override
{ return RGW_OP_TYPE_READ
; }
356 virtual bool need_object_expiration() { return false; }
358 * calculates filter used to decrypt RGW objects data
360 virtual int get_decrypt_filter(std::unique_ptr
<RGWGetObj_Filter
>* filter
, RGWGetObj_Filter
* cb
, bufferlist
* manifest_bl
) {
364 dmc::client_id
dmclock_client() override
{ return dmc::client_id::data
; }
367 class RGWGetObj_CB
: public RGWGetObj_Filter
371 explicit RGWGetObj_CB(RGWGetObj
*_op
) : op(_op
) {}
372 ~RGWGetObj_CB() override
{}
374 int handle_data(bufferlist
& bl
, off_t bl_ofs
, off_t bl_len
) override
{
375 return op
->get_data_cb(bl
, bl_ofs
, bl_len
);
379 class RGWGetObjTags
: public RGWOp
{
382 bool has_tags
{false};
384 int verify_permission() override
;
385 void execute() override
;
386 void pre_exec() override
;
388 virtual void send_response_data(bufferlist
& bl
) = 0;
389 const char* name() const override
{ return "get_obj_tags"; }
390 virtual uint32_t op_mask() override
{ return RGW_OP_TYPE_READ
; }
391 RGWOpType
get_type() override
{ return RGW_OP_GET_OBJ_TAGGING
; }
395 class RGWPutObjTags
: public RGWOp
{
399 int verify_permission() override
;
400 void execute() override
;
402 virtual void send_response() override
= 0;
403 virtual int get_params() = 0;
404 const char* name() const override
{ return "put_obj_tags"; }
405 virtual uint32_t op_mask() override
{ return RGW_OP_TYPE_WRITE
; }
406 RGWOpType
get_type() override
{ return RGW_OP_PUT_OBJ_TAGGING
; }
410 class RGWDeleteObjTags
: public RGWOp
{
412 void pre_exec() override
;
413 int verify_permission() override
;
414 void execute() override
;
416 const char* name() const override
{ return "delete_obj_tags"; }
417 virtual uint32_t op_mask() override
{ return RGW_OP_TYPE_DELETE
; }
418 RGWOpType
get_type() override
{ return RGW_OP_DELETE_OBJ_TAGGING
;}
421 class RGWBulkDelete
: public RGWOp
{
424 std::string bucket_name
;
435 const DoutPrefixProvider
* dpp
;
436 unsigned int num_deleted
;
437 unsigned int num_unfound
;
438 std::list
<fail_desc_t
> failures
;
440 RGWRados
* const store
;
444 Deleter(const DoutPrefixProvider
* dpp
, RGWRados
* const str
, req_state
* const s
)
452 unsigned int get_num_deleted() const {
456 unsigned int get_num_unfound() const {
460 const std::list
<fail_desc_t
> get_failures() const {
464 bool verify_permission(RGWBucketInfo
& binfo
,
465 map
<string
, bufferlist
>& battrs
,
466 ACLOwner
& bucket_owner
/* out */);
467 bool delete_single(const acct_path_t
& path
);
468 bool delete_chunk(const std::list
<acct_path_t
>& paths
);
470 /* End of Deleter subclass */
472 static const size_t MAX_CHUNK_ENTRIES
= 1024;
475 std::unique_ptr
<Deleter
> deleter
;
482 int verify_permission() override
;
483 void pre_exec() override
;
484 void execute() override
;
486 virtual int get_data(std::list
<acct_path_t
>& items
,
487 bool * is_truncated
) = 0;
488 void send_response() override
= 0;
490 const char* name() const override
{ return "bulk_delete"; }
491 RGWOpType
get_type() override
{ return RGW_OP_BULK_DELETE
; }
492 uint32_t op_mask() override
{ return RGW_OP_TYPE_DELETE
; }
493 dmc::client_id
dmclock_client() override
{ return dmc::client_id::data
; }
496 inline ostream
& operator<<(ostream
& out
, const RGWBulkDelete::acct_path_t
&o
) {
497 return out
<< o
.bucket_name
<< "/" << o
.obj_key
;
501 class RGWBulkUploadOp
: public RGWOp
{
502 boost::optional
<RGWSysObjectCtx
> dir_ctx
;
507 fail_desc_t(const int err
, std::string path
)
509 path(std::move(path
)) {
513 const std::string path
;
516 static constexpr std::array
<int, 2> terminal_errors
= {
520 /* FIXME: boost::container::small_vector<fail_desc_t, 4> failures; */
521 std::vector
<fail_desc_t
> failures
;
525 class DecoratedStreamGetter
;
526 class AlignedStreamGetter
;
528 virtual std::unique_ptr
<StreamGetter
> create_stream() = 0;
529 virtual void send_response() override
= 0;
531 boost::optional
<std::pair
<std::string
, rgw_obj_key
>>
532 parse_path(const boost::string_ref
& path
);
534 std::pair
<std::string
, std::string
>
535 handle_upload_path(struct req_state
*s
);
537 bool handle_file_verify_permission(RGWBucketInfo
& binfo
,
539 std::map
<std::string
, ceph::bufferlist
>& battrs
,
540 ACLOwner
& bucket_owner
/* out */);
541 int handle_file(boost::string_ref path
,
543 AlignedStreamGetter
& body
);
545 int handle_dir_verify_permission();
546 int handle_dir(boost::string_ref path
);
553 void init(RGWRados
* const store
,
554 struct req_state
* const s
,
555 RGWHandler
* const h
) override
;
557 int verify_permission() override
;
558 void pre_exec() override
;
559 void execute() override
;
561 const char* name() const override
{ return "bulk_upload"; }
563 RGWOpType
get_type() override
{
564 return RGW_OP_BULK_UPLOAD
;
567 uint32_t op_mask() override
{
568 return RGW_OP_TYPE_WRITE
;
570 dmc::client_id
dmclock_client() override
{ return dmc::client_id::data
; }
571 }; /* RGWBulkUploadOp */
574 class RGWBulkUploadOp::StreamGetter
{
576 StreamGetter() = default;
577 virtual ~StreamGetter() = default;
579 virtual ssize_t
get_at_most(size_t want
, ceph::bufferlist
& dst
) = 0;
580 virtual ssize_t
get_exactly(size_t want
, ceph::bufferlist
& dst
) = 0;
581 }; /* End of nested subclass StreamGetter */
584 class RGWBulkUploadOp::DecoratedStreamGetter
: public StreamGetter
{
585 StreamGetter
& decoratee
;
588 StreamGetter
& get_decoratee() {
593 explicit DecoratedStreamGetter(StreamGetter
& decoratee
)
594 : decoratee(decoratee
) {
596 virtual ~DecoratedStreamGetter() = default;
598 ssize_t
get_at_most(const size_t want
, ceph::bufferlist
& dst
) override
{
599 return get_decoratee().get_at_most(want
, dst
);
602 ssize_t
get_exactly(const size_t want
, ceph::bufferlist
& dst
) override
{
603 return get_decoratee().get_exactly(want
, dst
);
605 }; /* RGWBulkUploadOp::DecoratedStreamGetter */
608 class RGWBulkUploadOp::AlignedStreamGetter
609 : public RGWBulkUploadOp::DecoratedStreamGetter
{
615 template <typename U
>
616 AlignedStreamGetter(const size_t position
,
618 const size_t alignment
,
620 : DecoratedStreamGetter(std::forward
<U
>(decoratee
)),
623 alignment(alignment
) {
625 virtual ~AlignedStreamGetter();
626 ssize_t
get_at_most(size_t want
, ceph::bufferlist
& dst
) override
;
627 ssize_t
get_exactly(size_t want
, ceph::bufferlist
& dst
) override
;
628 }; /* RGWBulkUploadOp::AlignedStreamGetter */
631 struct RGWUsageStats
{
632 uint64_t bytes_used
= 0;
633 uint64_t bytes_used_rounded
= 0;
634 uint64_t buckets_count
= 0;
635 uint64_t objects_count
= 0;
638 #define RGW_LIST_BUCKETS_LIMIT_MAX 10000
640 class RGWListBuckets
: public RGWOp
{
644 std::string end_marker
;
647 std::map
<std::string
, ceph::bufferlist
> attrs
;
650 RGWUsageStats global_stats
;
651 std::map
<std::string
, RGWUsageStats
> policies_stats
;
653 virtual uint64_t get_default_max() const {
660 limit(RGW_LIST_BUCKETS_LIMIT_MAX
),
661 limit_max(RGW_LIST_BUCKETS_LIMIT_MAX
),
662 is_truncated(false) {
665 int verify_permission() override
;
666 void execute() override
;
668 virtual int get_params() = 0;
669 virtual void handle_listing_chunk(RGWUserBuckets
&& buckets
) {
670 /* The default implementation, used by e.g. S3, just generates a new
671 * part of listing and sends it client immediately. Swift can behave
672 * differently: when the reverse option is requested, all incoming
673 * instances of RGWUserBuckets are buffered and finally reversed. */
674 return send_response_data(buckets
);
676 virtual void send_response_begin(bool has_buckets
) = 0;
677 virtual void send_response_data(RGWUserBuckets
& buckets
) = 0;
678 virtual void send_response_end() = 0;
679 void send_response() override
{}
681 virtual bool should_get_stats() { return false; }
682 virtual bool supports_account_metadata() { return false; }
684 const char* name() const override
{ return "list_buckets"; }
685 RGWOpType
get_type() override
{ return RGW_OP_LIST_BUCKETS
; }
686 uint32_t op_mask() override
{ return RGW_OP_TYPE_READ
; }
687 }; // class RGWListBuckets
689 class RGWGetUsage
: public RGWOp
{
694 int show_log_entries
;
696 map
<string
, bool> categories
;
697 map
<rgw_user_bucket
, rgw_usage_log_entry
> usage
;
698 map
<string
, rgw_usage_log_entry
> summary_map
;
699 map
<string
, cls_user_bucket_entry
> buckets_usage
;
700 cls_user_header header
;
702 RGWGetUsage() : sent_data(false), show_log_entries(true), show_log_sum(true){
705 int verify_permission() override
;
706 void execute() override
;
708 virtual int get_params() = 0;
709 void send_response() override
{}
711 virtual bool should_get_stats() { return false; }
713 const char* name() const override
{ return "get_usage"; }
714 uint32_t op_mask() override
{ return RGW_OP_TYPE_READ
; }
717 class RGWStatAccount
: public RGWOp
{
719 RGWUsageStats global_stats
;
720 std::map
<std::string
, RGWUsageStats
> policies_stats
;
723 RGWStatAccount() = default;
725 int verify_permission() override
;
726 void execute() override
;
728 void send_response() override
= 0;
729 const char* name() const override
{ return "stat_account"; }
730 RGWOpType
get_type() override
{ return RGW_OP_STAT_ACCOUNT
; }
731 uint32_t op_mask() override
{ return RGW_OP_TYPE_READ
; }
734 class RGWListBucket
: public RGWOp
{
739 rgw_obj_key next_marker
;
740 rgw_obj_key end_marker
;
743 string encoding_type
;
746 vector
<rgw_bucket_dir_entry
> objs
;
747 map
<string
, bool> common_prefixes
;
751 bool allow_unordered
;
755 int parse_max_keys();
758 RGWListBucket() : list_versions(false), max(0),
759 default_max(0), is_truncated(false),
760 allow_unordered(false), shard_id(-1) {}
761 int verify_permission() override
;
762 void pre_exec() override
;
763 void execute() override
;
765 virtual int get_params() = 0;
766 void send_response() override
= 0;
767 const char* name() const override
{ return "list_bucket"; }
768 RGWOpType
get_type() override
{ return RGW_OP_LIST_BUCKET
; }
769 uint32_t op_mask() override
{ return RGW_OP_TYPE_READ
; }
770 virtual bool need_container_stats() { return false; }
773 class RGWGetBucketLogging
: public RGWOp
{
775 RGWGetBucketLogging() {}
776 int verify_permission() override
;
777 void execute() override
{ }
779 void send_response() override
= 0;
780 const char* name() const override
{ return "get_bucket_logging"; }
781 RGWOpType
get_type() override
{ return RGW_OP_GET_BUCKET_LOGGING
; }
782 uint32_t op_mask() override
{ return RGW_OP_TYPE_READ
; }
785 class RGWGetBucketLocation
: public RGWOp
{
787 RGWGetBucketLocation() {}
788 ~RGWGetBucketLocation() override
{}
789 int verify_permission() override
;
790 void execute() override
{ }
792 void send_response() override
= 0;
793 const char* name() const override
{ return "get_bucket_location"; }
794 RGWOpType
get_type() override
{ return RGW_OP_GET_BUCKET_LOCATION
; }
795 uint32_t op_mask() override
{ return RGW_OP_TYPE_READ
; }
798 class RGWGetBucketVersioning
: public RGWOp
{
800 bool versioned
{false};
801 bool versioning_enabled
{false};
802 bool mfa_enabled
{false};
804 RGWGetBucketVersioning() = default;
806 int verify_permission() override
;
807 void pre_exec() override
;
808 void execute() override
;
810 void send_response() override
= 0;
811 const char* name() const override
{ return "get_bucket_versioning"; }
812 RGWOpType
get_type() override
{ return RGW_OP_GET_BUCKET_VERSIONING
; }
813 uint32_t op_mask() override
{ return RGW_OP_TYPE_READ
; }
816 enum BucketVersionStatus
{
817 VersioningStatusInvalid
= -1,
818 VersioningNotChanged
= 0,
819 VersioningEnabled
= 1,
820 VersioningSuspended
=2,
823 class RGWSetBucketVersioning
: public RGWOp
{
825 int versioning_status
;
826 bool mfa_set_status
{false};
827 bool mfa_status
{false};
830 RGWSetBucketVersioning() : versioning_status(VersioningNotChanged
) {}
832 int verify_permission() override
;
833 void pre_exec() override
;
834 void execute() override
;
836 virtual int get_params() { return 0; }
838 void send_response() override
= 0;
839 const char* name() const override
{ return "set_bucket_versioning"; }
840 RGWOpType
get_type() override
{ return RGW_OP_SET_BUCKET_VERSIONING
; }
841 uint32_t op_mask() override
{ return RGW_OP_TYPE_WRITE
; }
844 class RGWGetBucketWebsite
: public RGWOp
{
846 RGWGetBucketWebsite() {}
848 int verify_permission() override
;
849 void pre_exec() override
;
850 void execute() override
;
852 void send_response() override
= 0;
853 const char* name() const override
{ return "get_bucket_website"; }
854 RGWOpType
get_type() override
{ return RGW_OP_GET_BUCKET_WEBSITE
; }
855 uint32_t op_mask() override
{ return RGW_OP_TYPE_READ
; }
858 class RGWSetBucketWebsite
: public RGWOp
{
861 RGWBucketWebsiteConf website_conf
;
863 RGWSetBucketWebsite() {}
865 int verify_permission() override
;
866 void pre_exec() override
;
867 void execute() override
;
869 virtual int get_params() { return 0; }
871 void send_response() override
= 0;
872 const char* name() const override
{ return "set_bucket_website"; }
873 RGWOpType
get_type() override
{ return RGW_OP_SET_BUCKET_WEBSITE
; }
874 uint32_t op_mask() override
{ return RGW_OP_TYPE_WRITE
; }
877 class RGWDeleteBucketWebsite
: public RGWOp
{
879 RGWDeleteBucketWebsite() {}
881 int verify_permission() override
;
882 void pre_exec() override
;
883 void execute() override
;
885 void send_response() override
= 0;
886 const char* name() const override
{ return "delete_bucket_website"; }
887 RGWOpType
get_type() override
{ return RGW_OP_SET_BUCKET_WEBSITE
; }
888 uint32_t op_mask() override
{ return RGW_OP_TYPE_WRITE
; }
891 class RGWStatBucket
: public RGWOp
{
897 ~RGWStatBucket() override
{}
899 int verify_permission() override
;
900 void pre_exec() override
;
901 void execute() override
;
903 void send_response() override
= 0;
904 const char* name() const override
{ return "stat_bucket"; }
905 RGWOpType
get_type() override
{ return RGW_OP_STAT_BUCKET
; }
906 uint32_t op_mask() override
{ return RGW_OP_TYPE_READ
; }
909 class RGWCreateBucket
: public RGWOp
{
911 RGWAccessControlPolicy policy
;
912 string location_constraint
;
913 rgw_placement_rule placement_rule
;
917 bool relaxed_region_enforcement
;
918 RGWCORSConfiguration cors_config
;
919 boost::optional
<std::string
> swift_ver_location
;
920 map
<string
, buffer::list
> attrs
;
921 set
<string
> rmattr_names
;
925 virtual bool need_metadata_upload() const { return false; }
928 RGWCreateBucket() : has_cors(false), relaxed_region_enforcement(false) {}
930 void emplace_attr(std::string
&& key
, buffer::list
&& bl
) {
931 attrs
.emplace(std::move(key
), std::move(bl
)); /* key and bl are r-value refs */
934 int verify_permission() override
;
935 void pre_exec() override
;
936 void execute() override
;
937 void init(RGWRados
*store
, struct req_state
*s
, RGWHandler
*h
) override
{
938 RGWOp::init(store
, s
, h
);
939 policy
.set_ctx(s
->cct
);
940 relaxed_region_enforcement
=
941 s
->cct
->_conf
.get_val
<bool>("rgw_relaxed_region_enforcement");
943 virtual int get_params() { return 0; }
944 void send_response() override
= 0;
945 const char* name() const override
{ return "create_bucket"; }
946 RGWOpType
get_type() override
{ return RGW_OP_CREATE_BUCKET
; }
947 uint32_t op_mask() override
{ return RGW_OP_TYPE_WRITE
; }
950 class RGWDeleteBucket
: public RGWOp
{
952 RGWObjVersionTracker objv_tracker
;
957 int verify_permission() override
;
958 void pre_exec() override
;
959 void execute() override
;
961 void send_response() override
= 0;
962 const char* name() const override
{ return "delete_bucket"; }
963 RGWOpType
get_type() override
{ return RGW_OP_DELETE_BUCKET
; }
964 uint32_t op_mask() override
{ return RGW_OP_TYPE_DELETE
; }
967 struct rgw_slo_entry
{
972 rgw_slo_entry() : size_bytes(0) {}
974 void encode(bufferlist
& bl
) const {
975 ENCODE_START(1, 1, bl
);
978 encode(size_bytes
, bl
);
982 void decode(bufferlist::const_iterator
& bl
) {
986 decode(size_bytes
, bl
);
990 void decode_json(JSONObj
*obj
);
992 WRITE_CLASS_ENCODER(rgw_slo_entry
)
995 vector
<rgw_slo_entry
> entries
;
1001 RGWSLOInfo() : total_size(0) {}
1004 void encode(bufferlist
& bl
) const {
1005 ENCODE_START(1, 1, bl
);
1006 encode(entries
, bl
);
1007 encode(total_size
, bl
);
1011 void decode(bufferlist::const_iterator
& bl
) {
1012 DECODE_START(1, bl
);
1013 decode(entries
, bl
);
1014 decode(total_size
, bl
);
1018 WRITE_CLASS_ENCODER(RGWSLOInfo
)
1020 class RGWPutObj
: public RGWOp
{
1024 const char *supplied_md5_b64
;
1025 const char *supplied_etag
;
1026 const char *if_match
;
1027 const char *if_nomatch
;
1028 std::string copy_source
;
1029 const char *copy_source_range
;
1030 RGWBucketInfo copy_source_bucket_info
;
1031 string copy_source_tenant_name
;
1032 string copy_source_bucket_name
;
1033 string copy_source_object_name
;
1034 string copy_source_version_id
;
1035 off_t copy_source_range_fst
;
1036 off_t copy_source_range_lst
;
1038 bool chunked_upload
;
1039 RGWAccessControlPolicy policy
;
1040 std::unique_ptr
<RGWObjTags
> obj_tags
;
1041 const char *dlo_manifest
;
1042 RGWSLOInfo
*slo_info
;
1043 map
<string
, bufferlist
> attrs
;
1044 ceph::real_time mtime
;
1048 map
<string
, string
> crypt_http_responses
;
1051 std::string multipart_upload_id
;
1052 std::string multipart_part_str
;
1053 int multipart_part_num
= 0;
1055 boost::optional
<ceph::real_time
> delete_at
;
1059 uint64_t cur_accounted_size
;
1062 RGWPutObj() : ofs(0),
1063 supplied_md5_b64(NULL
),
1064 supplied_etag(NULL
),
1067 copy_source_range(NULL
),
1068 copy_source_range_fst(0),
1069 copy_source_range_lst(0),
1076 cur_accounted_size(0) {}
1078 ~RGWPutObj() override
{
1082 void init(RGWRados
*store
, struct req_state
*s
, RGWHandler
*h
) override
{
1083 RGWOp::init(store
, s
, h
);
1084 policy
.set_ctx(s
->cct
);
1087 void emplace_attr(std::string
&& key
, buffer::list
&& bl
) {
1088 attrs
.emplace(std::move(key
), std::move(bl
)); /* key and bl are r-value refs */
1091 int verify_permission() override
;
1092 void pre_exec() override
;
1093 void execute() override
;
1095 /* this is for cases when copying data from other object */
1096 virtual int get_decrypt_filter(std::unique_ptr
<RGWGetObj_Filter
>* filter
,
1097 RGWGetObj_Filter
* cb
,
1098 map
<string
, bufferlist
>& attrs
,
1099 bufferlist
* manifest_bl
) {
1103 virtual int get_encrypt_filter(std::unique_ptr
<rgw::putobj::DataProcessor
> *filter
,
1104 rgw::putobj::DataProcessor
*cb
) {
1108 int get_data_cb(bufferlist
& bl
, off_t bl_ofs
, off_t bl_len
);
1109 int get_data(const off_t fst
, const off_t lst
, bufferlist
& bl
);
1111 virtual int get_params() = 0;
1112 virtual int get_data(bufferlist
& bl
) = 0;
1113 void send_response() override
= 0;
1114 const char* name() const override
{ return "put_obj"; }
1115 RGWOpType
get_type() override
{ return RGW_OP_PUT_OBJ
; }
1116 uint32_t op_mask() override
{ return RGW_OP_TYPE_WRITE
; }
1117 dmc::client_id
dmclock_client() override
{ return dmc::client_id::data
; }
1120 class RGWPostObj
: public RGWOp
{
1126 const char *supplied_md5_b64
;
1127 const char *supplied_etag
;
1129 RGWAccessControlPolicy policy
;
1130 map
<string
, bufferlist
> attrs
;
1131 boost::optional
<ceph::real_time
> delete_at
;
1133 /* Must be called after get_data() or the result is undefined. */
1134 virtual std::string
get_current_filename() const = 0;
1135 virtual std::string
get_current_content_type() const = 0;
1136 virtual bool is_next_file_to_upload() {
1140 RGWPostObj() : min_len(0),
1144 supplied_md5_b64(nullptr),
1145 supplied_etag(nullptr) {
1148 void emplace_attr(std::string
&& key
, buffer::list
&& bl
) {
1149 attrs
.emplace(std::move(key
), std::move(bl
)); /* key and bl are r-value refs */
1152 void init(RGWRados
*store
, struct req_state
*s
, RGWHandler
*h
) override
{
1153 RGWOp::init(store
, s
, h
);
1154 policy
.set_ctx(s
->cct
);
1157 int verify_permission() override
;
1158 void pre_exec() override
;
1159 void execute() override
;
1161 virtual int get_encrypt_filter(std::unique_ptr
<rgw::putobj::DataProcessor
> *filter
,
1162 rgw::putobj::DataProcessor
*cb
) {
1165 virtual int get_params() = 0;
1166 virtual int get_data(ceph::bufferlist
& bl
, bool& again
) = 0;
1167 void send_response() override
= 0;
1168 const char* name() const override
{ return "post_obj"; }
1169 RGWOpType
get_type() override
{ return RGW_OP_POST_OBJ
; }
1170 uint32_t op_mask() override
{ return RGW_OP_TYPE_WRITE
; }
1171 dmc::client_id
dmclock_client() override
{ return dmc::client_id::data
; }
1174 class RGWPutMetadataAccount
: public RGWOp
{
1176 std::set
<std::string
> rmattr_names
;
1177 std::map
<std::string
, bufferlist
> attrs
, orig_attrs
;
1178 std::map
<int, std::string
> temp_url_keys
;
1179 RGWQuotaInfo new_quota
;
1180 bool new_quota_extracted
;
1182 RGWObjVersionTracker acct_op_tracker
;
1184 RGWAccessControlPolicy policy
;
1188 RGWPutMetadataAccount()
1189 : new_quota_extracted(false),
1193 void init(RGWRados
*store
, struct req_state
*s
, RGWHandler
*h
) override
{
1194 RGWOp::init(store
, s
, h
);
1195 policy
.set_ctx(s
->cct
);
1197 int init_processing() override
;
1198 int verify_permission() override
;
1199 void pre_exec() override
{ }
1200 void execute() override
;
1202 virtual int get_params() = 0;
1203 void send_response() override
= 0;
1204 virtual void filter_out_temp_url(map
<string
, bufferlist
>& add_attrs
,
1205 const set
<string
>& rmattr_names
,
1206 map
<int, string
>& temp_url_keys
);
1207 const char* name() const override
{ return "put_account_metadata"; }
1208 RGWOpType
get_type() override
{ return RGW_OP_PUT_METADATA_ACCOUNT
; }
1209 uint32_t op_mask() override
{ return RGW_OP_TYPE_WRITE
; }
1212 class RGWPutMetadataBucket
: public RGWOp
{
1214 map
<string
, buffer::list
> attrs
;
1215 set
<string
> rmattr_names
;
1216 bool has_policy
, has_cors
;
1217 uint32_t policy_rw_mask
;
1218 RGWAccessControlPolicy policy
;
1219 RGWCORSConfiguration cors_config
;
1220 rgw_placement_rule placement_rule
;
1221 boost::optional
<std::string
> swift_ver_location
;
1224 RGWPutMetadataBucket()
1225 : has_policy(false), has_cors(false), policy_rw_mask(0)
1228 void emplace_attr(std::string
&& key
, buffer::list
&& bl
) {
1229 attrs
.emplace(std::move(key
), std::move(bl
)); /* key and bl are r-value refs */
1232 void init(RGWRados
*store
, struct req_state
*s
, RGWHandler
*h
) override
{
1233 RGWOp::init(store
, s
, h
);
1234 policy
.set_ctx(s
->cct
);
1237 int verify_permission() override
;
1238 void pre_exec() override
;
1239 void execute() override
;
1241 virtual int get_params() = 0;
1242 void send_response() override
= 0;
1243 const char* name() const override
{ return "put_bucket_metadata"; }
1244 RGWOpType
get_type() override
{ return RGW_OP_PUT_METADATA_BUCKET
; }
1245 uint32_t op_mask() override
{ return RGW_OP_TYPE_WRITE
; }
1248 class RGWPutMetadataObject
: public RGWOp
{
1250 RGWAccessControlPolicy policy
;
1251 boost::optional
<ceph::real_time
> delete_at
;
1252 const char *dlo_manifest
;
1255 RGWPutMetadataObject()
1256 : dlo_manifest(NULL
)
1259 void init(RGWRados
*store
, struct req_state
*s
, RGWHandler
*h
) override
{
1260 RGWOp::init(store
, s
, h
);
1261 policy
.set_ctx(s
->cct
);
1263 int verify_permission() override
;
1264 void pre_exec() override
;
1265 void execute() override
;
1267 virtual int get_params() = 0;
1268 void send_response() override
= 0;
1269 const char* name() const override
{ return "put_obj_metadata"; }
1270 RGWOpType
get_type() override
{ return RGW_OP_PUT_METADATA_OBJECT
; }
1271 uint32_t op_mask() override
{ return RGW_OP_TYPE_WRITE
; }
1272 virtual bool need_object_expiration() { return false; }
1275 class RGWDeleteObj
: public RGWOp
{
1278 bool multipart_delete
;
1280 ceph::real_time unmod_since
; /* if unmodified since */
1281 bool no_precondition_error
;
1282 std::unique_ptr
<RGWBulkDelete::Deleter
> deleter
;
1286 : delete_marker(false),
1287 multipart_delete(false),
1288 no_precondition_error(false),
1292 int verify_permission() override
;
1293 void pre_exec() override
;
1294 void execute() override
;
1295 int handle_slo_manifest(bufferlist
& bl
);
1297 virtual int get_params() { return 0; }
1298 void send_response() override
= 0;
1299 const char* name() const override
{ return "delete_obj"; }
1300 RGWOpType
get_type() override
{ return RGW_OP_DELETE_OBJ
; }
1301 uint32_t op_mask() override
{ return RGW_OP_TYPE_DELETE
; }
1302 virtual bool need_object_expiration() { return false; }
1303 dmc::client_id
dmclock_client() override
{ return dmc::client_id::data
; }
1306 class RGWCopyObj
: public RGWOp
{
1308 RGWAccessControlPolicy dest_policy
;
1310 const char *if_unmod
;
1311 const char *if_match
;
1312 const char *if_nomatch
;
1313 const char *copy_source
= nullptr;
1314 const char *md_directive
= nullptr;
1319 ceph::real_time mod_time
;
1320 ceph::real_time unmod_time
;
1321 ceph::real_time
*mod_ptr
;
1322 ceph::real_time
*unmod_ptr
;
1323 map
<string
, buffer::list
> attrs
;
1324 string src_tenant_name
, src_bucket_name
;
1325 rgw_bucket src_bucket
;
1326 rgw_obj_key src_object
;
1327 string dest_tenant_name
, dest_bucket_name
;
1328 rgw_bucket dest_bucket
;
1330 ceph::real_time src_mtime
;
1331 ceph::real_time mtime
;
1332 RGWRados::AttrsMod attrs_mod
;
1333 RGWBucketInfo src_bucket_info
;
1334 RGWBucketInfo dest_bucket_info
;
1343 boost::optional
<ceph::real_time
> delete_at
;
1346 bool need_to_check_storage_class
= false;
1361 attrs_mod
= RGWRados::ATTRSMOD_NONE
;
1364 copy_if_newer
= false;
1367 static bool parse_copy_location(const boost::string_view
& src
,
1368 string
& bucket_name
,
1369 rgw_obj_key
& object
);
1371 void emplace_attr(std::string
&& key
, buffer::list
&& bl
) {
1372 attrs
.emplace(std::move(key
), std::move(bl
));
1375 void init(RGWRados
*store
, struct req_state
*s
, RGWHandler
*h
) override
{
1376 RGWOp::init(store
, s
, h
);
1377 dest_policy
.set_ctx(s
->cct
);
1379 int verify_permission() override
;
1380 void pre_exec() override
;
1381 void execute() override
;
1382 void progress_cb(off_t ofs
);
1384 virtual int check_storage_class(const rgw_placement_rule
& src_placement
) {
1388 virtual int init_dest_policy() { return 0; }
1389 virtual int get_params() = 0;
1390 virtual void send_partial_response(off_t ofs
) {}
1391 void send_response() override
= 0;
1392 const char* name() const override
{ return "copy_obj"; }
1393 RGWOpType
get_type() override
{ return RGW_OP_COPY_OBJ
; }
1394 uint32_t op_mask() override
{ return RGW_OP_TYPE_WRITE
; }
1395 dmc::client_id
dmclock_client() override
{ return dmc::client_id::data
; }
1398 class RGWGetACLs
: public RGWOp
{
1405 int verify_permission() override
;
1406 void pre_exec() override
;
1407 void execute() override
;
1409 void send_response() override
= 0;
1410 const char* name() const override
{ return "get_acls"; }
1411 RGWOpType
get_type() override
{ return RGW_OP_GET_ACLS
; }
1412 uint32_t op_mask() override
{ return RGW_OP_TYPE_READ
; }
1415 class RGWPutACLs
: public RGWOp
{
1422 ~RGWPutACLs() override
{}
1424 int verify_permission() override
;
1425 void pre_exec() override
;
1426 void execute() override
;
1428 virtual int get_policy_from_state(RGWRados
*store
, struct req_state
*s
, stringstream
& ss
) { return 0; }
1429 virtual int get_params() = 0;
1430 void send_response() override
= 0;
1431 const char* name() const override
{ return "put_acls"; }
1432 RGWOpType
get_type() override
{ return RGW_OP_PUT_ACLS
; }
1433 uint32_t op_mask() override
{ return RGW_OP_TYPE_WRITE
; }
1436 class RGWGetLC
: public RGWOp
{
1441 ~RGWGetLC() override
{ }
1443 int verify_permission() override
;
1444 void pre_exec() override
;
1445 void execute() override
= 0;
1447 void send_response() override
= 0;
1448 const char* name() const override
{ return "get_lifecycle"; }
1449 RGWOpType
get_type() override
{ return RGW_OP_GET_LC
; }
1450 uint32_t op_mask() override
{ return RGW_OP_TYPE_READ
; }
1453 class RGWPutLC
: public RGWOp
{
1456 const char *content_md5
;
1461 content_md5
= nullptr;
1463 ~RGWPutLC() override
{}
1465 void init(RGWRados
*store
, struct req_state
*s
, RGWHandler
*dialect_handler
) override
{
1466 #define COOKIE_LEN 16
1467 char buf
[COOKIE_LEN
+ 1];
1469 RGWOp::init(store
, s
, dialect_handler
);
1470 gen_rand_alphanumeric(s
->cct
, buf
, sizeof(buf
) - 1);
1474 int verify_permission() override
;
1475 void pre_exec() override
;
1476 void execute() override
;
1478 // virtual int get_policy_from_state(RGWRados *store, struct req_state *s, stringstream& ss) { return 0; }
1479 virtual int get_params() = 0;
1480 void send_response() override
= 0;
1481 const char* name() const override
{ return "put_lifecycle"; }
1482 RGWOpType
get_type() override
{ return RGW_OP_PUT_LC
; }
1483 uint32_t op_mask() override
{ return RGW_OP_TYPE_WRITE
; }
1486 class RGWDeleteLC
: public RGWOp
{
1496 ~RGWDeleteLC() override
{
1500 int verify_permission() override
;
1501 void pre_exec() override
;
1502 void execute() override
;
1504 void send_response() override
= 0;
1505 const char* name() const override
{ return "delete_lifecycle"; }
1506 RGWOpType
get_type() override
{ return RGW_OP_DELETE_LC
; }
1507 uint32_t op_mask() override
{ return RGW_OP_TYPE_WRITE
; }
1510 class RGWGetCORS
: public RGWOp
{
1516 int verify_permission() override
;
1517 void execute() override
;
1519 void send_response() override
= 0;
1520 const char* name() const override
{ return "get_cors"; }
1521 RGWOpType
get_type() override
{ return RGW_OP_GET_CORS
; }
1522 uint32_t op_mask() override
{ return RGW_OP_TYPE_READ
; }
1525 class RGWPutCORS
: public RGWOp
{
1532 ~RGWPutCORS() override
{}
1534 int verify_permission() override
;
1535 void execute() override
;
1537 virtual int get_params() = 0;
1538 void send_response() override
= 0;
1539 const char* name() const override
{ return "put_cors"; }
1540 RGWOpType
get_type() override
{ return RGW_OP_PUT_CORS
; }
1541 uint32_t op_mask() override
{ return RGW_OP_TYPE_WRITE
; }
1544 class RGWDeleteCORS
: public RGWOp
{
1550 int verify_permission() override
;
1551 void execute() override
;
1553 void send_response() override
= 0;
1554 const char* name() const override
{ return "delete_cors"; }
1555 RGWOpType
get_type() override
{ return RGW_OP_DELETE_CORS
; }
1556 uint32_t op_mask() override
{ return RGW_OP_TYPE_WRITE
; }
1559 class RGWOptionsCORS
: public RGWOp
{
1562 const char *origin
, *req_hdrs
, *req_meth
;
1565 RGWOptionsCORS() : rule(NULL
), origin(NULL
),
1566 req_hdrs(NULL
), req_meth(NULL
) {
1569 int verify_permission() override
{return 0;}
1570 int validate_cors_request(RGWCORSConfiguration
*cc
);
1571 void execute() override
;
1572 void get_response_params(string
& allowed_hdrs
, string
& exp_hdrs
, unsigned *max_age
);
1573 void send_response() override
= 0;
1574 const char* name() const override
{ return "options_cors"; }
1575 RGWOpType
get_type() override
{ return RGW_OP_OPTIONS_CORS
; }
1576 uint32_t op_mask() override
{ return RGW_OP_TYPE_READ
; }
1579 class RGWGetRequestPayment
: public RGWOp
{
1581 bool requester_pays
;
1584 RGWGetRequestPayment() : requester_pays(0) {}
1586 int verify_permission() override
;
1587 void pre_exec() override
;
1588 void execute() override
;
1590 void send_response() override
= 0;
1591 const char* name() const override
{ return "get_request_payment"; }
1592 RGWOpType
get_type() override
{ return RGW_OP_GET_REQUEST_PAYMENT
; }
1593 uint32_t op_mask() override
{ return RGW_OP_TYPE_READ
; }
1596 class RGWSetRequestPayment
: public RGWOp
{
1598 bool requester_pays
;
1600 RGWSetRequestPayment() : requester_pays(false) {}
1602 int verify_permission() override
;
1603 void pre_exec() override
;
1604 void execute() override
;
1606 virtual int get_params() { return 0; }
1608 void send_response() override
= 0;
1609 const char* name() const override
{ return "set_request_payment"; }
1610 RGWOpType
get_type() override
{ return RGW_OP_SET_REQUEST_PAYMENT
; }
1611 uint32_t op_mask() override
{ return RGW_OP_TYPE_WRITE
; }
1614 class RGWInitMultipart
: public RGWOp
{
1617 RGWAccessControlPolicy policy
;
1620 RGWInitMultipart() {}
1622 void init(RGWRados
*store
, struct req_state
*s
, RGWHandler
*h
) override
{
1623 RGWOp::init(store
, s
, h
);
1624 policy
.set_ctx(s
->cct
);
1626 int verify_permission() override
;
1627 void pre_exec() override
;
1628 void execute() override
;
1630 virtual int get_params() = 0;
1631 void send_response() override
= 0;
1632 const char* name() const override
{ return "init_multipart"; }
1633 RGWOpType
get_type() override
{ return RGW_OP_INIT_MULTIPART
; }
1634 uint32_t op_mask() override
{ return RGW_OP_TYPE_WRITE
; }
1635 virtual int prepare_encryption(map
<string
, bufferlist
>& attrs
) { return 0; }
1638 class RGWCompleteMultipart
: public RGWOp
{
1645 struct MPSerializer
{
1646 librados::IoCtx ioctx
;
1647 rados::cls::lock::Lock lock
;
1648 librados::ObjectWriteOperation op
;
1652 MPSerializer() : lock("RGWCompleteMultipart"), locked(false)
1655 int try_lock(const std::string
& oid
, utime_t dur
);
1658 return lock
.unlock(&ioctx
, oid
);
1661 void clear_locked() {
1667 RGWCompleteMultipart() {}
1668 ~RGWCompleteMultipart() override
{}
1670 int verify_permission() override
;
1671 void pre_exec() override
;
1672 void execute() override
;
1673 void complete() override
;
1675 virtual int get_params() = 0;
1676 void send_response() override
= 0;
1677 const char* name() const override
{ return "complete_multipart"; }
1678 RGWOpType
get_type() override
{ return RGW_OP_COMPLETE_MULTIPART
; }
1679 uint32_t op_mask() override
{ return RGW_OP_TYPE_WRITE
; }
1682 class RGWAbortMultipart
: public RGWOp
{
1684 RGWAbortMultipart() {}
1686 int verify_permission() override
;
1687 void pre_exec() override
;
1688 void execute() override
;
1690 void send_response() override
= 0;
1691 const char* name() const override
{ return "abort_multipart"; }
1692 RGWOpType
get_type() override
{ return RGW_OP_ABORT_MULTIPART
; }
1693 uint32_t op_mask() override
{ return RGW_OP_TYPE_DELETE
; }
1696 class RGWListMultipart
: public RGWOp
{
1699 map
<uint32_t, RGWUploadPartInfo
> parts
;
1702 RGWAccessControlPolicy policy
;
1706 RGWListMultipart() {
1712 void init(RGWRados
*store
, struct req_state
*s
, RGWHandler
*h
) override
{
1713 RGWOp::init(store
, s
, h
);
1714 policy
= RGWAccessControlPolicy(s
->cct
);
1716 int verify_permission() override
;
1717 void pre_exec() override
;
1718 void execute() override
;
1720 virtual int get_params() = 0;
1721 void send_response() override
= 0;
1722 const char* name() const override
{ return "list_multipart"; }
1723 RGWOpType
get_type() override
{ return RGW_OP_LIST_MULTIPART
; }
1724 uint32_t op_mask() override
{ return RGW_OP_TYPE_READ
; }
1727 struct RGWMultipartUploadEntry
{
1728 rgw_bucket_dir_entry obj
;
1732 class RGWListBucketMultiparts
: public RGWOp
{
1736 RGWMultipartUploadEntry next_marker
;
1739 vector
<RGWMultipartUploadEntry
> uploads
;
1740 map
<string
, bool> common_prefixes
;
1745 RGWListBucketMultiparts() {
1747 is_truncated
= false;
1751 void init(RGWRados
*store
, struct req_state
*s
, RGWHandler
*h
) override
{
1752 RGWOp::init(store
, s
, h
);
1753 max_uploads
= default_max
;
1756 int verify_permission() override
;
1757 void pre_exec() override
;
1758 void execute() override
;
1760 virtual int get_params() = 0;
1761 void send_response() override
= 0;
1762 const char* name() const override
{ return "list_bucket_multiparts"; }
1763 RGWOpType
get_type() override
{ return RGW_OP_LIST_BUCKET_MULTIPARTS
; }
1764 uint32_t op_mask() override
{ return RGW_OP_TYPE_READ
; }
1768 class RGWGetCrossDomainPolicy
: public RGWOp
{
1770 RGWGetCrossDomainPolicy() = default;
1771 ~RGWGetCrossDomainPolicy() override
= default;
1773 int verify_permission() override
{
1777 void execute() override
{
1781 const char* name() const override
{ return "get_crossdomain_policy"; }
1783 RGWOpType
get_type() override
{
1784 return RGW_OP_GET_CROSS_DOMAIN_POLICY
;
1787 uint32_t op_mask() override
{
1788 return RGW_OP_TYPE_READ
;
1793 class RGWGetHealthCheck
: public RGWOp
{
1795 RGWGetHealthCheck() = default;
1796 ~RGWGetHealthCheck() override
= default;
1798 int verify_permission() override
{
1802 void execute() override
;
1804 const char* name() const override
{ return "get_health_check"; }
1806 RGWOpType
get_type() override
{
1807 return RGW_OP_GET_HEALTH_CHECK
;
1810 uint32_t op_mask() override
{
1811 return RGW_OP_TYPE_READ
;
1816 class RGWDeleteMultiObj
: public RGWOp
{
1822 bool acl_allowed
= false;
1825 RGWDeleteMultiObj() {
1827 status_dumped
= false;
1829 int verify_permission() override
;
1830 void pre_exec() override
;
1831 void execute() override
;
1833 virtual int get_params() = 0;
1834 virtual void send_status() = 0;
1835 virtual void begin_response() = 0;
1836 virtual void send_partial_response(rgw_obj_key
& key
, bool delete_marker
,
1837 const string
& marker_version_id
, int ret
) = 0;
1838 virtual void end_response() = 0;
1839 const char* name() const override
{ return "multi_object_delete"; }
1840 RGWOpType
get_type() override
{ return RGW_OP_DELETE_MULTI_OBJ
; }
1841 uint32_t op_mask() override
{ return RGW_OP_TYPE_DELETE
; }
1844 class RGWInfo
: public RGWOp
{
1846 RGWInfo() = default;
1847 ~RGWInfo() override
= default;
1849 int verify_permission() override
{ return 0; }
1850 const char* name() const override
{ return "get info"; }
1851 RGWOpType
get_type() override
{ return RGW_OP_GET_INFO
; }
1852 uint32_t op_mask() override
{ return RGW_OP_TYPE_READ
; }
1855 extern int rgw_build_bucket_policies(RGWRados
* store
, struct req_state
* s
);
1856 extern int rgw_build_object_policies(RGWRados
*store
, struct req_state
*s
,
1857 bool prefetch_data
);
1858 extern void rgw_build_iam_environment(RGWRados
* store
,
1859 struct req_state
* s
);
1860 extern vector
<rgw::IAM::Policy
> get_iam_user_policy_from_attr(CephContext
* cct
,
1862 map
<string
, bufferlist
>& attrs
,
1863 const string
& tenant
);
1865 static inline int get_system_versioning_params(req_state
*s
,
1866 uint64_t *olh_epoch
,
1869 if (!s
->system_request
) {
1874 string epoch_str
= s
->info
.args
.get(RGW_SYS_PARAM_PREFIX
"versioned-epoch");
1875 if (!epoch_str
.empty()) {
1877 *olh_epoch
= strict_strtol(epoch_str
.c_str(), 10, &err
);
1879 lsubdout(s
->cct
, rgw
, 0) << "failed to parse versioned-epoch param"
1887 *version_id
= s
->info
.args
.get(RGW_SYS_PARAM_PREFIX
"version-id");
1891 } /* get_system_versioning_params */
1893 static inline void format_xattr(std::string
&xattr
)
1895 /* If the extended attribute is not valid UTF-8, we encode it using
1896 * quoted-printable encoding.
1898 if ((check_utf8(xattr
.c_str(), xattr
.length()) != 0) ||
1899 (check_for_control_characters(xattr
.c_str(), xattr
.length()) != 0)) {
1900 static const char MIME_PREFIX_STR
[] = "=?UTF-8?Q?";
1901 static const int MIME_PREFIX_LEN
= sizeof(MIME_PREFIX_STR
) - 1;
1902 static const char MIME_SUFFIX_STR
[] = "?=";
1903 static const int MIME_SUFFIX_LEN
= sizeof(MIME_SUFFIX_STR
) - 1;
1904 int mlen
= mime_encode_as_qp(xattr
.c_str(), NULL
, 0);
1905 char *mime
= new char[MIME_PREFIX_LEN
+ mlen
+ MIME_SUFFIX_LEN
+ 1];
1906 strcpy(mime
, MIME_PREFIX_STR
);
1907 mime_encode_as_qp(xattr
.c_str(), mime
+ MIME_PREFIX_LEN
, mlen
);
1908 strcpy(mime
+ MIME_PREFIX_LEN
+ (mlen
- 1), MIME_SUFFIX_STR
);
1912 } /* format_xattr */
1915 * Get the HTTP request metadata out of the req_state as a
1916 * map(<attr_name, attr_contents>, where attr_name is RGW_ATTR_PREFIX.HTTP_NAME)
1917 * s: The request state
1918 * attrs: will be filled up with attrs mapped as <attr_name, attr_contents>
1919 * On success returns 0.
1920 * On failure returns a negative error code.
1923 static inline int rgw_get_request_metadata(CephContext
* const cct
,
1924 struct req_info
& info
,
1925 std::map
<std::string
, ceph::bufferlist
>& attrs
,
1926 const bool allow_empty_attrs
= true)
1928 static const std::set
<std::string
> blacklisted_headers
= {
1929 "x-amz-server-side-encryption-customer-algorithm",
1930 "x-amz-server-side-encryption-customer-key",
1931 "x-amz-server-side-encryption-customer-key-md5",
1932 "x-amz-storage-class"
1935 size_t valid_meta_count
= 0;
1936 for (auto& kv
: info
.x_meta_map
) {
1937 const std::string
& name
= kv
.first
;
1938 std::string
& xattr
= kv
.second
;
1940 if (blacklisted_headers
.count(name
) == 1) {
1941 lsubdout(cct
, rgw
, 10) << "skipping x>> " << name
<< dendl
;
1943 } else if (allow_empty_attrs
|| !xattr
.empty()) {
1944 lsubdout(cct
, rgw
, 10) << "x>> " << name
<< ":" << xattr
<< dendl
;
1945 format_xattr(xattr
);
1947 std::string
attr_name(RGW_ATTR_PREFIX
);
1948 attr_name
.append(name
);
1950 /* Check roughly whether we aren't going behind the limit on attribute
1951 * name. Passing here doesn't guarantee that an OSD will accept that
1952 * as ObjectStore::get_max_attr_name_length() can set the limit even
1953 * lower than the "osd_max_attr_name_len" configurable. */
1954 const size_t max_attr_name_len
= \
1955 cct
->_conf
.get_val
<Option::size_t>("rgw_max_attr_name_len");
1956 if (max_attr_name_len
&& attr_name
.length() > max_attr_name_len
) {
1957 return -ENAMETOOLONG
;
1960 /* Similar remarks apply to the check for value size. We're veryfing
1961 * it early at the RGW's side as it's being claimed in /info. */
1962 const size_t max_attr_size
= \
1963 cct
->_conf
.get_val
<Option::size_t>("rgw_max_attr_size");
1964 if (max_attr_size
&& xattr
.length() > max_attr_size
) {
1968 /* Swift allows administrators to limit the number of metadats items
1969 * send _in a single request_. */
1970 const auto rgw_max_attrs_num_in_req
= \
1971 cct
->_conf
.get_val
<uint64_t>("rgw_max_attrs_num_in_req");
1972 if (rgw_max_attrs_num_in_req
&&
1973 ++valid_meta_count
> rgw_max_attrs_num_in_req
) {
1977 auto rval
= attrs
.emplace(std::move(attr_name
), ceph::bufferlist());
1978 /* At the moment the value of the freshly created attribute key-value
1979 * pair is an empty bufferlist. */
1981 ceph::bufferlist
& bl
= rval
.first
->second
;
1982 bl
.append(xattr
.c_str(), xattr
.size() + 1);
1987 } /* rgw_get_request_metadata */
1989 static inline void encode_delete_at_attr(boost::optional
<ceph::real_time
> delete_at
,
1990 map
<string
, bufferlist
>& attrs
)
1992 if (delete_at
== boost::none
) {
1997 encode(*delete_at
, delatbl
);
1998 attrs
[RGW_ATTR_DELETE_AT
] = delatbl
;
1999 } /* encode_delete_at_attr */
2001 static inline void encode_obj_tags_attr(RGWObjTags
* obj_tags
, map
<string
, bufferlist
>& attrs
)
2003 if (obj_tags
== nullptr){
2004 // we assume the user submitted a tag format which we couldn't parse since
2005 // this wouldn't be parsed later by get/put obj tags, lets delete if the
2006 // attr was populated
2011 obj_tags
->encode(tagsbl
);
2012 attrs
[RGW_ATTR_TAGS
] = tagsbl
;
2015 static inline int encode_dlo_manifest_attr(const char * const dlo_manifest
,
2016 map
<string
, bufferlist
>& attrs
)
2018 string dm
= dlo_manifest
;
2020 if (dm
.find('/') == string::npos
) {
2024 bufferlist manifest_bl
;
2025 manifest_bl
.append(dlo_manifest
, strlen(dlo_manifest
) + 1);
2026 attrs
[RGW_ATTR_USER_MANIFEST
] = manifest_bl
;
2029 } /* encode_dlo_manifest_attr */
2031 static inline void complete_etag(MD5
& hash
, string
*etag
)
2033 char etag_buf
[CEPH_CRYPTO_MD5_DIGESTSIZE
];
2034 char etag_buf_str
[CEPH_CRYPTO_MD5_DIGESTSIZE
* 2 + 16];
2036 hash
.Final((unsigned char *)etag_buf
);
2037 buf_to_hex((const unsigned char *)etag_buf
, CEPH_CRYPTO_MD5_DIGESTSIZE
,
2040 *etag
= etag_buf_str
;
2041 } /* complete_etag */
2043 class RGWSetAttrs
: public RGWOp
{
2045 map
<string
, buffer::list
> attrs
;
2049 ~RGWSetAttrs() override
{}
2051 void emplace_attr(std::string
&& key
, buffer::list
&& bl
) {
2052 attrs
.emplace(std::move(key
), std::move(bl
));
2055 int verify_permission() override
;
2056 void pre_exec() override
;
2057 void execute() override
;
2059 virtual int get_params() = 0;
2060 void send_response() override
= 0;
2061 const char* name() const override
{ return "set_attrs"; }
2062 RGWOpType
get_type() override
{ return RGW_OP_SET_ATTRS
; }
2063 uint32_t op_mask() override
{ return RGW_OP_TYPE_WRITE
; }
2066 class RGWGetObjLayout
: public RGWOp
{
2068 RGWObjManifest
*manifest
{nullptr};
2069 rgw_raw_obj head_obj
;
2075 int check_caps(RGWUserCaps
& caps
) {
2076 return caps
.check_cap("admin", RGW_CAP_READ
);
2078 int verify_permission() override
{
2079 return check_caps(s
->user
->caps
);
2081 void pre_exec() override
;
2082 void execute() override
;
2084 const char* name() const override
{ return "get_obj_layout"; }
2085 virtual RGWOpType
get_type() override
{ return RGW_OP_GET_OBJ_LAYOUT
; }
2086 virtual uint32_t op_mask() override
{ return RGW_OP_TYPE_READ
; }
2089 class RGWPutBucketPolicy
: public RGWOp
{
2092 RGWPutBucketPolicy() = default;
2093 ~RGWPutBucketPolicy() {
2095 void send_response() override
;
2096 int verify_permission() override
;
2097 uint32_t op_mask() override
{
2098 return RGW_OP_TYPE_WRITE
;
2100 void execute() override
;
2102 const char* name() const override
{ return "put_bucket_policy"; }
2103 RGWOpType
get_type() override
{
2104 return RGW_OP_PUT_BUCKET_POLICY
;
2108 class RGWGetBucketPolicy
: public RGWOp
{
2109 buffer::list policy
;
2111 RGWGetBucketPolicy() = default;
2112 void send_response() override
;
2113 int verify_permission() override
;
2114 uint32_t op_mask() override
{
2115 return RGW_OP_TYPE_READ
;
2117 void execute() override
;
2118 const char* name() const override
{ return "get_bucket_policy"; }
2119 RGWOpType
get_type() override
{
2120 return RGW_OP_GET_BUCKET_POLICY
;
2124 class RGWDeleteBucketPolicy
: public RGWOp
{
2126 RGWDeleteBucketPolicy() = default;
2127 void send_response() override
;
2128 int verify_permission() override
;
2129 uint32_t op_mask() override
{
2130 return RGW_OP_TYPE_WRITE
;
2132 void execute() override
;
2134 const char* name() const override
{ return "delete_bucket_policy"; }
2135 RGWOpType
get_type() override
{
2136 return RGW_OP_DELETE_BUCKET_POLICY
;
2141 class RGWConfigBucketMetaSearch
: public RGWOp
{
2143 std::map
<std::string
, uint32_t> mdsearch_config
;
2145 RGWConfigBucketMetaSearch() {}
2147 int verify_permission() override
;
2148 void pre_exec() override
;
2149 void execute() override
;
2151 virtual int get_params() = 0;
2152 const char* name() const override
{ return "config_bucket_meta_search"; }
2153 virtual RGWOpType
get_type() override
{ return RGW_OP_CONFIG_BUCKET_META_SEARCH
; }
2154 virtual uint32_t op_mask() override
{ return RGW_OP_TYPE_WRITE
; }
2157 class RGWGetBucketMetaSearch
: public RGWOp
{
2159 RGWGetBucketMetaSearch() {}
2161 int verify_permission() override
;
2162 void pre_exec() override
;
2163 void execute() override
{}
2165 const char* name() const override
{ return "get_bucket_meta_search"; }
2166 virtual RGWOpType
get_type() override
{ return RGW_OP_GET_BUCKET_META_SEARCH
; }
2167 virtual uint32_t op_mask() override
{ return RGW_OP_TYPE_READ
; }
2170 class RGWDelBucketMetaSearch
: public RGWOp
{
2172 RGWDelBucketMetaSearch() {}
2174 int verify_permission() override
;
2175 void pre_exec() override
;
2176 void execute() override
;
2178 const char* name() const override
{ return "delete_bucket_meta_search"; }
2179 virtual RGWOpType
delete_type() { return RGW_OP_DEL_BUCKET_META_SEARCH
; }
2180 virtual uint32_t op_mask() override
{ return RGW_OP_TYPE_WRITE
; }
2183 class RGWGetClusterStat
: public RGWOp
{
2185 struct rados_cluster_stat_t stats_op
;
2187 RGWGetClusterStat() {}
2189 void init(RGWRados
*store
, struct req_state
*s
, RGWHandler
*h
) override
{
2190 RGWOp::init(store
, s
, h
);
2192 int verify_permission() override
{return 0;}
2193 virtual void send_response() override
= 0;
2194 virtual int get_params() = 0;
2195 void execute() override
;
2196 const char* name() const override
{ return "get_cluster_stat"; }
2197 dmc::client_id
dmclock_client() override
{ return dmc::client_id::admin
; }
2200 static inline int parse_value_and_bound(
2201 const string
&input
,
2203 const long lower_bound
,
2204 const long upper_bound
,
2205 const long default_val
)
2207 if (!input
.empty()) {
2209 output
= strtol(input
.c_str(), &endptr
, 10);
2211 if (endptr
== input
.c_str()) return -EINVAL
;
2212 while (*endptr
&& isspace(*endptr
)) // ignore white space
2218 if(output
> upper_bound
) {
2219 output
= upper_bound
;
2221 if(output
< lower_bound
) {
2222 output
= lower_bound
;
2225 output
= default_val
;
2232 #endif /* CEPH_RGW_OP_H */