1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 * All operations via the rados gateway are carried out by
5 * small classes known as RGWOps. This class contains a req_state
6 * and each possible command is a subclass of this with a defined
7 * execute() method that does whatever the subclass name implies.
8 * These subclasses must be further subclassed (by interface type)
9 * to provide additional virtual methods such as send_response or get_params.
23 #include <boost/optional.hpp>
24 #include <boost/utility/in_place_factory.hpp>
25 #include <boost/function.hpp>
27 #include "common/armor.h"
28 #include "common/mime.h"
29 #include "common/utf8.h"
30 #include "common/ceph_json.h"
31 #include "common/utf8.h"
32 #include "common/ceph_time.h"
34 #include "rgw_common.h"
35 #include "rgw_rados.h"
37 #include "rgw_bucket.h"
40 #include "rgw_quota.h"
43 #include "rgw_torrent.h"
45 #include "cls/lock/cls_lock_client.h"
46 #include "cls/rgw/cls_rgw_client.h"
48 #include "include/assert.h"
50 using ceph::crypto::SHA1
;
60 class StrategyRegistry
;
72 int do_init_permissions();
73 int do_read_permissions(RGWOp
* op
, bool only_bucket
);
80 virtual ~RGWHandler();
82 virtual int init(RGWRados
* store
,
84 rgw::io::BasicClient
* cio
);
86 virtual int init_permissions(RGWOp
*) {
90 virtual int retarget(RGWOp
* op
, RGWOp
** new_op
) {
95 virtual int read_permissions(RGWOp
* op
) = 0;
96 virtual int authorize() = 0;
97 virtual int postauth_init() = 0;
98 virtual int error_handler(int err_no
, std::string
* error_content
);
99 virtual void dump(const string
& code
, const string
& message
) const {}
104 void rgw_bucket_object_pre_exec(struct req_state
*s
);
107 * Provide the base class for all ops.
112 RGWHandler
*dialect_handler
;
114 RGWCORSConfiguration bucket_cors
;
116 RGWQuotaInfo bucket_quota
;
117 RGWQuotaInfo user_quota
;
120 int do_aws4_auth_completion();
122 virtual int init_quota();
127 dialect_handler(nullptr),
133 virtual ~RGWOp() = default;
135 int get_ret() const { return op_ret
; }
137 virtual int init_processing() {
138 op_ret
= init_quota();
145 virtual void init(RGWRados
*store
, struct req_state
*s
, RGWHandler
*dialect_handler
) {
148 this->dialect_handler
= dialect_handler
;
150 int read_bucket_cors();
151 bool generate_cors_headers(string
& origin
, string
& method
, string
& headers
, string
& exp_headers
, unsigned *max_age
);
153 virtual int verify_params() { return 0; }
154 virtual bool prefetch_data() { return false; }
156 /* Authenticate requester -- verify its identity.
158 * NOTE: typically the procedure is common across all operations of the same
159 * dialect (S3, Swift API). However, there are significant exceptions in
160 * both APIs: browser uploads, /info and OPTIONS handlers. All of them use
161 * different, specific authentication schema driving the need for per-op
162 * authentication. The alternative is to duplicate parts of the method-
163 * dispatch logic in RGWHandler::authorize() and pollute it with a lot
164 * of special cases. */
165 virtual int verify_requester(const rgw::auth::StrategyRegistry
& auth_registry
) {
166 /* TODO(rzarzynski): rename RGWHandler::authorize to generic_authenticate. */
167 return dialect_handler
->authorize();
169 virtual int verify_permission() = 0;
170 virtual int verify_op_mask();
171 virtual void pre_exec() {}
172 virtual void execute() = 0;
173 virtual void send_response() {}
174 virtual void complete() {
177 virtual const string
name() = 0;
178 virtual RGWOpType
get_type() { return RGW_OP_UNKNOWN
; }
180 virtual uint32_t op_mask() { return 0; }
182 virtual int error_handler(int err_no
, string
*error_content
);
185 class RGWGetObj
: public RGWOp
{
187 seed torrent
; // get torrent
188 const char *range_str
;
190 const char *if_unmod
;
191 const char *if_match
;
192 const char *if_nomatch
;
193 uint32_t mod_zone_id
;
199 ceph::real_time mod_time
;
200 ceph::real_time lastmod
;
201 ceph::real_time unmod_time
;
202 ceph::real_time
*mod_ptr
;
203 ceph::real_time
*unmod_ptr
;
204 map
<string
, bufferlist
> attrs
;
206 bool partial_content
;
207 bool ignore_invalid_range
;
210 bool skip_decrypt
{false};
212 utime_t gc_invalidate_time
;
215 bool rgwx_stat
; /* extended rgw stat operation */
219 RGWCompressionInfo cs_info
;
220 off_t first_block
, last_block
;
244 partial_content
= false;
245 range_parsed
= false;
246 skip_manifest
= false;
256 bool prefetch_data() override
;
258 void set_get_data(bool get_data
) {
259 this->get_data
= get_data
;
262 int verify_permission() override
;
263 void pre_exec() override
;
264 void execute() override
;
266 int read_user_manifest_part(
268 const rgw_bucket_dir_entry
& ent
,
269 RGWAccessControlPolicy
* const bucket_acl
,
270 const boost::optional
<rgw::IAM::Policy
>& bucket_policy
,
271 const off_t start_ofs
,
272 const off_t end_ofs
);
273 int handle_user_manifest(const char *prefix
);
274 int handle_slo_manifest(bufferlist
& bl
);
276 int get_data_cb(bufferlist
& bl
, off_t ofs
, off_t len
);
278 virtual int get_params() = 0;
279 virtual int send_response_data_error() = 0;
280 virtual int send_response_data(bufferlist
& bl
, off_t ofs
, off_t len
) = 0;
282 const string
name() override
{ return "get_obj"; }
283 RGWOpType
get_type() override
{ return RGW_OP_GET_OBJ
; }
284 uint32_t op_mask() override
{ return RGW_OP_TYPE_READ
; }
285 virtual bool need_object_expiration() { return false; }
287 * calculates filter used to decrypt RGW objects data
289 virtual int get_decrypt_filter(std::unique_ptr
<RGWGetDataCB
>* filter
, RGWGetDataCB
* cb
, bufferlist
* manifest_bl
) {
295 class RGWGetObj_CB
: public RGWGetDataCB
299 explicit RGWGetObj_CB(RGWGetObj
*_op
) : op(_op
) {}
300 ~RGWGetObj_CB() override
{}
302 int handle_data(bufferlist
& bl
, off_t bl_ofs
, off_t bl_len
) override
{
303 return op
->get_data_cb(bl
, bl_ofs
, bl_len
);
307 class RGWGetObj_Filter
: public RGWGetDataCB
312 RGWGetObj_Filter(RGWGetDataCB
* next
): next(next
) {}
313 ~RGWGetObj_Filter() override
{}
315 * Passes data through filter.
316 * Filter can modify content of bl.
317 * When bl_len == 0 , it means 'flush
319 int handle_data(bufferlist
& bl
, off_t bl_ofs
, off_t bl_len
) override
{
320 return next
->handle_data(bl
, bl_ofs
, bl_len
);
323 * Flushes any cached data. Used by RGWGetObjFilter.
324 * Return logic same as handle_data.
326 int flush() override
{
327 return next
->flush();
330 * Allows filter to extend range required for successful filtering
332 int fixup_range(off_t
& ofs
, off_t
& end
) override
{
333 return next
->fixup_range(ofs
, end
);
337 class RGWGetObjTags
: public RGWOp
{
340 bool has_tags
{false};
342 int verify_permission();
346 virtual void send_response_data(bufferlist
& bl
) = 0;
347 virtual const string
name() noexcept override
{ return "get_obj_tags"; }
348 virtual uint32_t op_mask() { return RGW_OP_TYPE_READ
; }
349 RGWOpType
get_type() { return RGW_OP_GET_OBJ_TAGGING
; }
353 class RGWPutObjTags
: public RGWOp
{
357 int verify_permission();
360 virtual void send_response() = 0;
361 virtual int get_params() = 0;
362 virtual const string
name() { return "put_obj_tags"; }
363 virtual uint32_t op_mask() { return RGW_OP_TYPE_WRITE
; }
364 RGWOpType
get_type() { return RGW_OP_PUT_OBJ_TAGGING
; }
368 class RGWDeleteObjTags
: public RGWOp
{
371 int verify_permission();
374 virtual void send_response() = 0;
375 virtual const string
name() { return "delete_obj_tags"; }
376 virtual uint32_t op_mask() { return RGW_OP_TYPE_DELETE
; }
377 RGWOpType
get_type() { return RGW_OP_DELETE_OBJ_TAGGING
;}
380 class RGWBulkDelete
: public RGWOp
{
383 std::string bucket_name
;
394 unsigned int num_deleted
;
395 unsigned int num_unfound
;
396 std::list
<fail_desc_t
> failures
;
398 RGWRados
* const store
;
402 Deleter(RGWRados
* const str
, req_state
* const s
)
409 unsigned int get_num_deleted() const {
413 unsigned int get_num_unfound() const {
417 const std::list
<fail_desc_t
> get_failures() const {
421 bool verify_permission(RGWBucketInfo
& binfo
,
422 map
<string
, bufferlist
>& battrs
,
423 ACLOwner
& bucket_owner
/* out */);
424 bool delete_single(const acct_path_t
& path
);
425 bool delete_chunk(const std::list
<acct_path_t
>& paths
);
427 /* End of Deleter subclass */
429 static const size_t MAX_CHUNK_ENTRIES
= 1024;
432 std::unique_ptr
<Deleter
> deleter
;
439 int verify_permission() override
;
440 void pre_exec() override
;
441 void execute() override
;
443 virtual int get_data(std::list
<acct_path_t
>& items
,
444 bool * is_truncated
) = 0;
445 void send_response() override
= 0;
447 const string
name() override
{ return "bulk_delete"; }
448 RGWOpType
get_type() override
{ return RGW_OP_BULK_DELETE
; }
449 uint32_t op_mask() override
{ return RGW_OP_TYPE_DELETE
; }
452 inline ostream
& operator<<(ostream
& out
, const RGWBulkDelete::acct_path_t
&o
) {
453 return out
<< o
.bucket_name
<< "/" << o
.obj_key
;
457 class RGWBulkUploadOp
: public RGWOp
{
458 boost::optional
<RGWObjectCtx
> dir_ctx
;
463 fail_desc_t(const int err
, std::string path
)
465 path(std::move(path
)) {
469 const std::string path
;
472 static constexpr std::array
<int, 2> terminal_errors
= {
476 /* FIXME: boost::container::small_vector<fail_desc_t, 4> failures; */
477 std::vector
<fail_desc_t
> failures
;
481 class DecoratedStreamGetter
;
482 class AlignedStreamGetter
;
484 virtual std::unique_ptr
<StreamGetter
> create_stream() = 0;
485 virtual void send_response() = 0;
487 boost::optional
<std::pair
<std::string
, rgw_obj_key
>>
488 parse_path(const boost::string_ref
& path
);
490 std::pair
<std::string
, std::string
>
491 handle_upload_path(struct req_state
*s
);
493 bool handle_file_verify_permission(RGWBucketInfo
& binfo
,
495 std::map
<std::string
, ceph::bufferlist
>& battrs
,
496 ACLOwner
& bucket_owner
/* out */);
497 int handle_file(boost::string_ref path
,
499 AlignedStreamGetter
& body
);
501 int handle_dir_verify_permission();
502 int handle_dir(boost::string_ref path
);
509 void init(RGWRados
* const store
,
510 struct req_state
* const s
,
511 RGWHandler
* const h
) override
{
512 RGWOp::init(store
, s
, h
);
513 dir_ctx
.emplace(store
);
516 int verify_permission() override
;
517 void pre_exec() override
;
518 void execute() override
;
520 const std::string
name() override
{
521 return "bulk_upload";
524 RGWOpType
get_type() override
{
525 return RGW_OP_BULK_UPLOAD
;
528 uint32_t op_mask() override
{
529 return RGW_OP_TYPE_WRITE
;
531 }; /* RGWBulkUploadOp */
534 class RGWBulkUploadOp::StreamGetter
{
536 StreamGetter() = default;
537 virtual ~StreamGetter() = default;
539 virtual ssize_t
get_at_most(size_t want
, ceph::bufferlist
& dst
) = 0;
540 virtual ssize_t
get_exactly(size_t want
, ceph::bufferlist
& dst
) = 0;
541 }; /* End of nested subclass StreamGetter */
544 class RGWBulkUploadOp::DecoratedStreamGetter
: public StreamGetter
{
545 StreamGetter
& decoratee
;
548 StreamGetter
& get_decoratee() {
553 DecoratedStreamGetter(StreamGetter
& decoratee
)
554 : decoratee(decoratee
) {
556 virtual ~DecoratedStreamGetter() = default;
558 ssize_t
get_at_most(const size_t want
, ceph::bufferlist
& dst
) override
{
559 return get_decoratee().get_at_most(want
, dst
);
562 ssize_t
get_exactly(const size_t want
, ceph::bufferlist
& dst
) override
{
563 return get_decoratee().get_exactly(want
, dst
);
565 }; /* RGWBulkUploadOp::DecoratedStreamGetter */
568 class RGWBulkUploadOp::AlignedStreamGetter
569 : public RGWBulkUploadOp::DecoratedStreamGetter
{
575 template <typename U
>
576 AlignedStreamGetter(const size_t position
,
578 const size_t alignment
,
580 : DecoratedStreamGetter(std::forward
<U
>(decoratee
)),
583 alignment(alignment
) {
585 virtual ~AlignedStreamGetter();
586 ssize_t
get_at_most(size_t want
, ceph::bufferlist
& dst
) override
;
587 ssize_t
get_exactly(size_t want
, ceph::bufferlist
& dst
) override
;
588 }; /* RGWBulkUploadOp::AlignedStreamGetter */
591 struct RGWUsageStats
{
592 uint64_t bytes_used
= 0;
593 uint64_t bytes_used_rounded
= 0;
594 uint64_t buckets_count
= 0;
595 uint64_t objects_count
= 0;
598 #define RGW_LIST_BUCKETS_LIMIT_MAX 10000
600 class RGWListBuckets
: public RGWOp
{
604 std::string end_marker
;
607 std::map
<std::string
, ceph::bufferlist
> attrs
;
610 RGWUsageStats global_stats
;
611 std::map
<std::string
, RGWUsageStats
> policies_stats
;
613 virtual uint64_t get_default_max() const {
620 limit(RGW_LIST_BUCKETS_LIMIT_MAX
),
621 limit_max(RGW_LIST_BUCKETS_LIMIT_MAX
),
622 is_truncated(false) {
625 int verify_permission() override
;
626 void execute() override
;
628 virtual int get_params() = 0;
629 virtual void handle_listing_chunk(RGWUserBuckets
&& buckets
) {
630 /* The default implementation, used by e.g. S3, just generates a new
631 * part of listing and sends it client immediately. Swift can behave
632 * differently: when the reverse option is requested, all incoming
633 * instances of RGWUserBuckets are buffered and finally reversed. */
634 return send_response_data(buckets
);
636 virtual void send_response_begin(bool has_buckets
) = 0;
637 virtual void send_response_data(RGWUserBuckets
& buckets
) = 0;
638 virtual void send_response_end() = 0;
639 void send_response() override
{}
641 virtual bool should_get_stats() { return false; }
642 virtual bool supports_account_metadata() { return false; }
644 const string
name() override
{ return "list_buckets"; }
645 RGWOpType
get_type() override
{ return RGW_OP_LIST_BUCKETS
; }
646 uint32_t op_mask() override
{ return RGW_OP_TYPE_READ
; }
647 }; // class RGWListBuckets
649 class RGWGetUsage
: public RGWOp
{
654 int show_log_entries
;
656 map
<string
, bool> categories
;
657 map
<rgw_user_bucket
, rgw_usage_log_entry
> usage
;
658 map
<string
, rgw_usage_log_entry
> summary_map
;
659 map
<string
, cls_user_bucket_entry
> buckets_usage
;
660 cls_user_header header
;
662 RGWGetUsage() : sent_data(false), show_log_entries(true), show_log_sum(true){
665 int verify_permission() override
;
666 void execute() override
;
668 virtual int get_params() = 0;
669 void send_response() override
{}
671 virtual bool should_get_stats() { return false; }
673 const string
name() override
{ return "get_usage"; }
674 uint32_t op_mask() override
{ return RGW_OP_TYPE_READ
; }
677 class RGWStatAccount
: public RGWOp
{
679 RGWUsageStats global_stats
;
680 std::map
<std::string
, RGWUsageStats
> policies_stats
;
683 RGWStatAccount() = default;
685 int verify_permission() override
;
686 void execute() override
;
688 void send_response() override
= 0;
689 const std::string
name() override
{ return "stat_account"; }
690 RGWOpType
get_type() override
{ return RGW_OP_STAT_ACCOUNT
; }
691 uint32_t op_mask() override
{ return RGW_OP_TYPE_READ
; }
694 class RGWListBucket
: public RGWOp
{
699 rgw_obj_key next_marker
;
700 rgw_obj_key end_marker
;
703 string encoding_type
;
706 vector
<rgw_bucket_dir_entry
> objs
;
707 map
<string
, bool> common_prefixes
;
711 bool allow_unordered
;
715 int parse_max_keys();
718 RGWListBucket() : list_versions(false), max(0),
719 default_max(0), is_truncated(false),
720 allow_unordered(false), shard_id(-1) {}
721 int verify_permission() override
;
722 void pre_exec() override
;
723 void execute() override
;
725 virtual int get_params() = 0;
726 void send_response() override
= 0;
727 const string
name() override
{ return "list_bucket"; }
728 RGWOpType
get_type() override
{ return RGW_OP_LIST_BUCKET
; }
729 uint32_t op_mask() override
{ return RGW_OP_TYPE_READ
; }
730 virtual bool need_container_stats() { return false; }
733 class RGWGetBucketLogging
: public RGWOp
{
735 RGWGetBucketLogging() {}
736 int verify_permission() override
;
737 void execute() override
{ }
739 void send_response() override
= 0;
740 const string
name() override
{ return "get_bucket_logging"; }
741 RGWOpType
get_type() override
{ return RGW_OP_GET_BUCKET_LOGGING
; }
742 uint32_t op_mask() override
{ return RGW_OP_TYPE_READ
; }
745 class RGWGetBucketLocation
: public RGWOp
{
747 RGWGetBucketLocation() {}
748 ~RGWGetBucketLocation() override
{}
749 int verify_permission() override
;
750 void execute() override
{ }
752 void send_response() override
= 0;
753 const string
name() override
{ return "get_bucket_location"; }
754 RGWOpType
get_type() override
{ return RGW_OP_GET_BUCKET_LOCATION
; }
755 uint32_t op_mask() override
{ return RGW_OP_TYPE_READ
; }
758 class RGWGetBucketVersioning
: public RGWOp
{
761 bool versioning_enabled
;
763 RGWGetBucketVersioning() : versioned(false), versioning_enabled(false) {}
765 int verify_permission() override
;
766 void pre_exec() override
;
767 void execute() override
;
769 void send_response() override
= 0;
770 const string
name() override
{ return "get_bucket_versioning"; }
771 RGWOpType
get_type() override
{ return RGW_OP_GET_BUCKET_VERSIONING
; }
772 uint32_t op_mask() override
{ return RGW_OP_TYPE_READ
; }
775 class RGWSetBucketVersioning
: public RGWOp
{
777 bool enable_versioning
;
780 RGWSetBucketVersioning() : enable_versioning(false) {}
782 int verify_permission() override
;
783 void pre_exec() override
;
784 void execute() override
;
786 virtual int get_params() { return 0; }
788 void send_response() override
= 0;
789 const string
name() override
{ return "set_bucket_versioning"; }
790 RGWOpType
get_type() override
{ return RGW_OP_SET_BUCKET_VERSIONING
; }
791 uint32_t op_mask() override
{ return RGW_OP_TYPE_WRITE
; }
794 class RGWGetBucketWebsite
: public RGWOp
{
796 RGWGetBucketWebsite() {}
798 int verify_permission() override
;
799 void pre_exec() override
;
800 void execute() override
;
802 void send_response() override
= 0;
803 const string
name() override
{ return "get_bucket_website"; }
804 RGWOpType
get_type() override
{ return RGW_OP_GET_BUCKET_WEBSITE
; }
805 uint32_t op_mask() override
{ return RGW_OP_TYPE_READ
; }
808 class RGWSetBucketWebsite
: public RGWOp
{
811 RGWBucketWebsiteConf website_conf
;
813 RGWSetBucketWebsite() {}
815 int verify_permission() override
;
816 void pre_exec() override
;
817 void execute() override
;
819 virtual int get_params() { return 0; }
821 void send_response() override
= 0;
822 const string
name() override
{ return "set_bucket_website"; }
823 RGWOpType
get_type() override
{ return RGW_OP_SET_BUCKET_WEBSITE
; }
824 uint32_t op_mask() override
{ return RGW_OP_TYPE_WRITE
; }
827 class RGWDeleteBucketWebsite
: public RGWOp
{
829 RGWDeleteBucketWebsite() {}
831 int verify_permission() override
;
832 void pre_exec() override
;
833 void execute() override
;
835 void send_response() override
= 0;
836 const string
name() override
{ return "delete_bucket_website"; }
837 RGWOpType
get_type() override
{ return RGW_OP_SET_BUCKET_WEBSITE
; }
838 uint32_t op_mask() override
{ return RGW_OP_TYPE_WRITE
; }
841 class RGWStatBucket
: public RGWOp
{
847 ~RGWStatBucket() override
{}
849 int verify_permission() override
;
850 void pre_exec() override
;
851 void execute() override
;
853 void send_response() override
= 0;
854 const string
name() override
{ return "stat_bucket"; }
855 RGWOpType
get_type() override
{ return RGW_OP_STAT_BUCKET
; }
856 uint32_t op_mask() override
{ return RGW_OP_TYPE_READ
; }
859 class RGWCreateBucket
: public RGWOp
{
861 RGWAccessControlPolicy policy
;
862 string location_constraint
;
863 string placement_rule
;
867 RGWCORSConfiguration cors_config
;
868 boost::optional
<std::string
> swift_ver_location
;
869 map
<string
, buffer::list
> attrs
;
870 set
<string
> rmattr_names
;
874 virtual bool need_metadata_upload() const { return false; }
877 RGWCreateBucket() : has_cors(false) {}
879 void emplace_attr(std::string
&& key
, buffer::list
&& bl
) {
880 attrs
.emplace(std::move(key
), std::move(bl
)); /* key and bl are r-value refs */
883 int verify_permission() override
;
884 void pre_exec() override
;
885 void execute() override
;
886 void init(RGWRados
*store
, struct req_state
*s
, RGWHandler
*h
) override
{
887 RGWOp::init(store
, s
, h
);
888 policy
.set_ctx(s
->cct
);
890 virtual int get_params() { return 0; }
891 void send_response() override
= 0;
892 const string
name() override
{ return "create_bucket"; }
893 RGWOpType
get_type() override
{ return RGW_OP_CREATE_BUCKET
; }
894 uint32_t op_mask() override
{ return RGW_OP_TYPE_WRITE
; }
897 class RGWDeleteBucket
: public RGWOp
{
899 RGWObjVersionTracker objv_tracker
;
904 int verify_permission() override
;
905 void pre_exec() override
;
906 void execute() override
;
908 void send_response() override
= 0;
909 const string
name() override
{ return "delete_bucket"; }
910 RGWOpType
get_type() override
{ return RGW_OP_DELETE_BUCKET
; }
911 uint32_t op_mask() override
{ return RGW_OP_TYPE_DELETE
; }
914 struct rgw_slo_entry
{
919 rgw_slo_entry() : size_bytes(0) {}
921 void encode(bufferlist
& bl
) const {
922 ENCODE_START(1, 1, bl
);
925 ::encode(size_bytes
, bl
);
929 void decode(bufferlist::iterator
& bl
) {
933 ::decode(size_bytes
, bl
);
937 void decode_json(JSONObj
*obj
);
939 WRITE_CLASS_ENCODER(rgw_slo_entry
)
942 vector
<rgw_slo_entry
> entries
;
949 RGWSLOInfo() : total_size(0), raw_data(NULL
), raw_data_len(0) {}
954 void encode(bufferlist
& bl
) const {
955 ENCODE_START(1, 1, bl
);
956 ::encode(entries
, bl
);
957 ::encode(total_size
, bl
);
961 void decode(bufferlist::iterator
& bl
) {
963 ::decode(entries
, bl
);
964 ::decode(total_size
, bl
);
968 WRITE_CLASS_ENCODER(RGWSLOInfo
)
970 class RGWPutObj
: public RGWOp
{
972 friend class RGWPutObjProcessor
;
977 const char *supplied_md5_b64
;
978 const char *supplied_etag
;
979 const char *if_match
;
980 const char *if_nomatch
;
981 std::string copy_source
;
982 const char *copy_source_range
;
983 RGWBucketInfo copy_source_bucket_info
;
984 string copy_source_tenant_name
;
985 string copy_source_bucket_name
;
986 string copy_source_object_name
;
987 string copy_source_version_id
;
988 off_t copy_source_range_fst
;
989 off_t copy_source_range_lst
;
992 RGWAccessControlPolicy policy
;
993 std::unique_ptr
<RGWObjTags
> obj_tags
;
994 const char *dlo_manifest
;
995 RGWSLOInfo
*slo_info
;
996 map
<string
, bufferlist
> attrs
;
997 ceph::real_time mtime
;
1001 map
<string
, string
> crypt_http_responses
;
1004 boost::optional
<ceph::real_time
> delete_at
;
1007 RGWPutObj() : ofs(0),
1008 supplied_md5_b64(NULL
),
1009 supplied_etag(NULL
),
1012 copy_source_range(NULL
),
1013 copy_source_range_fst(0),
1014 copy_source_range_lst(0),
1020 ~RGWPutObj() override
{
1024 void init(RGWRados
*store
, struct req_state
*s
, RGWHandler
*h
) override
{
1025 RGWOp::init(store
, s
, h
);
1026 policy
.set_ctx(s
->cct
);
1029 void emplace_attr(std::string
&& key
, buffer::list
&& bl
) {
1030 attrs
.emplace(std::move(key
), std::move(bl
)); /* key and bl are r-value refs */
1033 virtual RGWPutObjProcessor
*select_processor(RGWObjectCtx
& obj_ctx
, bool *is_multipart
);
1034 void dispose_processor(RGWPutObjDataProcessor
*processor
);
1036 int verify_permission() override
;
1037 void pre_exec() override
;
1038 void execute() override
;
1040 /* this is for cases when copying data from other object */
1041 virtual int get_decrypt_filter(std::unique_ptr
<RGWGetDataCB
>* filter
,
1043 map
<string
, bufferlist
>& attrs
,
1044 bufferlist
* manifest_bl
) {
1048 virtual int get_encrypt_filter(std::unique_ptr
<RGWPutObjDataProcessor
> *filter
, RGWPutObjDataProcessor
* cb
) {
1053 int get_data_cb(bufferlist
& bl
, off_t bl_ofs
, off_t bl_len
);
1054 int get_data(const off_t fst
, const off_t lst
, bufferlist
& bl
);
1056 virtual int get_params() = 0;
1057 virtual int get_data(bufferlist
& bl
) = 0;
1058 void send_response() override
= 0;
1059 const string
name() override
{ return "put_obj"; }
1060 RGWOpType
get_type() override
{ return RGW_OP_PUT_OBJ
; }
1061 uint32_t op_mask() override
{ return RGW_OP_TYPE_WRITE
; }
1064 class RGWPutObj_Filter
: public RGWPutObjDataProcessor
1067 RGWPutObjDataProcessor
* next
;
1069 RGWPutObj_Filter(RGWPutObjDataProcessor
* next
) :
1071 ~RGWPutObj_Filter() override
{}
1072 int handle_data(bufferlist
& bl
, off_t ofs
, void **phandle
, rgw_raw_obj
*pobj
, bool *again
) override
{
1073 return next
->handle_data(bl
, ofs
, phandle
, pobj
, again
);
1075 int throttle_data(void *handle
, const rgw_raw_obj
& obj
, uint64_t size
, bool need_to_wait
) override
{
1076 return next
->throttle_data(handle
, obj
, size
, need_to_wait
);
1078 }; /* RGWPutObj_Filter */
1080 class RGWPostObj
: public RGWOp
{
1086 const char *supplied_md5_b64
;
1087 const char *supplied_etag
;
1089 RGWAccessControlPolicy policy
;
1090 map
<string
, bufferlist
> attrs
;
1091 boost::optional
<ceph::real_time
> delete_at
;
1093 /* Must be called after get_data() or the result is undefined. */
1094 virtual std::string
get_current_filename() const = 0;
1095 virtual std::string
get_current_content_type() const = 0;
1096 virtual bool is_next_file_to_upload() {
1100 RGWPostObj() : min_len(0),
1104 supplied_md5_b64(nullptr),
1105 supplied_etag(nullptr) {
1108 void emplace_attr(std::string
&& key
, buffer::list
&& bl
) {
1109 attrs
.emplace(std::move(key
), std::move(bl
)); /* key and bl are r-value refs */
1112 void init(RGWRados
*store
, struct req_state
*s
, RGWHandler
*h
) override
{
1113 RGWOp::init(store
, s
, h
);
1114 policy
.set_ctx(s
->cct
);
1117 int verify_permission() override
;
1118 void pre_exec() override
;
1119 void execute() override
;
1121 virtual int get_encrypt_filter(std::unique_ptr
<RGWPutObjDataProcessor
> *filter
, RGWPutObjDataProcessor
* cb
) {
1125 virtual int get_params() = 0;
1126 virtual int get_data(ceph::bufferlist
& bl
, bool& again
) = 0;
1127 void send_response() override
= 0;
1128 const std::string
name() override
{ return "post_obj"; }
1129 RGWOpType
get_type() override
{ return RGW_OP_POST_OBJ
; }
1130 uint32_t op_mask() override
{ return RGW_OP_TYPE_WRITE
; }
1133 class RGWPutMetadataAccount
: public RGWOp
{
1135 std::set
<std::string
> rmattr_names
;
1136 std::map
<std::string
, bufferlist
> attrs
, orig_attrs
;
1137 std::map
<int, std::string
> temp_url_keys
;
1138 RGWQuotaInfo new_quota
;
1139 bool new_quota_extracted
;
1141 RGWObjVersionTracker acct_op_tracker
;
1143 RGWAccessControlPolicy policy
;
1147 RGWPutMetadataAccount()
1148 : new_quota_extracted(false),
1152 void init(RGWRados
*store
, struct req_state
*s
, RGWHandler
*h
) override
{
1153 RGWOp::init(store
, s
, h
);
1154 policy
.set_ctx(s
->cct
);
1156 int init_processing() override
;
1157 int verify_permission() override
;
1158 void pre_exec() override
{ }
1159 void execute() override
;
1161 virtual int get_params() = 0;
1162 void send_response() override
= 0;
1163 virtual void filter_out_temp_url(map
<string
, bufferlist
>& add_attrs
,
1164 const set
<string
>& rmattr_names
,
1165 map
<int, string
>& temp_url_keys
);
1166 const string
name() override
{ return "put_account_metadata"; }
1167 RGWOpType
get_type() override
{ return RGW_OP_PUT_METADATA_ACCOUNT
; }
1168 uint32_t op_mask() override
{ return RGW_OP_TYPE_WRITE
; }
1171 class RGWPutMetadataBucket
: public RGWOp
{
1173 map
<string
, buffer::list
> attrs
;
1174 set
<string
> rmattr_names
;
1175 bool has_policy
, has_cors
;
1176 uint32_t policy_rw_mask
;
1177 RGWAccessControlPolicy policy
;
1178 RGWCORSConfiguration cors_config
;
1179 string placement_rule
;
1180 boost::optional
<std::string
> swift_ver_location
;
1183 RGWPutMetadataBucket()
1184 : has_policy(false), has_cors(false), policy_rw_mask(0)
1187 void emplace_attr(std::string
&& key
, buffer::list
&& bl
) {
1188 attrs
.emplace(std::move(key
), std::move(bl
)); /* key and bl are r-value refs */
1191 void init(RGWRados
*store
, struct req_state
*s
, RGWHandler
*h
) override
{
1192 RGWOp::init(store
, s
, h
);
1193 policy
.set_ctx(s
->cct
);
1196 int verify_permission() override
;
1197 void pre_exec() override
;
1198 void execute() override
;
1200 virtual int get_params() = 0;
1201 void send_response() override
= 0;
1202 const string
name() override
{ return "put_bucket_metadata"; }
1203 RGWOpType
get_type() override
{ return RGW_OP_PUT_METADATA_BUCKET
; }
1204 uint32_t op_mask() override
{ return RGW_OP_TYPE_WRITE
; }
1207 class RGWPutMetadataObject
: public RGWOp
{
1209 RGWAccessControlPolicy policy
;
1210 string placement_rule
;
1211 boost::optional
<ceph::real_time
> delete_at
;
1212 const char *dlo_manifest
;
1215 RGWPutMetadataObject()
1216 : dlo_manifest(NULL
)
1219 void init(RGWRados
*store
, struct req_state
*s
, RGWHandler
*h
) override
{
1220 RGWOp::init(store
, s
, h
);
1221 policy
.set_ctx(s
->cct
);
1223 int verify_permission() override
;
1224 void pre_exec() override
;
1225 void execute() override
;
1227 virtual int get_params() = 0;
1228 void send_response() override
= 0;
1229 const string
name() override
{ return "put_obj_metadata"; }
1230 RGWOpType
get_type() override
{ return RGW_OP_PUT_METADATA_OBJECT
; }
1231 uint32_t op_mask() override
{ return RGW_OP_TYPE_WRITE
; }
1232 virtual bool need_object_expiration() { return false; }
1235 class RGWDeleteObj
: public RGWOp
{
1238 bool multipart_delete
;
1240 ceph::real_time unmod_since
; /* if unmodified since */
1241 bool no_precondition_error
;
1242 std::unique_ptr
<RGWBulkDelete::Deleter
> deleter
;
1246 : delete_marker(false),
1247 multipart_delete(false),
1248 no_precondition_error(false),
1252 int verify_permission() override
;
1253 void pre_exec() override
;
1254 void execute() override
;
1255 int handle_slo_manifest(bufferlist
& bl
);
1257 virtual int get_params() { return 0; }
1258 void send_response() override
= 0;
1259 const string
name() override
{ return "delete_obj"; }
1260 RGWOpType
get_type() override
{ return RGW_OP_DELETE_OBJ
; }
1261 uint32_t op_mask() override
{ return RGW_OP_TYPE_DELETE
; }
1262 virtual bool need_object_expiration() { return false; }
1265 class RGWCopyObj
: public RGWOp
{
1267 RGWAccessControlPolicy dest_policy
;
1269 const char *if_unmod
;
1270 const char *if_match
;
1271 const char *if_nomatch
;
1275 ceph::real_time mod_time
;
1276 ceph::real_time unmod_time
;
1277 ceph::real_time
*mod_ptr
;
1278 ceph::real_time
*unmod_ptr
;
1279 map
<string
, buffer::list
> attrs
;
1280 string src_tenant_name
, src_bucket_name
;
1281 rgw_bucket src_bucket
;
1282 rgw_obj_key src_object
;
1283 string dest_tenant_name
, dest_bucket_name
;
1284 rgw_bucket dest_bucket
;
1286 ceph::real_time src_mtime
;
1287 ceph::real_time mtime
;
1288 RGWRados::AttrsMod attrs_mod
;
1289 RGWBucketInfo src_bucket_info
;
1290 RGWBucketInfo dest_bucket_info
;
1294 ceph::buffer::list etag
;
1301 boost::optional
<ceph::real_time
> delete_at
;
1317 attrs_mod
= RGWRados::ATTRSMOD_NONE
;
1320 copy_if_newer
= false;
1323 static bool parse_copy_location(const boost::string_view
& src
,
1324 string
& bucket_name
,
1325 rgw_obj_key
& object
);
1327 void emplace_attr(std::string
&& key
, buffer::list
&& bl
) {
1328 attrs
.emplace(std::move(key
), std::move(bl
));
1331 void init(RGWRados
*store
, struct req_state
*s
, RGWHandler
*h
) override
{
1332 RGWOp::init(store
, s
, h
);
1333 dest_policy
.set_ctx(s
->cct
);
1335 int verify_permission() override
;
1336 void pre_exec() override
;
1337 void execute() override
;
1338 void progress_cb(off_t ofs
);
1340 virtual int init_dest_policy() { return 0; }
1341 virtual int get_params() = 0;
1342 virtual void send_partial_response(off_t ofs
) {}
1343 void send_response() override
= 0;
1344 const string
name() override
{ return "copy_obj"; }
1345 RGWOpType
get_type() override
{ return RGW_OP_COPY_OBJ
; }
1346 uint32_t op_mask() override
{ return RGW_OP_TYPE_WRITE
; }
1349 class RGWGetACLs
: public RGWOp
{
1356 int verify_permission() override
;
1357 void pre_exec() override
;
1358 void execute() override
;
1360 void send_response() override
= 0;
1361 const string
name() override
{ return "get_acls"; }
1362 RGWOpType
get_type() override
{ return RGW_OP_GET_ACLS
; }
1363 uint32_t op_mask() override
{ return RGW_OP_TYPE_READ
; }
1366 class RGWPutACLs
: public RGWOp
{
1377 ~RGWPutACLs() override
{
1381 int verify_permission() override
;
1382 void pre_exec() override
;
1383 void execute() override
;
1385 virtual int get_policy_from_state(RGWRados
*store
, struct req_state
*s
, stringstream
& ss
) { return 0; }
1386 virtual int get_params() = 0;
1387 void send_response() override
= 0;
1388 const string
name() override
{ return "put_acls"; }
1389 RGWOpType
get_type() override
{ return RGW_OP_PUT_ACLS
; }
1390 uint32_t op_mask() override
{ return RGW_OP_TYPE_WRITE
; }
1393 class RGWGetLC
: public RGWOp
{
1398 ~RGWGetLC() override
{ }
1400 int verify_permission() override
;
1401 void pre_exec() override
;
1402 void execute() override
= 0;
1404 void send_response() override
= 0;
1405 const string
name() override
{ return "get_lifecycle"; }
1406 RGWOpType
get_type() override
{ return RGW_OP_GET_LC
; }
1407 uint32_t op_mask() override
{ return RGW_OP_TYPE_READ
; }
1410 class RGWPutLC
: public RGWOp
{
1414 const char *content_md5
;
1421 content_md5
= nullptr;
1423 ~RGWPutLC() override
{
1427 void init(RGWRados
*store
, struct req_state
*s
, RGWHandler
*dialect_handler
) override
{
1428 #define COOKIE_LEN 16
1429 char buf
[COOKIE_LEN
+ 1];
1431 RGWOp::init(store
, s
, dialect_handler
);
1432 gen_rand_alphanumeric(s
->cct
, buf
, sizeof(buf
) - 1);
1436 int verify_permission() override
;
1437 void pre_exec() override
;
1438 void execute() override
;
1440 // virtual int get_policy_from_state(RGWRados *store, struct req_state *s, stringstream& ss) { return 0; }
1441 virtual int get_params() = 0;
1442 void send_response() override
= 0;
1443 const string
name() override
{ return "put_lifecycle"; }
1444 RGWOpType
get_type() override
{ return RGW_OP_PUT_LC
; }
1445 uint32_t op_mask() override
{ return RGW_OP_TYPE_WRITE
; }
1448 class RGWDeleteLC
: public RGWOp
{
1458 ~RGWDeleteLC() override
{
1462 int verify_permission() override
;
1463 void pre_exec() override
;
1464 void execute() override
;
1466 void send_response() override
= 0;
1467 const string
name() override
{ return "delete_lifecycle"; }
1468 RGWOpType
get_type() override
{ return RGW_OP_DELETE_LC
; }
1469 uint32_t op_mask() override
{ return RGW_OP_TYPE_WRITE
; }
1472 class RGWGetCORS
: public RGWOp
{
1478 int verify_permission() override
;
1479 void execute() override
;
1481 void send_response() override
= 0;
1482 const string
name() override
{ return "get_cors"; }
1483 RGWOpType
get_type() override
{ return RGW_OP_GET_CORS
; }
1484 uint32_t op_mask() override
{ return RGW_OP_TYPE_READ
; }
1487 class RGWPutCORS
: public RGWOp
{
1494 ~RGWPutCORS() override
{}
1496 int verify_permission() override
;
1497 void execute() override
;
1499 virtual int get_params() = 0;
1500 void send_response() override
= 0;
1501 const string
name() override
{ return "put_cors"; }
1502 RGWOpType
get_type() override
{ return RGW_OP_PUT_CORS
; }
1503 uint32_t op_mask() override
{ return RGW_OP_TYPE_WRITE
; }
1506 class RGWDeleteCORS
: public RGWOp
{
1512 int verify_permission() override
;
1513 void execute() override
;
1515 void send_response() override
= 0;
1516 const string
name() override
{ return "delete_cors"; }
1517 RGWOpType
get_type() override
{ return RGW_OP_DELETE_CORS
; }
1518 uint32_t op_mask() override
{ return RGW_OP_TYPE_WRITE
; }
1521 class RGWOptionsCORS
: public RGWOp
{
1524 const char *origin
, *req_hdrs
, *req_meth
;
1527 RGWOptionsCORS() : rule(NULL
), origin(NULL
),
1528 req_hdrs(NULL
), req_meth(NULL
) {
1531 int verify_permission() override
{return 0;}
1532 int validate_cors_request(RGWCORSConfiguration
*cc
);
1533 void execute() override
;
1534 void get_response_params(string
& allowed_hdrs
, string
& exp_hdrs
, unsigned *max_age
);
1535 void send_response() override
= 0;
1536 const string
name() override
{ return "options_cors"; }
1537 RGWOpType
get_type() override
{ return RGW_OP_OPTIONS_CORS
; }
1538 uint32_t op_mask() override
{ return RGW_OP_TYPE_READ
; }
1541 class RGWGetRequestPayment
: public RGWOp
{
1543 bool requester_pays
;
1546 RGWGetRequestPayment() : requester_pays(0) {}
1548 int verify_permission() override
;
1549 void pre_exec() override
;
1550 void execute() override
;
1552 void send_response() override
= 0;
1553 const string
name() override
{ return "get_request_payment"; }
1554 RGWOpType
get_type() override
{ return RGW_OP_GET_REQUEST_PAYMENT
; }
1555 uint32_t op_mask() override
{ return RGW_OP_TYPE_READ
; }
1558 class RGWSetRequestPayment
: public RGWOp
{
1560 bool requester_pays
;
1562 RGWSetRequestPayment() : requester_pays(false) {}
1564 int verify_permission() override
;
1565 void pre_exec() override
;
1566 void execute() override
;
1568 virtual int get_params() { return 0; }
1570 void send_response() override
= 0;
1571 const string
name() override
{ return "set_request_payment"; }
1572 RGWOpType
get_type() override
{ return RGW_OP_SET_REQUEST_PAYMENT
; }
1573 uint32_t op_mask() override
{ return RGW_OP_TYPE_WRITE
; }
1576 class RGWInitMultipart
: public RGWOp
{
1579 RGWAccessControlPolicy policy
;
1582 RGWInitMultipart() {}
1584 void init(RGWRados
*store
, struct req_state
*s
, RGWHandler
*h
) override
{
1585 RGWOp::init(store
, s
, h
);
1586 policy
.set_ctx(s
->cct
);
1588 int verify_permission() override
;
1589 void pre_exec() override
;
1590 void execute() override
;
1592 virtual int get_params() = 0;
1593 void send_response() override
= 0;
1594 const string
name() override
{ return "init_multipart"; }
1595 RGWOpType
get_type() override
{ return RGW_OP_INIT_MULTIPART
; }
1596 uint32_t op_mask() override
{ return RGW_OP_TYPE_WRITE
; }
1597 virtual int prepare_encryption(map
<string
, bufferlist
>& attrs
) { return 0; }
1600 class RGWCompleteMultipart
: public RGWOp
{
1607 struct MPSerializer
{
1608 librados::IoCtx ioctx
;
1609 rados::cls::lock::Lock lock
;
1610 librados::ObjectWriteOperation op
;
1614 MPSerializer() : lock("RGWCompleteMultipart"), locked(false)
1617 int try_lock(const std::string
& oid
, utime_t dur
);
1620 return lock
.unlock(&ioctx
, oid
);
1623 void clear_locked() {
1629 RGWCompleteMultipart() {
1633 ~RGWCompleteMultipart() override
{
1637 int verify_permission() override
;
1638 void pre_exec() override
;
1639 void execute() override
;
1640 void complete() override
;
1642 virtual int get_params() = 0;
1643 void send_response() override
= 0;
1644 const string
name() override
{ return "complete_multipart"; }
1645 RGWOpType
get_type() override
{ return RGW_OP_COMPLETE_MULTIPART
; }
1646 uint32_t op_mask() override
{ return RGW_OP_TYPE_WRITE
; }
1649 class RGWAbortMultipart
: public RGWOp
{
1651 RGWAbortMultipart() {}
1653 int verify_permission() override
;
1654 void pre_exec() override
;
1655 void execute() override
;
1657 void send_response() override
= 0;
1658 const string
name() override
{ return "abort_multipart"; }
1659 RGWOpType
get_type() override
{ return RGW_OP_ABORT_MULTIPART
; }
1660 uint32_t op_mask() override
{ return RGW_OP_TYPE_DELETE
; }
1663 class RGWListMultipart
: public RGWOp
{
1666 map
<uint32_t, RGWUploadPartInfo
> parts
;
1669 RGWAccessControlPolicy policy
;
1673 RGWListMultipart() {
1679 void init(RGWRados
*store
, struct req_state
*s
, RGWHandler
*h
) override
{
1680 RGWOp::init(store
, s
, h
);
1681 policy
= RGWAccessControlPolicy(s
->cct
);
1683 int verify_permission() override
;
1684 void pre_exec() override
;
1685 void execute() override
;
1687 virtual int get_params() = 0;
1688 void send_response() override
= 0;
1689 const string
name() override
{ return "list_multipart"; }
1690 RGWOpType
get_type() override
{ return RGW_OP_LIST_MULTIPART
; }
1691 uint32_t op_mask() override
{ return RGW_OP_TYPE_READ
; }
1694 struct RGWMultipartUploadEntry
{
1695 rgw_bucket_dir_entry obj
;
1699 class RGWListBucketMultiparts
: public RGWOp
{
1703 RGWMultipartUploadEntry next_marker
;
1706 vector
<RGWMultipartUploadEntry
> uploads
;
1707 map
<string
, bool> common_prefixes
;
1712 RGWListBucketMultiparts() {
1714 is_truncated
= false;
1718 void init(RGWRados
*store
, struct req_state
*s
, RGWHandler
*h
) override
{
1719 RGWOp::init(store
, s
, h
);
1720 max_uploads
= default_max
;
1723 int verify_permission() override
;
1724 void pre_exec() override
;
1725 void execute() override
;
1727 virtual int get_params() = 0;
1728 void send_response() override
= 0;
1729 const string
name() override
{ return "list_bucket_multiparts"; }
1730 RGWOpType
get_type() override
{ return RGW_OP_LIST_BUCKET_MULTIPARTS
; }
1731 uint32_t op_mask() override
{ return RGW_OP_TYPE_READ
; }
1735 class RGWGetCrossDomainPolicy
: public RGWOp
{
1737 RGWGetCrossDomainPolicy() = default;
1738 ~RGWGetCrossDomainPolicy() override
= default;
1740 int verify_permission() override
{
1744 void execute() override
{
1748 const string
name() override
{
1749 return "get_crossdomain_policy";
1752 RGWOpType
get_type() override
{
1753 return RGW_OP_GET_CROSS_DOMAIN_POLICY
;
1756 uint32_t op_mask() override
{
1757 return RGW_OP_TYPE_READ
;
1762 class RGWGetHealthCheck
: public RGWOp
{
1764 RGWGetHealthCheck() = default;
1765 ~RGWGetHealthCheck() override
= default;
1767 int verify_permission() override
{
1771 void execute() override
;
1773 const string
name() override
{
1774 return "get_health_check";
1777 RGWOpType
get_type() override
{
1778 return RGW_OP_GET_HEALTH_CHECK
;
1781 uint32_t op_mask() override
{
1782 return RGW_OP_TYPE_READ
;
1787 class RGWDeleteMultiObj
: public RGWOp
{
1795 bool acl_allowed
= false;
1798 RGWDeleteMultiObj() {
1799 max_to_delete
= 1000;
1803 status_dumped
= false;
1805 int verify_permission() override
;
1806 void pre_exec() override
;
1807 void execute() override
;
1809 virtual int get_params() = 0;
1810 virtual void send_status() = 0;
1811 virtual void begin_response() = 0;
1812 virtual void send_partial_response(rgw_obj_key
& key
, bool delete_marker
,
1813 const string
& marker_version_id
, int ret
) = 0;
1814 virtual void end_response() = 0;
1815 const string
name() override
{ return "multi_object_delete"; }
1816 RGWOpType
get_type() override
{ return RGW_OP_DELETE_MULTI_OBJ
; }
1817 uint32_t op_mask() override
{ return RGW_OP_TYPE_DELETE
; }
1820 class RGWInfo
: public RGWOp
{
1822 RGWInfo() = default;
1823 ~RGWInfo() override
= default;
1825 int verify_permission() override
{ return 0; }
1826 const string
name() override
{ return "get info"; }
1827 RGWOpType
get_type() override
{ return RGW_OP_GET_INFO
; }
1828 uint32_t op_mask() override
{ return RGW_OP_TYPE_READ
; }
1831 extern int rgw_build_bucket_policies(RGWRados
* store
, struct req_state
* s
);
1832 extern int rgw_build_object_policies(RGWRados
*store
, struct req_state
*s
,
1833 bool prefetch_data
);
1834 extern rgw::IAM::Environment
rgw_build_iam_environment(RGWRados
* store
,
1835 struct req_state
* s
);
1837 static inline int put_data_and_throttle(RGWPutObjDataProcessor
*processor
,
1838 bufferlist
& data
, off_t ofs
,
1843 void *handle
= nullptr;
1846 uint64_t size
= data
.length();
1848 int ret
= processor
->handle_data(data
, ofs
, &handle
, &obj
, &again
);
1851 if (handle
!= nullptr)
1853 ret
= processor
->throttle_data(handle
, obj
, size
, need_to_wait
);
1859 need_to_wait
= false; /* the need to wait only applies to the first
1864 } /* put_data_and_throttle */
1870 static inline int get_system_versioning_params(req_state
*s
,
1871 uint64_t *olh_epoch
,
1874 if (!s
->system_request
) {
1879 string epoch_str
= s
->info
.args
.get(RGW_SYS_PARAM_PREFIX
"versioned-epoch");
1880 if (!epoch_str
.empty()) {
1882 *olh_epoch
= strict_strtol(epoch_str
.c_str(), 10, &err
);
1884 lsubdout(s
->cct
, rgw
, 0) << "failed to parse versioned-epoch param"
1892 *version_id
= s
->info
.args
.get(RGW_SYS_PARAM_PREFIX
"version-id");
1896 } /* get_system_versioning_params */
1898 static inline void format_xattr(std::string
&xattr
)
1900 /* If the extended attribute is not valid UTF-8, we encode it using
1901 * quoted-printable encoding.
1903 if ((check_utf8(xattr
.c_str(), xattr
.length()) != 0) ||
1904 (check_for_control_characters(xattr
.c_str(), xattr
.length()) != 0)) {
1905 static const char MIME_PREFIX_STR
[] = "=?UTF-8?Q?";
1906 static const int MIME_PREFIX_LEN
= sizeof(MIME_PREFIX_STR
) - 1;
1907 static const char MIME_SUFFIX_STR
[] = "?=";
1908 static const int MIME_SUFFIX_LEN
= sizeof(MIME_SUFFIX_STR
) - 1;
1909 int mlen
= mime_encode_as_qp(xattr
.c_str(), NULL
, 0);
1910 char *mime
= new char[MIME_PREFIX_LEN
+ mlen
+ MIME_SUFFIX_LEN
+ 1];
1911 strcpy(mime
, MIME_PREFIX_STR
);
1912 mime_encode_as_qp(xattr
.c_str(), mime
+ MIME_PREFIX_LEN
, mlen
);
1913 strcpy(mime
+ MIME_PREFIX_LEN
+ (mlen
- 1), MIME_SUFFIX_STR
);
1917 } /* format_xattr */
1920 * Get the HTTP request metadata out of the req_state as a
1921 * map(<attr_name, attr_contents>, where attr_name is RGW_ATTR_PREFIX.HTTP_NAME)
1922 * s: The request state
1923 * attrs: will be filled up with attrs mapped as <attr_name, attr_contents>
1924 * On success returns 0.
1925 * On failure returns a negative error code.
1928 static inline int rgw_get_request_metadata(CephContext
* const cct
,
1929 struct req_info
& info
,
1930 std::map
<std::string
, ceph::bufferlist
>& attrs
,
1931 const bool allow_empty_attrs
= true)
1933 static const std::set
<std::string
> blacklisted_headers
= {
1934 "x-amz-server-side-encryption-customer-algorithm",
1935 "x-amz-server-side-encryption-customer-key",
1936 "x-amz-server-side-encryption-customer-key-md5"
1939 size_t valid_meta_count
= 0;
1940 for (auto& kv
: info
.x_meta_map
) {
1941 const std::string
& name
= kv
.first
;
1942 std::string
& xattr
= kv
.second
;
1944 if (blacklisted_headers
.count(name
) == 1) {
1945 lsubdout(cct
, rgw
, 10) << "skipping x>> " << name
<< dendl
;
1947 } else if (allow_empty_attrs
|| !xattr
.empty()) {
1948 lsubdout(cct
, rgw
, 10) << "x>> " << name
<< ":" << xattr
<< dendl
;
1949 format_xattr(xattr
);
1951 std::string
attr_name(RGW_ATTR_PREFIX
);
1952 attr_name
.append(name
);
1954 /* Check roughly whether we aren't going behind the limit on attribute
1955 * name. Passing here doesn't guarantee that an OSD will accept that
1956 * as ObjectStore::get_max_attr_name_length() can set the limit even
1957 * lower than the "osd_max_attr_name_len" configurable. */
1958 const size_t max_attr_name_len
= \
1959 cct
->_conf
->get_val
<size_t>("rgw_max_attr_name_len");
1960 if (max_attr_name_len
&& attr_name
.length() > max_attr_name_len
) {
1961 return -ENAMETOOLONG
;
1964 /* Similar remarks apply to the check for value size. We're veryfing
1965 * it early at the RGW's side as it's being claimed in /info. */
1966 const size_t max_attr_size
= \
1967 cct
->_conf
->get_val
<size_t>("rgw_max_attr_size");
1968 if (max_attr_size
&& xattr
.length() > max_attr_size
) {
1972 /* Swift allows administrators to limit the number of metadats items
1973 * send _in a single request_. */
1974 const auto rgw_max_attrs_num_in_req
= \
1975 cct
->_conf
->get_val
<size_t>("rgw_max_attrs_num_in_req");
1976 if (rgw_max_attrs_num_in_req
&&
1977 ++valid_meta_count
> rgw_max_attrs_num_in_req
) {
1981 auto rval
= attrs
.emplace(std::move(attr_name
), ceph::bufferlist());
1982 /* At the moment the value of the freshly created attribute key-value
1983 * pair is an empty bufferlist. */
1985 ceph::bufferlist
& bl
= rval
.first
->second
;
1986 bl
.append(xattr
.c_str(), xattr
.size() + 1);
1991 } /* rgw_get_request_metadata */
1993 static inline void encode_delete_at_attr(boost::optional
<ceph::real_time
> delete_at
,
1994 map
<string
, bufferlist
>& attrs
)
1996 if (delete_at
== boost::none
) {
2001 ::encode(*delete_at
, delatbl
);
2002 attrs
[RGW_ATTR_DELETE_AT
] = delatbl
;
2003 } /* encode_delete_at_attr */
2005 static inline void encode_obj_tags_attr(RGWObjTags
* obj_tags
, map
<string
, bufferlist
>& attrs
)
2007 if (obj_tags
== nullptr){
2008 // we assume the user submitted a tag format which we couldn't parse since
2009 // this wouldn't be parsed later by get/put obj tags, lets delete if the
2010 // attr was populated
2015 obj_tags
->encode(tagsbl
);
2016 attrs
[RGW_ATTR_TAGS
] = tagsbl
;
2019 static inline int encode_dlo_manifest_attr(const char * const dlo_manifest
,
2020 map
<string
, bufferlist
>& attrs
)
2022 string dm
= dlo_manifest
;
2024 if (dm
.find('/') == string::npos
) {
2028 bufferlist manifest_bl
;
2029 manifest_bl
.append(dlo_manifest
, strlen(dlo_manifest
) + 1);
2030 attrs
[RGW_ATTR_USER_MANIFEST
] = manifest_bl
;
2033 } /* encode_dlo_manifest_attr */
2035 static inline void complete_etag(MD5
& hash
, string
*etag
)
2037 char etag_buf
[CEPH_CRYPTO_MD5_DIGESTSIZE
];
2038 char etag_buf_str
[CEPH_CRYPTO_MD5_DIGESTSIZE
* 2 + 16];
2040 hash
.Final((byte
*)etag_buf
);
2041 buf_to_hex((const unsigned char *)etag_buf
, CEPH_CRYPTO_MD5_DIGESTSIZE
,
2044 *etag
= etag_buf_str
;
2045 } /* complete_etag */
2047 class RGWSetAttrs
: public RGWOp
{
2049 map
<string
, buffer::list
> attrs
;
2053 ~RGWSetAttrs() override
{}
2055 void emplace_attr(std::string
&& key
, buffer::list
&& bl
) {
2056 attrs
.emplace(std::move(key
), std::move(bl
));
2059 int verify_permission() override
;
2060 void pre_exec() override
;
2061 void execute() override
;
2063 virtual int get_params() = 0;
2064 void send_response() override
= 0;
2065 const string
name() override
{ return "set_attrs"; }
2066 RGWOpType
get_type() override
{ return RGW_OP_SET_ATTRS
; }
2067 uint32_t op_mask() override
{ return RGW_OP_TYPE_WRITE
; }
2070 class RGWGetObjLayout
: public RGWOp
{
2072 RGWObjManifest
*manifest
{nullptr};
2073 rgw_raw_obj head_obj
;
2079 int check_caps(RGWUserCaps
& caps
) {
2080 return caps
.check_cap("admin", RGW_CAP_READ
);
2082 int verify_permission() {
2083 return check_caps(s
->user
->caps
);
2088 virtual void send_response() = 0;
2089 virtual const string
name() { return "get_obj_layout"; }
2090 virtual RGWOpType
get_type() { return RGW_OP_GET_OBJ_LAYOUT
; }
2091 virtual uint32_t op_mask() { return RGW_OP_TYPE_READ
; }
2094 class RGWPutBucketPolicy
: public RGWOp
{
2096 char *data
= nullptr;
2098 RGWPutBucketPolicy() = default;
2099 ~RGWPutBucketPolicy() {
2101 free(static_cast<void*>(data
));
2104 void send_response() override
;
2105 int verify_permission() override
;
2106 uint32_t op_mask() override
{
2107 return RGW_OP_TYPE_WRITE
;
2109 void execute() override
;
2111 const std::string
name() override
{
2112 return "put_bucket_policy";
2114 RGWOpType
get_type() override
{
2115 return RGW_OP_PUT_BUCKET_POLICY
;
2119 class RGWGetBucketPolicy
: public RGWOp
{
2120 buffer::list policy
;
2122 RGWGetBucketPolicy() = default;
2123 void send_response() override
;
2124 int verify_permission() override
;
2125 uint32_t op_mask() override
{
2126 return RGW_OP_TYPE_READ
;
2128 void execute() override
;
2129 const std::string
name() override
{
2130 return "get_bucket_policy";
2132 RGWOpType
get_type() override
{
2133 return RGW_OP_GET_BUCKET_POLICY
;
2137 class RGWDeleteBucketPolicy
: public RGWOp
{
2139 RGWDeleteBucketPolicy() = default;
2140 void send_response() override
;
2141 int verify_permission() override
;
2142 uint32_t op_mask() override
{
2143 return RGW_OP_TYPE_WRITE
;
2145 void execute() override
;
2147 const std::string
name() override
{
2148 return "delete_bucket_policy";
2150 RGWOpType
get_type() override
{
2151 return RGW_OP_DELETE_BUCKET_POLICY
;
2156 class RGWConfigBucketMetaSearch
: public RGWOp
{
2158 std::map
<std::string
, uint32_t> mdsearch_config
;
2160 RGWConfigBucketMetaSearch() {}
2162 int verify_permission();
2166 virtual int get_params() = 0;
2167 virtual void send_response() = 0;
2168 virtual const string
name() { return "config_bucket_meta_search"; }
2169 virtual RGWOpType
get_type() { return RGW_OP_CONFIG_BUCKET_META_SEARCH
; }
2170 virtual uint32_t op_mask() { return RGW_OP_TYPE_WRITE
; }
2173 class RGWGetBucketMetaSearch
: public RGWOp
{
2175 RGWGetBucketMetaSearch() {}
2177 int verify_permission();
2181 virtual void send_response() = 0;
2182 virtual const string
name() { return "get_bucket_meta_search"; }
2183 virtual RGWOpType
get_type() { return RGW_OP_GET_BUCKET_META_SEARCH
; }
2184 virtual uint32_t op_mask() { return RGW_OP_TYPE_READ
; }
2187 class RGWDelBucketMetaSearch
: public RGWOp
{
2189 RGWDelBucketMetaSearch() {}
2191 int verify_permission();
2195 virtual void send_response() = 0;
2196 virtual const string
name() { return "delete_bucket_meta_search"; }
2197 virtual RGWOpType
delete_type() { return RGW_OP_DEL_BUCKET_META_SEARCH
; }
2198 virtual uint32_t op_mask() { return RGW_OP_TYPE_WRITE
; }
2201 class RGWGetClusterStat
: public RGWOp
{
2203 struct rados_cluster_stat_t stats_op
;
2205 RGWGetClusterStat() {}
2207 void init(RGWRados
*store
, struct req_state
*s
, RGWHandler
*h
) override
{
2208 RGWOp::init(store
, s
, h
);
2210 int verify_permission() override
{return 0;}
2211 virtual void send_response() = 0;
2212 virtual int get_params() = 0;
2213 void execute() override
;
2214 virtual const string
name() { return "get_cluster_stat"; }
2219 #endif /* CEPH_RGW_OP_H */