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();
126 dialect_handler(nullptr),
132 virtual ~RGWOp() = default;
134 int get_ret() const { return op_ret
; }
136 virtual int init_processing() {
137 op_ret
= init_quota();
144 virtual void init(RGWRados
*store
, struct req_state
*s
, RGWHandler
*dialect_handler
) {
147 this->dialect_handler
= dialect_handler
;
149 int read_bucket_cors();
150 bool generate_cors_headers(string
& origin
, string
& method
, string
& headers
, string
& exp_headers
, unsigned *max_age
);
152 virtual int verify_params() { return 0; }
153 virtual bool prefetch_data() { return false; }
155 /* Authenticate requester -- verify its identity.
157 * NOTE: typically the procedure is common across all operations of the same
158 * dialect (S3, Swift API). However, there are significant exceptions in
159 * both APIs: browser uploads, /info and OPTIONS handlers. All of them use
160 * different, specific authentication schema driving the need for per-op
161 * authentication. The alternative is to duplicate parts of the method-
162 * dispatch logic in RGWHandler::authorize() and pollute it with a lot
163 * of special cases. */
164 virtual int verify_requester(const rgw::auth::StrategyRegistry
& auth_registry
) {
165 /* TODO(rzarzynski): rename RGWHandler::authorize to generic_authenticate. */
166 return dialect_handler
->authorize();
168 virtual int verify_permission() = 0;
169 virtual int verify_op_mask();
170 virtual void pre_exec() {}
171 virtual void execute() = 0;
172 virtual void send_response() {}
173 virtual void complete() {
176 virtual const string
name() = 0;
177 virtual RGWOpType
get_type() { return RGW_OP_UNKNOWN
; }
179 virtual uint32_t op_mask() { return 0; }
181 virtual int error_handler(int err_no
, string
*error_content
);
184 class RGWGetObj
: public RGWOp
{
186 seed torrent
; // get torrent
187 const char *range_str
;
189 const char *if_unmod
;
190 const char *if_match
;
191 const char *if_nomatch
;
192 uint32_t mod_zone_id
;
198 ceph::real_time mod_time
;
199 ceph::real_time lastmod
;
200 ceph::real_time unmod_time
;
201 ceph::real_time
*mod_ptr
;
202 ceph::real_time
*unmod_ptr
;
203 map
<string
, bufferlist
> attrs
;
205 bool partial_content
;
208 bool skip_decrypt
{false};
210 utime_t gc_invalidate_time
;
213 bool rgwx_stat
; /* extended rgw stat operation */
217 RGWCompressionInfo cs_info
;
218 off_t first_block
, last_block
;
242 partial_content
= false;
243 range_parsed
= false;
244 skip_manifest
= false;
254 bool prefetch_data() override
;
256 void set_get_data(bool get_data
) {
257 this->get_data
= get_data
;
259 int verify_permission() override
;
260 void pre_exec() override
;
261 void execute() override
;
262 int read_user_manifest_part(
264 const rgw_bucket_dir_entry
& ent
,
265 RGWAccessControlPolicy
* const bucket_acl
,
266 const boost::optional
<rgw::IAM::Policy
>& bucket_policy
,
267 const off_t start_ofs
,
268 const off_t end_ofs
);
269 int handle_user_manifest(const char *prefix
);
270 int handle_slo_manifest(bufferlist
& bl
);
272 int get_data_cb(bufferlist
& bl
, off_t ofs
, off_t len
);
274 virtual int get_params() = 0;
275 virtual int send_response_data_error() = 0;
276 virtual int send_response_data(bufferlist
& bl
, off_t ofs
, off_t len
) = 0;
278 const string
name() override
{ return "get_obj"; }
279 RGWOpType
get_type() override
{ return RGW_OP_GET_OBJ
; }
280 uint32_t op_mask() override
{ return RGW_OP_TYPE_READ
; }
281 virtual bool need_object_expiration() { return false; }
283 * calculates filter used to decrypt RGW objects data
285 virtual int get_decrypt_filter(std::unique_ptr
<RGWGetDataCB
>* filter
, RGWGetDataCB
* cb
, bufferlist
* manifest_bl
) {
291 class RGWGetObj_CB
: public RGWGetDataCB
295 explicit RGWGetObj_CB(RGWGetObj
*_op
) : op(_op
) {}
296 ~RGWGetObj_CB() override
{}
298 int handle_data(bufferlist
& bl
, off_t bl_ofs
, off_t bl_len
) override
{
299 return op
->get_data_cb(bl
, bl_ofs
, bl_len
);
303 class RGWGetObj_Filter
: public RGWGetDataCB
308 RGWGetObj_Filter(RGWGetDataCB
* next
): next(next
) {}
309 ~RGWGetObj_Filter() override
{}
311 * Passes data through filter.
312 * Filter can modify content of bl.
313 * When bl_len == 0 , it means 'flush
315 int handle_data(bufferlist
& bl
, off_t bl_ofs
, off_t bl_len
) override
{
316 return next
->handle_data(bl
, bl_ofs
, bl_len
);
319 * Flushes any cached data. Used by RGWGetObjFilter.
320 * Return logic same as handle_data.
322 int flush() override
{
323 return next
->flush();
326 * Allows filter to extend range required for successful filtering
328 int fixup_range(off_t
& ofs
, off_t
& end
) override
{
329 return next
->fixup_range(ofs
, end
);
333 class RGWGetObjTags
: public RGWOp
{
336 bool has_tags
{false};
338 int verify_permission();
342 virtual void send_response_data(bufferlist
& bl
) = 0;
343 virtual const string
name() noexcept override
{ return "get_obj_tags"; }
344 virtual uint32_t op_mask() { return RGW_OP_TYPE_READ
; }
345 RGWOpType
get_type() { return RGW_OP_GET_OBJ_TAGGING
; }
349 class RGWPutObjTags
: public RGWOp
{
353 int verify_permission();
356 virtual void send_response() = 0;
357 virtual int get_params() = 0;
358 virtual const string
name() { return "put_obj_tags"; }
359 virtual uint32_t op_mask() { return RGW_OP_TYPE_WRITE
; }
360 RGWOpType
get_type() { return RGW_OP_PUT_OBJ_TAGGING
; }
364 class RGWDeleteObjTags
: public RGWOp
{
367 int verify_permission();
370 virtual void send_response() = 0;
371 virtual const string
name() { return "delete_obj_tags"; }
372 virtual uint32_t op_mask() { return RGW_OP_TYPE_DELETE
; }
373 RGWOpType
get_type() { return RGW_OP_DELETE_OBJ_TAGGING
;}
376 class RGWBulkDelete
: public RGWOp
{
379 std::string bucket_name
;
390 unsigned int num_deleted
;
391 unsigned int num_unfound
;
392 std::list
<fail_desc_t
> failures
;
394 RGWRados
* const store
;
398 Deleter(RGWRados
* const str
, req_state
* const s
)
405 unsigned int get_num_deleted() const {
409 unsigned int get_num_unfound() const {
413 const std::list
<fail_desc_t
> get_failures() const {
417 bool verify_permission(RGWBucketInfo
& binfo
,
418 map
<string
, bufferlist
>& battrs
,
419 ACLOwner
& bucket_owner
/* out */);
420 bool delete_single(const acct_path_t
& path
);
421 bool delete_chunk(const std::list
<acct_path_t
>& paths
);
423 /* End of Deleter subclass */
425 static const size_t MAX_CHUNK_ENTRIES
= 1024;
428 std::unique_ptr
<Deleter
> deleter
;
435 int verify_permission() override
;
436 void pre_exec() override
;
437 void execute() override
;
439 virtual int get_data(std::list
<acct_path_t
>& items
,
440 bool * is_truncated
) = 0;
441 void send_response() override
= 0;
443 const string
name() override
{ return "bulk_delete"; }
444 RGWOpType
get_type() override
{ return RGW_OP_BULK_DELETE
; }
445 uint32_t op_mask() override
{ return RGW_OP_TYPE_DELETE
; }
448 inline ostream
& operator<<(ostream
& out
, const RGWBulkDelete::acct_path_t
&o
) {
449 return out
<< o
.bucket_name
<< "/" << o
.obj_key
;
453 class RGWBulkUploadOp
: public RGWOp
{
454 boost::optional
<RGWObjectCtx
> dir_ctx
;
459 fail_desc_t(const int err
, std::string path
)
461 path(std::move(path
)) {
465 const std::string path
;
468 static constexpr std::array
<int, 2> terminal_errors
= {
472 /* FIXME: boost::container::small_vector<fail_desc_t, 4> failures; */
473 std::vector
<fail_desc_t
> failures
;
477 class DecoratedStreamGetter
;
478 class AlignedStreamGetter
;
480 virtual std::unique_ptr
<StreamGetter
> create_stream() = 0;
481 virtual void send_response() = 0;
483 boost::optional
<std::pair
<std::string
, rgw_obj_key
>>
484 parse_path(const boost::string_ref
& path
);
486 std::pair
<std::string
, std::string
>
487 handle_upload_path(struct req_state
*s
);
489 bool handle_file_verify_permission(RGWBucketInfo
& binfo
,
491 std::map
<std::string
, ceph::bufferlist
>& battrs
,
492 ACLOwner
& bucket_owner
/* out */);
493 int handle_file(boost::string_ref path
,
495 AlignedStreamGetter
& body
);
497 int handle_dir_verify_permission();
498 int handle_dir(boost::string_ref path
);
505 void init(RGWRados
* const store
,
506 struct req_state
* const s
,
507 RGWHandler
* const h
) override
{
508 RGWOp::init(store
, s
, h
);
509 dir_ctx
.emplace(store
);
512 int verify_permission() override
;
513 void pre_exec() override
;
514 void execute() override
;
516 const std::string
name() override
{
517 return "bulk_upload";
520 RGWOpType
get_type() override
{
521 return RGW_OP_BULK_UPLOAD
;
524 uint32_t op_mask() override
{
525 return RGW_OP_TYPE_WRITE
;
527 }; /* RGWBulkUploadOp */
530 class RGWBulkUploadOp::StreamGetter
{
532 StreamGetter() = default;
533 virtual ~StreamGetter() = default;
535 virtual ssize_t
get_at_most(size_t want
, ceph::bufferlist
& dst
) = 0;
536 virtual ssize_t
get_exactly(size_t want
, ceph::bufferlist
& dst
) = 0;
537 }; /* End of nested subclass StreamGetter */
540 class RGWBulkUploadOp::DecoratedStreamGetter
: public StreamGetter
{
541 StreamGetter
& decoratee
;
544 StreamGetter
& get_decoratee() {
549 DecoratedStreamGetter(StreamGetter
& decoratee
)
550 : decoratee(decoratee
) {
552 virtual ~DecoratedStreamGetter() = default;
554 ssize_t
get_at_most(const size_t want
, ceph::bufferlist
& dst
) override
{
555 return get_decoratee().get_at_most(want
, dst
);
558 ssize_t
get_exactly(const size_t want
, ceph::bufferlist
& dst
) override
{
559 return get_decoratee().get_exactly(want
, dst
);
561 }; /* RGWBulkUploadOp::DecoratedStreamGetter */
564 class RGWBulkUploadOp::AlignedStreamGetter
565 : public RGWBulkUploadOp::DecoratedStreamGetter
{
571 template <typename U
>
572 AlignedStreamGetter(const size_t position
,
574 const size_t alignment
,
576 : DecoratedStreamGetter(std::forward
<U
>(decoratee
)),
579 alignment(alignment
) {
581 virtual ~AlignedStreamGetter();
582 ssize_t
get_at_most(size_t want
, ceph::bufferlist
& dst
) override
;
583 ssize_t
get_exactly(size_t want
, ceph::bufferlist
& dst
) override
;
584 }; /* RGWBulkUploadOp::AlignedStreamGetter */
587 struct RGWUsageStats
{
588 uint64_t bytes_used
= 0;
589 uint64_t bytes_used_rounded
= 0;
590 uint64_t buckets_count
= 0;
591 uint64_t objects_count
= 0;
594 #define RGW_LIST_BUCKETS_LIMIT_MAX 10000
596 class RGWListBuckets
: public RGWOp
{
600 std::string end_marker
;
603 std::map
<std::string
, ceph::bufferlist
> attrs
;
606 RGWUsageStats global_stats
;
607 std::map
<std::string
, RGWUsageStats
> policies_stats
;
609 virtual uint64_t get_default_max() const {
616 limit(RGW_LIST_BUCKETS_LIMIT_MAX
),
617 limit_max(RGW_LIST_BUCKETS_LIMIT_MAX
),
618 is_truncated(false) {
621 int verify_permission() override
;
622 void execute() override
;
624 virtual int get_params() = 0;
625 virtual void handle_listing_chunk(RGWUserBuckets
&& buckets
) {
626 /* The default implementation, used by e.g. S3, just generates a new
627 * part of listing and sends it client immediately. Swift can behave
628 * differently: when the reverse option is requested, all incoming
629 * instances of RGWUserBuckets are buffered and finally reversed. */
630 return send_response_data(buckets
);
632 virtual void send_response_begin(bool has_buckets
) = 0;
633 virtual void send_response_data(RGWUserBuckets
& buckets
) = 0;
634 virtual void send_response_end() = 0;
635 void send_response() override
{}
637 virtual bool should_get_stats() { return false; }
638 virtual bool supports_account_metadata() { return false; }
640 const string
name() override
{ return "list_buckets"; }
641 RGWOpType
get_type() override
{ return RGW_OP_LIST_BUCKETS
; }
642 uint32_t op_mask() override
{ return RGW_OP_TYPE_READ
; }
645 class RGWGetUsage
: public RGWOp
{
650 int show_log_entries
;
652 map
<string
, bool> categories
;
653 map
<rgw_user_bucket
, rgw_usage_log_entry
> usage
;
654 map
<string
, rgw_usage_log_entry
> summary_map
;
655 map
<string
, cls_user_bucket_entry
> buckets_usage
;
656 cls_user_header header
;
658 RGWGetUsage() : sent_data(false), show_log_entries(true), show_log_sum(true){
661 int verify_permission() override
;
662 void execute() override
;
664 virtual int get_params() = 0;
665 void send_response() override
{}
667 virtual bool should_get_stats() { return false; }
669 const string
name() override
{ return "get_usage"; }
670 uint32_t op_mask() override
{ return RGW_OP_TYPE_READ
; }
673 class RGWStatAccount
: public RGWOp
{
675 RGWUsageStats global_stats
;
676 std::map
<std::string
, RGWUsageStats
> policies_stats
;
679 RGWStatAccount() = default;
681 int verify_permission() override
;
682 void execute() override
;
684 void send_response() override
= 0;
685 const std::string
name() override
{ return "stat_account"; }
686 RGWOpType
get_type() override
{ return RGW_OP_STAT_ACCOUNT
; }
687 uint32_t op_mask() override
{ return RGW_OP_TYPE_READ
; }
690 class RGWListBucket
: public RGWOp
{
695 rgw_obj_key next_marker
;
696 rgw_obj_key end_marker
;
699 string encoding_type
;
702 vector
<rgw_bucket_dir_entry
> objs
;
703 map
<string
, bool> common_prefixes
;
710 int parse_max_keys();
713 RGWListBucket() : list_versions(false), max(0),
714 default_max(0), is_truncated(false), shard_id(-1) {}
715 int verify_permission() override
;
716 void pre_exec() override
;
717 void execute() override
;
719 virtual int get_params() = 0;
720 void send_response() override
= 0;
721 const string
name() override
{ return "list_bucket"; }
722 RGWOpType
get_type() override
{ return RGW_OP_LIST_BUCKET
; }
723 uint32_t op_mask() override
{ return RGW_OP_TYPE_READ
; }
724 virtual bool need_container_stats() { return false; }
727 class RGWGetBucketLogging
: public RGWOp
{
729 RGWGetBucketLogging() {}
730 int verify_permission() override
;
731 void execute() override
{ }
733 void send_response() override
= 0;
734 const string
name() override
{ return "get_bucket_logging"; }
735 RGWOpType
get_type() override
{ return RGW_OP_GET_BUCKET_LOGGING
; }
736 uint32_t op_mask() override
{ return RGW_OP_TYPE_READ
; }
739 class RGWGetBucketLocation
: public RGWOp
{
741 RGWGetBucketLocation() {}
742 ~RGWGetBucketLocation() override
{}
743 int verify_permission() override
;
744 void execute() override
{ }
746 void send_response() override
= 0;
747 const string
name() override
{ return "get_bucket_location"; }
748 RGWOpType
get_type() override
{ return RGW_OP_GET_BUCKET_LOCATION
; }
749 uint32_t op_mask() override
{ return RGW_OP_TYPE_READ
; }
752 class RGWGetBucketVersioning
: public RGWOp
{
755 bool versioning_enabled
;
757 RGWGetBucketVersioning() : versioned(false), versioning_enabled(false) {}
759 int verify_permission() override
;
760 void pre_exec() override
;
761 void execute() override
;
763 void send_response() override
= 0;
764 const string
name() override
{ return "get_bucket_versioning"; }
765 RGWOpType
get_type() override
{ return RGW_OP_GET_BUCKET_VERSIONING
; }
766 uint32_t op_mask() override
{ return RGW_OP_TYPE_READ
; }
769 class RGWSetBucketVersioning
: public RGWOp
{
771 bool enable_versioning
;
774 RGWSetBucketVersioning() : enable_versioning(false) {}
776 int verify_permission() override
;
777 void pre_exec() override
;
778 void execute() override
;
780 virtual int get_params() { return 0; }
782 void send_response() override
= 0;
783 const string
name() override
{ return "set_bucket_versioning"; }
784 RGWOpType
get_type() override
{ return RGW_OP_SET_BUCKET_VERSIONING
; }
785 uint32_t op_mask() override
{ return RGW_OP_TYPE_WRITE
; }
788 class RGWGetBucketWebsite
: public RGWOp
{
790 RGWGetBucketWebsite() {}
792 int verify_permission() override
;
793 void pre_exec() override
;
794 void execute() override
;
796 void send_response() override
= 0;
797 const string
name() override
{ return "get_bucket_website"; }
798 RGWOpType
get_type() override
{ return RGW_OP_GET_BUCKET_WEBSITE
; }
799 uint32_t op_mask() override
{ return RGW_OP_TYPE_READ
; }
802 class RGWSetBucketWebsite
: public RGWOp
{
805 RGWBucketWebsiteConf website_conf
;
807 RGWSetBucketWebsite() {}
809 int verify_permission() override
;
810 void pre_exec() override
;
811 void execute() override
;
813 virtual int get_params() { return 0; }
815 void send_response() override
= 0;
816 const string
name() override
{ return "set_bucket_website"; }
817 RGWOpType
get_type() override
{ return RGW_OP_SET_BUCKET_WEBSITE
; }
818 uint32_t op_mask() override
{ return RGW_OP_TYPE_WRITE
; }
821 class RGWDeleteBucketWebsite
: public RGWOp
{
823 RGWDeleteBucketWebsite() {}
825 int verify_permission() override
;
826 void pre_exec() override
;
827 void execute() override
;
829 void send_response() override
= 0;
830 const string
name() override
{ return "delete_bucket_website"; }
831 RGWOpType
get_type() override
{ return RGW_OP_SET_BUCKET_WEBSITE
; }
832 uint32_t op_mask() override
{ return RGW_OP_TYPE_WRITE
; }
835 class RGWStatBucket
: public RGWOp
{
841 ~RGWStatBucket() override
{}
843 int verify_permission() override
;
844 void pre_exec() override
;
845 void execute() override
;
847 void send_response() override
= 0;
848 const string
name() override
{ return "stat_bucket"; }
849 RGWOpType
get_type() override
{ return RGW_OP_STAT_BUCKET
; }
850 uint32_t op_mask() override
{ return RGW_OP_TYPE_READ
; }
853 class RGWCreateBucket
: public RGWOp
{
855 RGWAccessControlPolicy policy
;
856 string location_constraint
;
857 string placement_rule
;
861 RGWCORSConfiguration cors_config
;
862 boost::optional
<std::string
> swift_ver_location
;
863 map
<string
, buffer::list
> attrs
;
864 set
<string
> rmattr_names
;
868 virtual bool need_metadata_upload() const { return false; }
871 RGWCreateBucket() : has_cors(false) {}
873 void emplace_attr(std::string
&& key
, buffer::list
&& bl
) {
874 attrs
.emplace(std::move(key
), std::move(bl
)); /* key and bl are r-value refs */
877 int verify_permission() override
;
878 void pre_exec() override
;
879 void execute() override
;
880 void init(RGWRados
*store
, struct req_state
*s
, RGWHandler
*h
) override
{
881 RGWOp::init(store
, s
, h
);
882 policy
.set_ctx(s
->cct
);
884 virtual int get_params() { return 0; }
885 void send_response() override
= 0;
886 const string
name() override
{ return "create_bucket"; }
887 RGWOpType
get_type() override
{ return RGW_OP_CREATE_BUCKET
; }
888 uint32_t op_mask() override
{ return RGW_OP_TYPE_WRITE
; }
891 class RGWDeleteBucket
: public RGWOp
{
893 RGWObjVersionTracker objv_tracker
;
898 int verify_permission() override
;
899 void pre_exec() override
;
900 void execute() override
;
902 void send_response() override
= 0;
903 const string
name() override
{ return "delete_bucket"; }
904 RGWOpType
get_type() override
{ return RGW_OP_DELETE_BUCKET
; }
905 uint32_t op_mask() override
{ return RGW_OP_TYPE_DELETE
; }
908 struct rgw_slo_entry
{
913 rgw_slo_entry() : size_bytes(0) {}
915 void encode(bufferlist
& bl
) const {
916 ENCODE_START(1, 1, bl
);
919 ::encode(size_bytes
, bl
);
923 void decode(bufferlist::iterator
& bl
) {
927 ::decode(size_bytes
, bl
);
931 void decode_json(JSONObj
*obj
);
933 WRITE_CLASS_ENCODER(rgw_slo_entry
)
936 vector
<rgw_slo_entry
> entries
;
943 RGWSLOInfo() : total_size(0), raw_data(NULL
), raw_data_len(0) {}
948 void encode(bufferlist
& bl
) const {
949 ENCODE_START(1, 1, bl
);
950 ::encode(entries
, bl
);
951 ::encode(total_size
, bl
);
955 void decode(bufferlist::iterator
& bl
) {
957 ::decode(entries
, bl
);
958 ::decode(total_size
, bl
);
962 WRITE_CLASS_ENCODER(RGWSLOInfo
)
964 class RGWPutObj
: public RGWOp
{
966 friend class RGWPutObjProcessor
;
971 const char *supplied_md5_b64
;
972 const char *supplied_etag
;
973 const char *if_match
;
974 const char *if_nomatch
;
975 const char *copy_source
;
976 const char *copy_source_range
;
977 RGWBucketInfo copy_source_bucket_info
;
978 string copy_source_tenant_name
;
979 string copy_source_bucket_name
;
980 string copy_source_object_name
;
981 string copy_source_version_id
;
982 off_t copy_source_range_fst
;
983 off_t copy_source_range_lst
;
986 RGWAccessControlPolicy policy
;
987 std::unique_ptr
<RGWObjTags
> obj_tags
;
988 const char *dlo_manifest
;
989 RGWSLOInfo
*slo_info
;
990 map
<string
, bufferlist
> attrs
;
991 ceph::real_time mtime
;
995 map
<string
, string
> crypt_http_responses
;
998 boost::optional
<ceph::real_time
> delete_at
;
1001 RGWPutObj() : ofs(0),
1002 supplied_md5_b64(NULL
),
1003 supplied_etag(NULL
),
1007 copy_source_range(NULL
),
1008 copy_source_range_fst(0),
1009 copy_source_range_lst(0),
1015 ~RGWPutObj() override
{
1019 void init(RGWRados
*store
, struct req_state
*s
, RGWHandler
*h
) override
{
1020 RGWOp::init(store
, s
, h
);
1021 policy
.set_ctx(s
->cct
);
1024 void emplace_attr(std::string
&& key
, buffer::list
&& bl
) {
1025 attrs
.emplace(std::move(key
), std::move(bl
)); /* key and bl are r-value refs */
1028 virtual RGWPutObjProcessor
*select_processor(RGWObjectCtx
& obj_ctx
, bool *is_multipart
);
1029 void dispose_processor(RGWPutObjDataProcessor
*processor
);
1031 int verify_permission() override
;
1032 void pre_exec() override
;
1033 void execute() override
;
1035 /* this is for cases when copying data from other object */
1036 virtual int get_decrypt_filter(std::unique_ptr
<RGWGetDataCB
>* filter
,
1038 map
<string
, bufferlist
>& attrs
,
1039 bufferlist
* manifest_bl
) {
1043 virtual int get_encrypt_filter(std::unique_ptr
<RGWPutObjDataProcessor
> *filter
, RGWPutObjDataProcessor
* cb
) {
1048 int get_data_cb(bufferlist
& bl
, off_t bl_ofs
, off_t bl_len
);
1049 int get_data(const off_t fst
, const off_t lst
, bufferlist
& bl
);
1051 virtual int get_params() = 0;
1052 virtual int get_data(bufferlist
& bl
) = 0;
1053 void send_response() override
= 0;
1054 const string
name() override
{ return "put_obj"; }
1055 RGWOpType
get_type() override
{ return RGW_OP_PUT_OBJ
; }
1056 uint32_t op_mask() override
{ return RGW_OP_TYPE_WRITE
; }
1059 class RGWPutObj_Filter
: public RGWPutObjDataProcessor
1062 RGWPutObjDataProcessor
* next
;
1064 RGWPutObj_Filter(RGWPutObjDataProcessor
* next
) :
1066 ~RGWPutObj_Filter() override
{}
1067 int handle_data(bufferlist
& bl
, off_t ofs
, void **phandle
, rgw_raw_obj
*pobj
, bool *again
) override
{
1068 return next
->handle_data(bl
, ofs
, phandle
, pobj
, again
);
1070 int throttle_data(void *handle
, const rgw_raw_obj
& obj
, uint64_t size
, bool need_to_wait
) override
{
1071 return next
->throttle_data(handle
, obj
, size
, need_to_wait
);
1073 }; /* RGWPutObj_Filter */
1075 class RGWPostObj
: public RGWOp
{
1081 const char *supplied_md5_b64
;
1082 const char *supplied_etag
;
1084 RGWAccessControlPolicy policy
;
1085 map
<string
, bufferlist
> attrs
;
1086 boost::optional
<ceph::real_time
> delete_at
;
1088 /* Must be called after get_data() or the result is undefined. */
1089 virtual std::string
get_current_filename() const = 0;
1090 virtual std::string
get_current_content_type() const = 0;
1091 virtual bool is_next_file_to_upload() {
1095 RGWPostObj() : min_len(0),
1099 supplied_md5_b64(nullptr),
1100 supplied_etag(nullptr) {
1103 void emplace_attr(std::string
&& key
, buffer::list
&& bl
) {
1104 attrs
.emplace(std::move(key
), std::move(bl
)); /* key and bl are r-value refs */
1107 void init(RGWRados
*store
, struct req_state
*s
, RGWHandler
*h
) override
{
1108 RGWOp::init(store
, s
, h
);
1109 policy
.set_ctx(s
->cct
);
1112 int verify_permission() override
;
1113 void pre_exec() override
;
1114 void execute() override
;
1116 virtual int get_encrypt_filter(std::unique_ptr
<RGWPutObjDataProcessor
> *filter
, RGWPutObjDataProcessor
* cb
) {
1120 virtual int get_params() = 0;
1121 virtual int get_data(ceph::bufferlist
& bl
, bool& again
) = 0;
1122 void send_response() override
= 0;
1123 const std::string
name() override
{ return "post_obj"; }
1124 RGWOpType
get_type() override
{ return RGW_OP_POST_OBJ
; }
1125 uint32_t op_mask() override
{ return RGW_OP_TYPE_WRITE
; }
1128 class RGWPutMetadataAccount
: public RGWOp
{
1130 std::set
<std::string
> rmattr_names
;
1131 std::map
<std::string
, bufferlist
> attrs
, orig_attrs
;
1132 std::map
<int, std::string
> temp_url_keys
;
1133 RGWQuotaInfo new_quota
;
1134 bool new_quota_extracted
;
1136 RGWObjVersionTracker acct_op_tracker
;
1138 RGWAccessControlPolicy policy
;
1142 RGWPutMetadataAccount()
1143 : new_quota_extracted(false),
1147 void init(RGWRados
*store
, struct req_state
*s
, RGWHandler
*h
) override
{
1148 RGWOp::init(store
, s
, h
);
1149 policy
.set_ctx(s
->cct
);
1151 int init_processing() override
;
1152 int verify_permission() override
;
1153 void pre_exec() override
{ }
1154 void execute() override
;
1156 virtual int get_params() = 0;
1157 void send_response() override
= 0;
1158 virtual void filter_out_temp_url(map
<string
, bufferlist
>& add_attrs
,
1159 const set
<string
>& rmattr_names
,
1160 map
<int, string
>& temp_url_keys
);
1161 const string
name() override
{ return "put_account_metadata"; }
1162 RGWOpType
get_type() override
{ return RGW_OP_PUT_METADATA_ACCOUNT
; }
1163 uint32_t op_mask() override
{ return RGW_OP_TYPE_WRITE
; }
1166 class RGWPutMetadataBucket
: public RGWOp
{
1168 map
<string
, buffer::list
> attrs
;
1169 set
<string
> rmattr_names
;
1170 bool has_policy
, has_cors
;
1171 uint32_t policy_rw_mask
;
1172 RGWAccessControlPolicy policy
;
1173 RGWCORSConfiguration cors_config
;
1174 string placement_rule
;
1175 boost::optional
<std::string
> swift_ver_location
;
1178 RGWPutMetadataBucket()
1179 : has_policy(false), has_cors(false), policy_rw_mask(0)
1182 void emplace_attr(std::string
&& key
, buffer::list
&& bl
) {
1183 attrs
.emplace(std::move(key
), std::move(bl
)); /* key and bl are r-value refs */
1186 void init(RGWRados
*store
, struct req_state
*s
, RGWHandler
*h
) override
{
1187 RGWOp::init(store
, s
, h
);
1188 policy
.set_ctx(s
->cct
);
1191 int verify_permission() override
;
1192 void pre_exec() override
;
1193 void execute() override
;
1195 virtual int get_params() = 0;
1196 void send_response() override
= 0;
1197 const string
name() override
{ return "put_bucket_metadata"; }
1198 RGWOpType
get_type() override
{ return RGW_OP_PUT_METADATA_BUCKET
; }
1199 uint32_t op_mask() override
{ return RGW_OP_TYPE_WRITE
; }
1202 class RGWPutMetadataObject
: public RGWOp
{
1204 RGWAccessControlPolicy policy
;
1205 string placement_rule
;
1206 boost::optional
<ceph::real_time
> delete_at
;
1207 const char *dlo_manifest
;
1210 RGWPutMetadataObject()
1211 : dlo_manifest(NULL
)
1214 void init(RGWRados
*store
, struct req_state
*s
, RGWHandler
*h
) override
{
1215 RGWOp::init(store
, s
, h
);
1216 policy
.set_ctx(s
->cct
);
1218 int verify_permission() override
;
1219 void pre_exec() override
;
1220 void execute() override
;
1222 virtual int get_params() = 0;
1223 void send_response() override
= 0;
1224 const string
name() override
{ return "put_obj_metadata"; }
1225 RGWOpType
get_type() override
{ return RGW_OP_PUT_METADATA_OBJECT
; }
1226 uint32_t op_mask() override
{ return RGW_OP_TYPE_WRITE
; }
1227 virtual bool need_object_expiration() { return false; }
1230 class RGWDeleteObj
: public RGWOp
{
1233 bool multipart_delete
;
1235 ceph::real_time unmod_since
; /* if unmodified since */
1236 bool no_precondition_error
;
1237 std::unique_ptr
<RGWBulkDelete::Deleter
> deleter
;
1241 : delete_marker(false),
1242 multipart_delete(false),
1243 no_precondition_error(false),
1247 int verify_permission() override
;
1248 void pre_exec() override
;
1249 void execute() override
;
1250 int handle_slo_manifest(bufferlist
& bl
);
1252 virtual int get_params() { return 0; }
1253 void send_response() override
= 0;
1254 const string
name() override
{ return "delete_obj"; }
1255 RGWOpType
get_type() override
{ return RGW_OP_DELETE_OBJ
; }
1256 uint32_t op_mask() override
{ return RGW_OP_TYPE_DELETE
; }
1257 virtual bool need_object_expiration() { return false; }
1260 class RGWCopyObj
: public RGWOp
{
1262 RGWAccessControlPolicy dest_policy
;
1264 const char *if_unmod
;
1265 const char *if_match
;
1266 const char *if_nomatch
;
1270 ceph::real_time mod_time
;
1271 ceph::real_time unmod_time
;
1272 ceph::real_time
*mod_ptr
;
1273 ceph::real_time
*unmod_ptr
;
1274 map
<string
, buffer::list
> attrs
;
1275 string src_tenant_name
, src_bucket_name
;
1276 rgw_bucket src_bucket
;
1277 rgw_obj_key src_object
;
1278 string dest_tenant_name
, dest_bucket_name
;
1279 rgw_bucket dest_bucket
;
1281 ceph::real_time src_mtime
;
1282 ceph::real_time mtime
;
1283 RGWRados::AttrsMod attrs_mod
;
1284 RGWBucketInfo src_bucket_info
;
1285 RGWBucketInfo dest_bucket_info
;
1289 ceph::buffer::list etag
;
1296 boost::optional
<ceph::real_time
> delete_at
;
1312 attrs_mod
= RGWRados::ATTRSMOD_NONE
;
1315 copy_if_newer
= false;
1318 static bool parse_copy_location(const string
& src
,
1319 string
& bucket_name
,
1320 rgw_obj_key
& object
);
1322 void emplace_attr(std::string
&& key
, buffer::list
&& bl
) {
1323 attrs
.emplace(std::move(key
), std::move(bl
));
1326 void init(RGWRados
*store
, struct req_state
*s
, RGWHandler
*h
) override
{
1327 RGWOp::init(store
, s
, h
);
1328 dest_policy
.set_ctx(s
->cct
);
1330 int verify_permission() override
;
1331 void pre_exec() override
;
1332 void execute() override
;
1333 void progress_cb(off_t ofs
);
1335 virtual int init_dest_policy() { return 0; }
1336 virtual int get_params() = 0;
1337 virtual void send_partial_response(off_t ofs
) {}
1338 void send_response() override
= 0;
1339 const string
name() override
{ return "copy_obj"; }
1340 RGWOpType
get_type() override
{ return RGW_OP_COPY_OBJ
; }
1341 uint32_t op_mask() override
{ return RGW_OP_TYPE_WRITE
; }
1344 class RGWGetACLs
: public RGWOp
{
1351 int verify_permission() override
;
1352 void pre_exec() override
;
1353 void execute() override
;
1355 void send_response() override
= 0;
1356 const string
name() override
{ return "get_acls"; }
1357 RGWOpType
get_type() override
{ return RGW_OP_GET_ACLS
; }
1358 uint32_t op_mask() override
{ return RGW_OP_TYPE_READ
; }
1361 class RGWPutACLs
: public RGWOp
{
1372 ~RGWPutACLs() override
{
1376 int verify_permission() override
;
1377 void pre_exec() override
;
1378 void execute() override
;
1380 virtual int get_policy_from_state(RGWRados
*store
, struct req_state
*s
, stringstream
& ss
) { return 0; }
1381 virtual int get_params() = 0;
1382 void send_response() override
= 0;
1383 const string
name() override
{ return "put_acls"; }
1384 RGWOpType
get_type() override
{ return RGW_OP_PUT_ACLS
; }
1385 uint32_t op_mask() override
{ return RGW_OP_TYPE_WRITE
; }
1388 class RGWGetLC
: public RGWOp
{
1393 ~RGWGetLC() override
{ }
1395 int verify_permission() override
;
1396 void pre_exec() override
;
1397 void execute() override
= 0;
1399 void send_response() override
= 0;
1400 const string
name() override
{ return "get_lifecycle"; }
1401 RGWOpType
get_type() override
{ return RGW_OP_GET_LC
; }
1402 uint32_t op_mask() override
{ return RGW_OP_TYPE_READ
; }
1405 class RGWPutLC
: public RGWOp
{
1416 ~RGWPutLC() override
{
1420 void init(RGWRados
*store
, struct req_state
*s
, RGWHandler
*dialect_handler
) override
{
1421 #define COOKIE_LEN 16
1422 char buf
[COOKIE_LEN
+ 1];
1424 RGWOp::init(store
, s
, dialect_handler
);
1425 gen_rand_alphanumeric(s
->cct
, buf
, sizeof(buf
) - 1);
1429 int verify_permission() override
;
1430 void pre_exec() override
;
1431 void execute() override
;
1433 // virtual int get_policy_from_state(RGWRados *store, struct req_state *s, stringstream& ss) { return 0; }
1434 virtual int get_params() = 0;
1435 void send_response() override
= 0;
1436 const string
name() override
{ return "put_lifecycle"; }
1437 RGWOpType
get_type() override
{ return RGW_OP_PUT_LC
; }
1438 uint32_t op_mask() override
{ return RGW_OP_TYPE_WRITE
; }
1441 class RGWDeleteLC
: public RGWOp
{
1451 ~RGWDeleteLC() override
{
1455 int verify_permission() override
;
1456 void pre_exec() override
;
1457 void execute() override
;
1459 void send_response() override
= 0;
1460 const string
name() override
{ return "delete_lifecycle"; }
1461 RGWOpType
get_type() override
{ return RGW_OP_DELETE_LC
; }
1462 uint32_t op_mask() override
{ return RGW_OP_TYPE_WRITE
; }
1465 class RGWGetCORS
: public RGWOp
{
1471 int verify_permission() override
;
1472 void execute() override
;
1474 void send_response() override
= 0;
1475 const string
name() override
{ return "get_cors"; }
1476 RGWOpType
get_type() override
{ return RGW_OP_GET_CORS
; }
1477 uint32_t op_mask() override
{ return RGW_OP_TYPE_READ
; }
1480 class RGWPutCORS
: public RGWOp
{
1487 ~RGWPutCORS() override
{}
1489 int verify_permission() override
;
1490 void execute() override
;
1492 virtual int get_params() = 0;
1493 void send_response() override
= 0;
1494 const string
name() override
{ return "put_cors"; }
1495 RGWOpType
get_type() override
{ return RGW_OP_PUT_CORS
; }
1496 uint32_t op_mask() override
{ return RGW_OP_TYPE_WRITE
; }
1499 class RGWDeleteCORS
: public RGWOp
{
1505 int verify_permission() override
;
1506 void execute() override
;
1508 void send_response() override
= 0;
1509 const string
name() override
{ return "delete_cors"; }
1510 RGWOpType
get_type() override
{ return RGW_OP_DELETE_CORS
; }
1511 uint32_t op_mask() override
{ return RGW_OP_TYPE_WRITE
; }
1514 class RGWOptionsCORS
: public RGWOp
{
1517 const char *origin
, *req_hdrs
, *req_meth
;
1520 RGWOptionsCORS() : rule(NULL
), origin(NULL
),
1521 req_hdrs(NULL
), req_meth(NULL
) {
1524 int verify_permission() override
{return 0;}
1525 int validate_cors_request(RGWCORSConfiguration
*cc
);
1526 void execute() override
;
1527 void get_response_params(string
& allowed_hdrs
, string
& exp_hdrs
, unsigned *max_age
);
1528 void send_response() override
= 0;
1529 const string
name() override
{ return "options_cors"; }
1530 RGWOpType
get_type() override
{ return RGW_OP_OPTIONS_CORS
; }
1531 uint32_t op_mask() override
{ return RGW_OP_TYPE_READ
; }
1534 class RGWGetRequestPayment
: public RGWOp
{
1536 bool requester_pays
;
1539 RGWGetRequestPayment() : requester_pays(0) {}
1541 int verify_permission() override
;
1542 void pre_exec() override
;
1543 void execute() override
;
1545 void send_response() override
= 0;
1546 const string
name() override
{ return "get_request_payment"; }
1547 RGWOpType
get_type() override
{ return RGW_OP_GET_REQUEST_PAYMENT
; }
1548 uint32_t op_mask() override
{ return RGW_OP_TYPE_READ
; }
1551 class RGWSetRequestPayment
: public RGWOp
{
1553 bool requester_pays
;
1555 RGWSetRequestPayment() : requester_pays(false) {}
1557 int verify_permission() override
;
1558 void pre_exec() override
;
1559 void execute() override
;
1561 virtual int get_params() { return 0; }
1563 void send_response() override
= 0;
1564 const string
name() override
{ return "set_request_payment"; }
1565 RGWOpType
get_type() override
{ return RGW_OP_SET_REQUEST_PAYMENT
; }
1566 uint32_t op_mask() override
{ return RGW_OP_TYPE_WRITE
; }
1569 class RGWInitMultipart
: public RGWOp
{
1572 RGWAccessControlPolicy policy
;
1575 RGWInitMultipart() {}
1577 void init(RGWRados
*store
, struct req_state
*s
, RGWHandler
*h
) override
{
1578 RGWOp::init(store
, s
, h
);
1579 policy
.set_ctx(s
->cct
);
1581 int verify_permission() override
;
1582 void pre_exec() override
;
1583 void execute() override
;
1585 virtual int get_params() = 0;
1586 void send_response() override
= 0;
1587 const string
name() override
{ return "init_multipart"; }
1588 RGWOpType
get_type() override
{ return RGW_OP_INIT_MULTIPART
; }
1589 uint32_t op_mask() override
{ return RGW_OP_TYPE_WRITE
; }
1590 virtual int prepare_encryption(map
<string
, bufferlist
>& attrs
) { return 0; }
1593 class RGWCompleteMultipart
: public RGWOp
{
1600 struct MPSerializer
{
1601 librados::IoCtx ioctx
;
1602 rados::cls::lock::Lock lock
;
1603 librados::ObjectWriteOperation op
;
1607 MPSerializer() : lock("RGWCompleteMultipart"), locked(false)
1610 int try_lock(const std::string
& oid
, utime_t dur
);
1613 return lock
.unlock(&ioctx
, oid
);
1616 void clear_locked() {
1622 RGWCompleteMultipart() {
1626 ~RGWCompleteMultipart() override
{
1630 int verify_permission() override
;
1631 void pre_exec() override
;
1632 void execute() override
;
1633 void complete() override
;
1635 virtual int get_params() = 0;
1636 void send_response() override
= 0;
1637 const string
name() override
{ return "complete_multipart"; }
1638 RGWOpType
get_type() override
{ return RGW_OP_COMPLETE_MULTIPART
; }
1639 uint32_t op_mask() override
{ return RGW_OP_TYPE_WRITE
; }
1642 class RGWAbortMultipart
: public RGWOp
{
1644 RGWAbortMultipart() {}
1646 int verify_permission() override
;
1647 void pre_exec() override
;
1648 void execute() override
;
1650 void send_response() override
= 0;
1651 const string
name() override
{ return "abort_multipart"; }
1652 RGWOpType
get_type() override
{ return RGW_OP_ABORT_MULTIPART
; }
1653 uint32_t op_mask() override
{ return RGW_OP_TYPE_DELETE
; }
1656 class RGWListMultipart
: public RGWOp
{
1659 map
<uint32_t, RGWUploadPartInfo
> parts
;
1662 RGWAccessControlPolicy policy
;
1666 RGWListMultipart() {
1672 void init(RGWRados
*store
, struct req_state
*s
, RGWHandler
*h
) override
{
1673 RGWOp::init(store
, s
, h
);
1674 policy
= RGWAccessControlPolicy(s
->cct
);
1676 int verify_permission() override
;
1677 void pre_exec() override
;
1678 void execute() override
;
1680 virtual int get_params() = 0;
1681 void send_response() override
= 0;
1682 const string
name() override
{ return "list_multipart"; }
1683 RGWOpType
get_type() override
{ return RGW_OP_LIST_MULTIPART
; }
1684 uint32_t op_mask() override
{ return RGW_OP_TYPE_READ
; }
1687 struct RGWMultipartUploadEntry
{
1688 rgw_bucket_dir_entry obj
;
1692 class RGWListBucketMultiparts
: public RGWOp
{
1696 RGWMultipartUploadEntry next_marker
;
1699 vector
<RGWMultipartUploadEntry
> uploads
;
1700 map
<string
, bool> common_prefixes
;
1705 RGWListBucketMultiparts() {
1707 is_truncated
= false;
1711 void init(RGWRados
*store
, struct req_state
*s
, RGWHandler
*h
) override
{
1712 RGWOp::init(store
, s
, h
);
1713 max_uploads
= default_max
;
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 string
name() override
{ return "list_bucket_multiparts"; }
1723 RGWOpType
get_type() override
{ return RGW_OP_LIST_BUCKET_MULTIPARTS
; }
1724 uint32_t op_mask() override
{ return RGW_OP_TYPE_READ
; }
1728 class RGWGetCrossDomainPolicy
: public RGWOp
{
1730 RGWGetCrossDomainPolicy() = default;
1731 ~RGWGetCrossDomainPolicy() override
= default;
1733 int verify_permission() override
{
1737 void execute() override
{
1741 const string
name() override
{
1742 return "get_crossdomain_policy";
1745 RGWOpType
get_type() override
{
1746 return RGW_OP_GET_CROSS_DOMAIN_POLICY
;
1749 uint32_t op_mask() override
{
1750 return RGW_OP_TYPE_READ
;
1755 class RGWGetHealthCheck
: public RGWOp
{
1757 RGWGetHealthCheck() = default;
1758 ~RGWGetHealthCheck() override
= default;
1760 int verify_permission() override
{
1764 void execute() override
;
1766 const string
name() override
{
1767 return "get_health_check";
1770 RGWOpType
get_type() override
{
1771 return RGW_OP_GET_HEALTH_CHECK
;
1774 uint32_t op_mask() override
{
1775 return RGW_OP_TYPE_READ
;
1780 class RGWDeleteMultiObj
: public RGWOp
{
1788 bool acl_allowed
= false;
1791 RGWDeleteMultiObj() {
1792 max_to_delete
= 1000;
1796 status_dumped
= false;
1798 int verify_permission() override
;
1799 void pre_exec() override
;
1800 void execute() override
;
1802 virtual int get_params() = 0;
1803 virtual void send_status() = 0;
1804 virtual void begin_response() = 0;
1805 virtual void send_partial_response(rgw_obj_key
& key
, bool delete_marker
,
1806 const string
& marker_version_id
, int ret
) = 0;
1807 virtual void end_response() = 0;
1808 const string
name() override
{ return "multi_object_delete"; }
1809 RGWOpType
get_type() override
{ return RGW_OP_DELETE_MULTI_OBJ
; }
1810 uint32_t op_mask() override
{ return RGW_OP_TYPE_DELETE
; }
1813 class RGWInfo
: public RGWOp
{
1815 RGWInfo() = default;
1816 ~RGWInfo() override
= default;
1818 int verify_permission() override
{ return 0; }
1819 const string
name() override
{ return "get info"; }
1820 RGWOpType
get_type() override
{ return RGW_OP_GET_INFO
; }
1821 uint32_t op_mask() override
{ return RGW_OP_TYPE_READ
; }
1824 extern int rgw_build_bucket_policies(RGWRados
* store
, struct req_state
* s
);
1825 extern int rgw_build_object_policies(RGWRados
*store
, struct req_state
*s
,
1826 bool prefetch_data
);
1827 extern rgw::IAM::Environment
rgw_build_iam_environment(RGWRados
* store
,
1828 struct req_state
* s
);
1830 static inline int put_data_and_throttle(RGWPutObjDataProcessor
*processor
,
1831 bufferlist
& data
, off_t ofs
,
1836 void *handle
= nullptr;
1839 uint64_t size
= data
.length();
1841 int ret
= processor
->handle_data(data
, ofs
, &handle
, &obj
, &again
);
1844 if (handle
!= nullptr)
1846 ret
= processor
->throttle_data(handle
, obj
, size
, need_to_wait
);
1852 need_to_wait
= false; /* the need to wait only applies to the first
1857 } /* put_data_and_throttle */
1863 static inline int get_system_versioning_params(req_state
*s
,
1864 uint64_t *olh_epoch
,
1867 if (!s
->system_request
) {
1872 string epoch_str
= s
->info
.args
.get(RGW_SYS_PARAM_PREFIX
"versioned-epoch");
1873 if (!epoch_str
.empty()) {
1875 *olh_epoch
= strict_strtol(epoch_str
.c_str(), 10, &err
);
1877 lsubdout(s
->cct
, rgw
, 0) << "failed to parse versioned-epoch param"
1885 *version_id
= s
->info
.args
.get(RGW_SYS_PARAM_PREFIX
"version-id");
1889 } /* get_system_versioning_params */
1891 static inline void format_xattr(std::string
&xattr
)
1893 /* If the extended attribute is not valid UTF-8, we encode it using
1894 * quoted-printable encoding.
1896 if ((check_utf8(xattr
.c_str(), xattr
.length()) != 0) ||
1897 (check_for_control_characters(xattr
.c_str(), xattr
.length()) != 0)) {
1898 static const char MIME_PREFIX_STR
[] = "=?UTF-8?Q?";
1899 static const int MIME_PREFIX_LEN
= sizeof(MIME_PREFIX_STR
) - 1;
1900 static const char MIME_SUFFIX_STR
[] = "?=";
1901 static const int MIME_SUFFIX_LEN
= sizeof(MIME_SUFFIX_STR
) - 1;
1902 int mlen
= mime_encode_as_qp(xattr
.c_str(), NULL
, 0);
1903 char *mime
= new char[MIME_PREFIX_LEN
+ mlen
+ MIME_SUFFIX_LEN
+ 1];
1904 strcpy(mime
, MIME_PREFIX_STR
);
1905 mime_encode_as_qp(xattr
.c_str(), mime
+ MIME_PREFIX_LEN
, mlen
);
1906 strcpy(mime
+ MIME_PREFIX_LEN
+ (mlen
- 1), MIME_SUFFIX_STR
);
1910 } /* format_xattr */
1913 * Get the HTTP request metadata out of the req_state as a
1914 * map(<attr_name, attr_contents>, where attr_name is RGW_ATTR_PREFIX.HTTP_NAME)
1915 * s: The request state
1916 * attrs: will be filled up with attrs mapped as <attr_name, attr_contents>
1917 * On success returns 0.
1918 * On failure returns a negative error code.
1921 static inline int rgw_get_request_metadata(CephContext
* const cct
,
1922 struct req_info
& info
,
1923 std::map
<std::string
, ceph::bufferlist
>& attrs
,
1924 const bool allow_empty_attrs
= true)
1926 static const std::set
<std::string
> blacklisted_headers
= {
1927 "x-amz-server-side-encryption-customer-algorithm",
1928 "x-amz-server-side-encryption-customer-key",
1929 "x-amz-server-side-encryption-customer-key-md5"
1932 size_t valid_meta_count
= 0;
1933 for (auto& kv
: info
.x_meta_map
) {
1934 const std::string
& name
= kv
.first
;
1935 std::string
& xattr
= kv
.second
;
1937 if (blacklisted_headers
.count(name
) == 1) {
1938 lsubdout(cct
, rgw
, 10) << "skipping x>> " << name
<< dendl
;
1940 } else if (allow_empty_attrs
|| !xattr
.empty()) {
1941 lsubdout(cct
, rgw
, 10) << "x>> " << name
<< ":" << xattr
<< dendl
;
1942 format_xattr(xattr
);
1944 std::string
attr_name(RGW_ATTR_PREFIX
);
1945 attr_name
.append(name
);
1947 /* Check roughly whether we aren't going behind the limit on attribute
1948 * name. Passing here doesn't guarantee that an OSD will accept that
1949 * as ObjectStore::get_max_attr_name_length() can set the limit even
1950 * lower than the "osd_max_attr_name_len" configurable. */
1951 const size_t max_attr_name_len
= \
1952 cct
->_conf
->get_val
<size_t>("rgw_max_attr_name_len");
1953 if (max_attr_name_len
&& attr_name
.length() > max_attr_name_len
) {
1954 return -ENAMETOOLONG
;
1957 /* Similar remarks apply to the check for value size. We're veryfing
1958 * it early at the RGW's side as it's being claimed in /info. */
1959 const size_t max_attr_size
= \
1960 cct
->_conf
->get_val
<size_t>("rgw_max_attr_size");
1961 if (max_attr_size
&& xattr
.length() > max_attr_size
) {
1965 /* Swift allows administrators to limit the number of metadats items
1966 * send _in a single request_. */
1967 const auto rgw_max_attrs_num_in_req
= \
1968 cct
->_conf
->get_val
<size_t>("rgw_max_attrs_num_in_req");
1969 if (rgw_max_attrs_num_in_req
&&
1970 ++valid_meta_count
> rgw_max_attrs_num_in_req
) {
1974 auto rval
= attrs
.emplace(std::move(attr_name
), ceph::bufferlist());
1975 /* At the moment the value of the freshly created attribute key-value
1976 * pair is an empty bufferlist. */
1978 ceph::bufferlist
& bl
= rval
.first
->second
;
1979 bl
.append(xattr
.c_str(), xattr
.size() + 1);
1984 } /* rgw_get_request_metadata */
1986 static inline void encode_delete_at_attr(boost::optional
<ceph::real_time
> delete_at
,
1987 map
<string
, bufferlist
>& attrs
)
1989 if (delete_at
== boost::none
) {
1994 ::encode(*delete_at
, delatbl
);
1995 attrs
[RGW_ATTR_DELETE_AT
] = delatbl
;
1996 } /* encode_delete_at_attr */
1998 static inline void encode_obj_tags_attr(RGWObjTags
* obj_tags
, map
<string
, bufferlist
>& attrs
)
2000 if (obj_tags
== nullptr){
2001 // we assume the user submitted a tag format which we couldn't parse since
2002 // this wouldn't be parsed later by get/put obj tags, lets delete if the
2003 // attr was populated
2008 obj_tags
->encode(tagsbl
);
2009 attrs
[RGW_ATTR_TAGS
] = tagsbl
;
2012 static inline int encode_dlo_manifest_attr(const char * const dlo_manifest
,
2013 map
<string
, bufferlist
>& attrs
)
2015 string dm
= dlo_manifest
;
2017 if (dm
.find('/') == string::npos
) {
2021 bufferlist manifest_bl
;
2022 manifest_bl
.append(dlo_manifest
, strlen(dlo_manifest
) + 1);
2023 attrs
[RGW_ATTR_USER_MANIFEST
] = manifest_bl
;
2026 } /* encode_dlo_manifest_attr */
2028 static inline void complete_etag(MD5
& hash
, string
*etag
)
2030 char etag_buf
[CEPH_CRYPTO_MD5_DIGESTSIZE
];
2031 char etag_buf_str
[CEPH_CRYPTO_MD5_DIGESTSIZE
* 2 + 16];
2033 hash
.Final((byte
*)etag_buf
);
2034 buf_to_hex((const unsigned char *)etag_buf
, CEPH_CRYPTO_MD5_DIGESTSIZE
,
2037 *etag
= etag_buf_str
;
2038 } /* complete_etag */
2040 class RGWSetAttrs
: public RGWOp
{
2042 map
<string
, buffer::list
> attrs
;
2046 ~RGWSetAttrs() override
{}
2048 void emplace_attr(std::string
&& key
, buffer::list
&& bl
) {
2049 attrs
.emplace(std::move(key
), std::move(bl
));
2052 int verify_permission() override
;
2053 void pre_exec() override
;
2054 void execute() override
;
2056 virtual int get_params() = 0;
2057 void send_response() override
= 0;
2058 const string
name() override
{ return "set_attrs"; }
2059 RGWOpType
get_type() override
{ return RGW_OP_SET_ATTRS
; }
2060 uint32_t op_mask() override
{ return RGW_OP_TYPE_WRITE
; }
2063 class RGWGetObjLayout
: public RGWOp
{
2065 RGWObjManifest
*manifest
{nullptr};
2066 rgw_raw_obj head_obj
;
2072 int check_caps(RGWUserCaps
& caps
) {
2073 return caps
.check_cap("admin", RGW_CAP_READ
);
2075 int verify_permission() {
2076 return check_caps(s
->user
->caps
);
2081 virtual void send_response() = 0;
2082 virtual const string
name() { return "get_obj_layout"; }
2083 virtual RGWOpType
get_type() { return RGW_OP_GET_OBJ_LAYOUT
; }
2084 virtual uint32_t op_mask() { return RGW_OP_TYPE_READ
; }
2087 class RGWPutBucketPolicy
: public RGWOp
{
2089 char *data
= nullptr;
2091 RGWPutBucketPolicy() = default;
2092 ~RGWPutBucketPolicy() {
2094 free(static_cast<void*>(data
));
2097 void send_response() override
;
2098 int verify_permission() override
;
2099 uint32_t op_mask() override
{
2100 return RGW_OP_TYPE_WRITE
;
2102 void execute() override
;
2104 const std::string
name() override
{
2105 return "put_bucket_policy";
2107 RGWOpType
get_type() override
{
2108 return RGW_OP_PUT_BUCKET_POLICY
;
2112 class RGWGetBucketPolicy
: public RGWOp
{
2113 buffer::list policy
;
2115 RGWGetBucketPolicy() = default;
2116 void send_response() override
;
2117 int verify_permission() override
;
2118 uint32_t op_mask() override
{
2119 return RGW_OP_TYPE_READ
;
2121 void execute() override
;
2122 const std::string
name() override
{
2123 return "get_bucket_policy";
2125 RGWOpType
get_type() override
{
2126 return RGW_OP_GET_BUCKET_POLICY
;
2130 class RGWDeleteBucketPolicy
: public RGWOp
{
2132 RGWDeleteBucketPolicy() = default;
2133 void send_response() override
;
2134 int verify_permission() override
;
2135 uint32_t op_mask() override
{
2136 return RGW_OP_TYPE_WRITE
;
2138 void execute() override
;
2140 const std::string
name() override
{
2141 return "delete_bucket_policy";
2143 RGWOpType
get_type() override
{
2144 return RGW_OP_DELETE_BUCKET_POLICY
;
2149 class RGWConfigBucketMetaSearch
: public RGWOp
{
2151 std::map
<std::string
, uint32_t> mdsearch_config
;
2153 RGWConfigBucketMetaSearch() {}
2155 int verify_permission();
2159 virtual int get_params() = 0;
2160 virtual void send_response() = 0;
2161 virtual const string
name() { return "config_bucket_meta_search"; }
2162 virtual RGWOpType
get_type() { return RGW_OP_CONFIG_BUCKET_META_SEARCH
; }
2163 virtual uint32_t op_mask() { return RGW_OP_TYPE_WRITE
; }
2166 class RGWGetBucketMetaSearch
: public RGWOp
{
2168 RGWGetBucketMetaSearch() {}
2170 int verify_permission();
2174 virtual void send_response() = 0;
2175 virtual const string
name() { return "get_bucket_meta_search"; }
2176 virtual RGWOpType
get_type() { return RGW_OP_GET_BUCKET_META_SEARCH
; }
2177 virtual uint32_t op_mask() { return RGW_OP_TYPE_READ
; }
2180 class RGWDelBucketMetaSearch
: public RGWOp
{
2182 RGWDelBucketMetaSearch() {}
2184 int verify_permission();
2188 virtual void send_response() = 0;
2189 virtual const string
name() { return "delete_bucket_meta_search"; }
2190 virtual RGWOpType
delete_type() { return RGW_OP_DEL_BUCKET_META_SEARCH
; }
2191 virtual uint32_t op_mask() { return RGW_OP_TYPE_WRITE
; }
2194 #endif /* CEPH_RGW_OP_H */