]> git.proxmox.com Git - ceph.git/blame - ceph/src/rgw/rgw_op.h
update sources to 12.2.2
[ceph.git] / ceph / src / rgw / rgw_op.h
CommitLineData
31f18b77 1// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
7c673cae
FG
2// vim: ts=8 sw=2 smarttab
3/**
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.
10 */
11#ifndef CEPH_RGW_OP_H
12#define CEPH_RGW_OP_H
13
14#include <limits.h>
15
16#include <array>
17#include <memory>
18#include <string>
19#include <set>
20#include <map>
21#include <vector>
22
23#include <boost/optional.hpp>
24#include <boost/utility/in_place_factory.hpp>
31f18b77 25#include <boost/function.hpp>
7c673cae
FG
26
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"
33
34#include "rgw_common.h"
35#include "rgw_rados.h"
36#include "rgw_user.h"
37#include "rgw_bucket.h"
38#include "rgw_acl.h"
39#include "rgw_cors.h"
40#include "rgw_quota.h"
41
42#include "rgw_lc.h"
43#include "rgw_torrent.h"
224ce89b 44#include "rgw_tag.h"
3efd9988
FG
45#include "cls/lock/cls_lock_client.h"
46#include "cls/rgw/cls_rgw_client.h"
7c673cae
FG
47
48#include "include/assert.h"
49
7c673cae
FG
50using ceph::crypto::SHA1;
51
52struct req_state;
53class RGWOp;
54
55
56namespace rgw {
57namespace auth {
58namespace registry {
59
60class StrategyRegistry;
61
62}
63}
64}
65
66
67class RGWHandler {
68protected:
69 RGWRados* store;
70 struct req_state* s;
71
72 int do_init_permissions();
73 int do_read_permissions(RGWOp* op, bool only_bucket);
74
75public:
76 RGWHandler()
77 : store(nullptr),
78 s(nullptr) {
79 }
80 virtual ~RGWHandler();
81
82 virtual int init(RGWRados* store,
83 struct req_state* _s,
84 rgw::io::BasicClient* cio);
85
86 virtual int init_permissions(RGWOp*) {
87 return 0;
88 }
89
90 virtual int retarget(RGWOp* op, RGWOp** new_op) {
91 *new_op = op;
92 return 0;
93 }
94
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);
31f18b77 99 virtual void dump(const string& code, const string& message) const {}
7c673cae
FG
100};
101
102
31f18b77
FG
103
104void rgw_bucket_object_pre_exec(struct req_state *s);
105
7c673cae
FG
106/**
107 * Provide the base class for all ops.
108 */
109class RGWOp {
110protected:
111 struct req_state *s;
112 RGWHandler *dialect_handler;
113 RGWRados *store;
114 RGWCORSConfiguration bucket_cors;
115 bool cors_exist;
116 RGWQuotaInfo bucket_quota;
117 RGWQuotaInfo user_quota;
118 int op_ret;
119
120 int do_aws4_auth_completion();
121
122 virtual int init_quota();
123public:
124 RGWOp()
125 : s(nullptr),
126 dialect_handler(nullptr),
127 store(nullptr),
128 cors_exist(false),
129 op_ret(0) {
130 }
131
132 virtual ~RGWOp() = default;
133
134 int get_ret() const { return op_ret; }
135
136 virtual int init_processing() {
137 op_ret = init_quota();
138 if (op_ret < 0)
139 return op_ret;
140
141 return 0;
142 }
143
144 virtual void init(RGWRados *store, struct req_state *s, RGWHandler *dialect_handler) {
145 this->store = store;
146 this->s = s;
147 this->dialect_handler = dialect_handler;
148 }
149 int read_bucket_cors();
150 bool generate_cors_headers(string& origin, string& method, string& headers, string& exp_headers, unsigned *max_age);
151
152 virtual int verify_params() { return 0; }
153 virtual bool prefetch_data() { return false; }
154
155 /* Authenticate requester -- verify its identity.
156 *
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();
167 }
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() {
174 send_response();
175 }
176 virtual const string name() = 0;
177 virtual RGWOpType get_type() { return RGW_OP_UNKNOWN; }
178
179 virtual uint32_t op_mask() { return 0; }
180
181 virtual int error_handler(int err_no, string *error_content);
182};
183
184class RGWGetObj : public RGWOp {
185protected:
186 seed torrent; // get torrent
187 const char *range_str;
188 const char *if_mod;
189 const char *if_unmod;
190 const char *if_match;
191 const char *if_nomatch;
192 uint32_t mod_zone_id;
193 uint64_t mod_pg_ver;
194 off_t ofs;
195 uint64_t total_len;
196 off_t start;
197 off_t end;
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;
204 bool get_data;
205 bool partial_content;
206 bool range_parsed;
207 bool skip_manifest;
181888fb 208 bool skip_decrypt{false};
7c673cae
FG
209 rgw_obj obj;
210 utime_t gc_invalidate_time;
211 bool is_slo;
212 string lo_etag;
213 bool rgwx_stat; /* extended rgw stat operation */
31f18b77 214 string version_id;
7c673cae
FG
215
216 // compression attrs
217 RGWCompressionInfo cs_info;
218 off_t first_block, last_block;
219 off_t q_ofs, q_len;
220 bool first_data;
221 uint64_t cur_ofs;
222 bufferlist waiting;
31f18b77 223 uint64_t action = 0;
7c673cae
FG
224
225 int init_common();
226public:
227 RGWGetObj() {
228 range_str = NULL;
229 if_mod = NULL;
230 if_unmod = NULL;
231 if_match = NULL;
232 if_nomatch = NULL;
233 mod_zone_id = 0;
234 mod_pg_ver = 0;
235 start = 0;
236 ofs = 0;
237 total_len = 0;
238 end = -1;
239 mod_ptr = NULL;
240 unmod_ptr = NULL;
241 get_data = false;
242 partial_content = false;
243 range_parsed = false;
244 skip_manifest = false;
245 is_slo = false;
246 first_block = 0;
247 last_block = 0;
248 q_ofs = 0;
249 q_len = 0;
250 first_data = true;
251 cur_ofs = 0;
252 }
253
254 bool prefetch_data() override;
255
256 void set_get_data(bool get_data) {
257 this->get_data = get_data;
258 }
259 int verify_permission() override;
260 void pre_exec() override;
261 void execute() override;
31f18b77
FG
262 int read_user_manifest_part(
263 rgw_bucket& bucket,
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);
7c673cae
FG
269 int handle_user_manifest(const char *prefix);
270 int handle_slo_manifest(bufferlist& bl);
271
272 int get_data_cb(bufferlist& bl, off_t ofs, off_t len);
273
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;
277
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; }
282 /**
283 * calculates filter used to decrypt RGW objects data
284 */
285 virtual int get_decrypt_filter(std::unique_ptr<RGWGetDataCB>* filter, RGWGetDataCB* cb, bufferlist* manifest_bl) {
286 *filter = nullptr;
287 return 0;
288 }
289};
290
291class RGWGetObj_CB : public RGWGetDataCB
292{
293 RGWGetObj *op;
294public:
295 explicit RGWGetObj_CB(RGWGetObj *_op) : op(_op) {}
296 ~RGWGetObj_CB() override {}
297
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);
300 }
301};
302
303class RGWGetObj_Filter : public RGWGetDataCB
304{
305protected:
306 RGWGetDataCB* next;
307public:
308 RGWGetObj_Filter(RGWGetDataCB* next): next(next) {}
309 ~RGWGetObj_Filter() override {}
310 /**
311 * Passes data through filter.
312 * Filter can modify content of bl.
313 * When bl_len == 0 , it means 'flush
314 */
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);
317 }
318 /**
319 * Flushes any cached data. Used by RGWGetObjFilter.
320 * Return logic same as handle_data.
321 */
322 int flush() override {
323 return next->flush();
324 }
325 /**
326 * Allows filter to extend range required for successful filtering
327 */
328 int fixup_range(off_t& ofs, off_t& end) override {
329 return next->fixup_range(ofs, end);
330 }
331};
332
224ce89b
WB
333class RGWGetObjTags : public RGWOp {
334 protected:
335 bufferlist tags_bl;
336 bool has_tags{false};
337 public:
338 int verify_permission();
339 void execute();
340 void pre_exec();
341
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; }
346
347};
348
349class RGWPutObjTags : public RGWOp {
350 protected:
351 bufferlist tags_bl;
352 public:
353 int verify_permission();
354 void execute();
355
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; }
361
362};
363
364class RGWDeleteObjTags: public RGWOp {
365 public:
366 void pre_exec();
367 int verify_permission();
368 void execute();
369
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;}
374};
375
7c673cae
FG
376class RGWBulkDelete : public RGWOp {
377public:
378 struct acct_path_t {
379 std::string bucket_name;
380 rgw_obj_key obj_key;
381 };
382
383 struct fail_desc_t {
384 int err;
385 acct_path_t path;
386 };
387
388 class Deleter {
389 protected:
390 unsigned int num_deleted;
391 unsigned int num_unfound;
392 std::list<fail_desc_t> failures;
393
394 RGWRados * const store;
395 req_state * const s;
396
397 public:
398 Deleter(RGWRados * const str, req_state * const s)
399 : num_deleted(0),
400 num_unfound(0),
401 store(str),
402 s(s) {
403 }
404
405 unsigned int get_num_deleted() const {
406 return num_deleted;
407 }
408
409 unsigned int get_num_unfound() const {
410 return num_unfound;
411 }
412
413 const std::list<fail_desc_t> get_failures() const {
414 return failures;
415 }
416
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);
422 };
423 /* End of Deleter subclass */
424
425 static const size_t MAX_CHUNK_ENTRIES = 1024;
426
427protected:
428 std::unique_ptr<Deleter> deleter;
429
430public:
431 RGWBulkDelete()
432 : deleter(nullptr) {
433 }
434
435 int verify_permission() override;
436 void pre_exec() override;
437 void execute() override;
438
439 virtual int get_data(std::list<acct_path_t>& items,
440 bool * is_truncated) = 0;
441 void send_response() override = 0;
442
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; }
446};
447
448inline ostream& operator<<(ostream& out, const RGWBulkDelete::acct_path_t &o) {
449 return out << o.bucket_name << "/" << o.obj_key;
450}
451
452
453class RGWBulkUploadOp : public RGWOp {
454 boost::optional<RGWObjectCtx> dir_ctx;
455
456protected:
457 class fail_desc_t {
458 public:
459 fail_desc_t(const int err, std::string path)
460 : err(err),
461 path(std::move(path)) {
462 }
463
464 const int err;
465 const std::string path;
466 };
467
468 static constexpr std::array<int, 2> terminal_errors = {
469 { -EACCES, -EPERM }
470 };
471
472 /* FIXME: boost::container::small_vector<fail_desc_t, 4> failures; */
473 std::vector<fail_desc_t> failures;
474 size_t num_created;
475
476 class StreamGetter;
477 class DecoratedStreamGetter;
478 class AlignedStreamGetter;
479
480 virtual std::unique_ptr<StreamGetter> create_stream() = 0;
481 virtual void send_response() = 0;
482
483 boost::optional<std::pair<std::string, rgw_obj_key>>
484 parse_path(const boost::string_ref& path);
485
486 std::pair<std::string, std::string>
487 handle_upload_path(struct req_state *s);
488
489 bool handle_file_verify_permission(RGWBucketInfo& binfo,
31f18b77
FG
490 const rgw_obj& obj,
491 std::map<std::string, ceph::bufferlist>& battrs,
7c673cae
FG
492 ACLOwner& bucket_owner /* out */);
493 int handle_file(boost::string_ref path,
494 size_t size,
495 AlignedStreamGetter& body);
496
497 int handle_dir_verify_permission();
498 int handle_dir(boost::string_ref path);
499
500public:
501 RGWBulkUploadOp()
502 : num_created(0) {
503 }
504
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);
510 }
511
512 int verify_permission() override;
513 void pre_exec() override;
514 void execute() override;
515
516 const std::string name() override {
517 return "bulk_upload";
518 }
519
520 RGWOpType get_type() override {
521 return RGW_OP_BULK_UPLOAD;
522 }
523
524 uint32_t op_mask() override {
525 return RGW_OP_TYPE_WRITE;
526 }
527}; /* RGWBulkUploadOp */
528
529
530class RGWBulkUploadOp::StreamGetter {
531public:
532 StreamGetter() = default;
533 virtual ~StreamGetter() = default;
534
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 */
538
539
540class RGWBulkUploadOp::DecoratedStreamGetter : public StreamGetter {
541 StreamGetter& decoratee;
542
543protected:
544 StreamGetter& get_decoratee() {
545 return decoratee;
546 }
547
548public:
549 DecoratedStreamGetter(StreamGetter& decoratee)
550 : decoratee(decoratee) {
551 }
552 virtual ~DecoratedStreamGetter() = default;
553
554 ssize_t get_at_most(const size_t want, ceph::bufferlist& dst) override {
555 return get_decoratee().get_at_most(want, dst);
556 }
557
558 ssize_t get_exactly(const size_t want, ceph::bufferlist& dst) override {
559 return get_decoratee().get_exactly(want, dst);
560 }
561}; /* RGWBulkUploadOp::DecoratedStreamGetter */
562
563
564class RGWBulkUploadOp::AlignedStreamGetter
565 : public RGWBulkUploadOp::DecoratedStreamGetter {
566 size_t position;
567 size_t length;
568 size_t alignment;
569
570public:
571 template <typename U>
572 AlignedStreamGetter(const size_t position,
573 const size_t length,
574 const size_t alignment,
575 U&& decoratee)
576 : DecoratedStreamGetter(std::forward<U>(decoratee)),
577 position(position),
578 length(length),
579 alignment(alignment) {
580 }
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 */
585
586
3efd9988
FG
587struct 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;
592};
593
7c673cae
FG
594#define RGW_LIST_BUCKETS_LIMIT_MAX 10000
595
596class RGWListBuckets : public RGWOp {
597protected:
598 bool sent_data;
3efd9988
FG
599 std::string marker;
600 std::string end_marker;
7c673cae
FG
601 int64_t limit;
602 uint64_t limit_max;
3efd9988 603 std::map<std::string, ceph::bufferlist> attrs;
7c673cae
FG
604 bool is_truncated;
605
3efd9988
FG
606 RGWUsageStats global_stats;
607 std::map<std::string, RGWUsageStats> policies_stats;
608
7c673cae
FG
609 virtual uint64_t get_default_max() const {
610 return 1000;
611 }
612
613public:
3efd9988
FG
614 RGWListBuckets()
615 : sent_data(false),
616 limit(RGW_LIST_BUCKETS_LIMIT_MAX),
617 limit_max(RGW_LIST_BUCKETS_LIMIT_MAX),
618 is_truncated(false) {
7c673cae
FG
619 }
620
621 int verify_permission() override;
622 void execute() override;
623
624 virtual int get_params() = 0;
3efd9988
FG
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);
631 }
7c673cae
FG
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 {}
636
637 virtual bool should_get_stats() { return false; }
638 virtual bool supports_account_metadata() { return false; }
639
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; }
643};
644
645class RGWGetUsage : public RGWOp {
646protected:
647 bool sent_data;
648 string start_date;
649 string end_date;
650 int show_log_entries;
651 int show_log_sum;
652 map<string, bool> categories;
653 map<rgw_user_bucket, rgw_usage_log_entry> usage;
654 map<string, rgw_usage_log_entry> summary_map;
c07f9fc5 655 map<string, cls_user_bucket_entry> buckets_usage;
7c673cae
FG
656 cls_user_header header;
657public:
658 RGWGetUsage() : sent_data(false), show_log_entries(true), show_log_sum(true){
659 }
660
661 int verify_permission() override;
662 void execute() override;
663
664 virtual int get_params() = 0;
665 void send_response() override {}
666
667 virtual bool should_get_stats() { return false; }
668
669 const string name() override { return "get_usage"; }
670 uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
671};
672
673class RGWStatAccount : public RGWOp {
674protected:
3efd9988
FG
675 RGWUsageStats global_stats;
676 std::map<std::string, RGWUsageStats> policies_stats;
7c673cae
FG
677
678public:
3efd9988 679 RGWStatAccount() = default;
7c673cae
FG
680
681 int verify_permission() override;
682 void execute() override;
683
684 void send_response() override = 0;
3efd9988 685 const std::string name() override { return "stat_account"; }
7c673cae
FG
686 RGWOpType get_type() override { return RGW_OP_STAT_ACCOUNT; }
687 uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
688};
689
690class RGWListBucket : public RGWOp {
691protected:
692 RGWBucketEnt bucket;
693 string prefix;
694 rgw_obj_key marker;
695 rgw_obj_key next_marker;
696 rgw_obj_key end_marker;
697 string max_keys;
698 string delimiter;
699 string encoding_type;
700 bool list_versions;
701 int max;
702 vector<rgw_bucket_dir_entry> objs;
703 map<string, bool> common_prefixes;
704
705 int default_max;
706 bool is_truncated;
707
708 int shard_id;
709
710 int parse_max_keys();
711
712public:
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;
718
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; }
725};
726
727class RGWGetBucketLogging : public RGWOp {
728public:
729 RGWGetBucketLogging() {}
730 int verify_permission() override;
731 void execute() override { }
732
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; }
737};
738
739class RGWGetBucketLocation : public RGWOp {
740public:
741 RGWGetBucketLocation() {}
742 ~RGWGetBucketLocation() override {}
743 int verify_permission() override;
744 void execute() override { }
745
746 void send_response() override = 0;
747 const string name() override { return "get_bucket_location"; }
3efd9988 748 RGWOpType get_type() override { return RGW_OP_GET_BUCKET_LOCATION; }
7c673cae
FG
749 uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
750};
751
752class RGWGetBucketVersioning : public RGWOp {
753protected:
754 bool versioned;
755 bool versioning_enabled;
756public:
757 RGWGetBucketVersioning() : versioned(false), versioning_enabled(false) {}
758
759 int verify_permission() override;
760 void pre_exec() override;
761 void execute() override;
762
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; }
767};
768
769class RGWSetBucketVersioning : public RGWOp {
770protected:
771 bool enable_versioning;
772 bufferlist in_data;
773public:
774 RGWSetBucketVersioning() : enable_versioning(false) {}
775
776 int verify_permission() override;
777 void pre_exec() override;
778 void execute() override;
779
780 virtual int get_params() { return 0; }
781
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; }
786};
787
788class RGWGetBucketWebsite : public RGWOp {
789public:
790 RGWGetBucketWebsite() {}
791
792 int verify_permission() override;
793 void pre_exec() override;
794 void execute() override;
795
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; }
800};
801
802class RGWSetBucketWebsite : public RGWOp {
803protected:
31f18b77 804 bufferlist in_data;
7c673cae
FG
805 RGWBucketWebsiteConf website_conf;
806public:
807 RGWSetBucketWebsite() {}
808
809 int verify_permission() override;
810 void pre_exec() override;
811 void execute() override;
812
813 virtual int get_params() { return 0; }
814
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; }
819};
820
821class RGWDeleteBucketWebsite : public RGWOp {
822public:
823 RGWDeleteBucketWebsite() {}
824
825 int verify_permission() override;
826 void pre_exec() override;
827 void execute() override;
828
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; }
833};
834
835class RGWStatBucket : public RGWOp {
836protected:
837 RGWBucketEnt bucket;
838
839public:
840 RGWStatBucket() {}
841 ~RGWStatBucket() override {}
842
843 int verify_permission() override;
844 void pre_exec() override;
845 void execute() override;
846
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; }
851};
852
853class RGWCreateBucket : public RGWOp {
854protected:
855 RGWAccessControlPolicy policy;
856 string location_constraint;
857 string placement_rule;
858 RGWBucketInfo info;
859 obj_version ep_objv;
860 bool has_cors;
861 RGWCORSConfiguration cors_config;
862 boost::optional<std::string> swift_ver_location;
863 map<string, buffer::list> attrs;
864 set<string> rmattr_names;
865
866 bufferlist in_data;
867
868 virtual bool need_metadata_upload() const { return false; }
869
870public:
871 RGWCreateBucket() : has_cors(false) {}
872
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 */
875 }
876
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);
883 }
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; }
889};
890
891class RGWDeleteBucket : public RGWOp {
892protected:
893 RGWObjVersionTracker objv_tracker;
894
895public:
896 RGWDeleteBucket() {}
897
898 int verify_permission() override;
899 void pre_exec() override;
900 void execute() override;
901
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; }
906};
907
908struct rgw_slo_entry {
909 string path;
910 string etag;
911 uint64_t size_bytes;
912
913 rgw_slo_entry() : size_bytes(0) {}
914
915 void encode(bufferlist& bl) const {
916 ENCODE_START(1, 1, bl);
917 ::encode(path, bl);
918 ::encode(etag, bl);
919 ::encode(size_bytes, bl);
920 ENCODE_FINISH(bl);
921 }
922
923 void decode(bufferlist::iterator& bl) {
924 DECODE_START(1, bl);
925 ::decode(path, bl);
926 ::decode(etag, bl);
927 ::decode(size_bytes, bl);
928 DECODE_FINISH(bl);
929 }
930
931 void decode_json(JSONObj *obj);
932};
933WRITE_CLASS_ENCODER(rgw_slo_entry)
934
935struct RGWSLOInfo {
936 vector<rgw_slo_entry> entries;
937 uint64_t total_size;
938
939 /* in memory only */
940 char *raw_data;
941 int raw_data_len;
942
943 RGWSLOInfo() : total_size(0), raw_data(NULL), raw_data_len(0) {}
944 ~RGWSLOInfo() {
945 free(raw_data);
946 }
947
948 void encode(bufferlist& bl) const {
949 ENCODE_START(1, 1, bl);
950 ::encode(entries, bl);
951 ::encode(total_size, bl);
952 ENCODE_FINISH(bl);
953 }
954
955 void decode(bufferlist::iterator& bl) {
956 DECODE_START(1, bl);
957 ::decode(entries, bl);
958 ::decode(total_size, bl);
959 DECODE_FINISH(bl);
960 }
961};
962WRITE_CLASS_ENCODER(RGWSLOInfo)
963
964class RGWPutObj : public RGWOp {
965
966 friend class RGWPutObjProcessor;
967
968protected:
969 seed torrent;
970 off_t ofs;
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;
984 string etag;
985 bool chunked_upload;
986 RGWAccessControlPolicy policy;
224ce89b 987 std::unique_ptr <RGWObjTags> obj_tags;
7c673cae
FG
988 const char *dlo_manifest;
989 RGWSLOInfo *slo_info;
990 map<string, bufferlist> attrs;
991 ceph::real_time mtime;
992 uint64_t olh_epoch;
993 string version_id;
994 bufferlist bl_aux;
995 map<string, string> crypt_http_responses;
996 string user_data;
997
998 boost::optional<ceph::real_time> delete_at;
999
1000public:
1001 RGWPutObj() : ofs(0),
1002 supplied_md5_b64(NULL),
1003 supplied_etag(NULL),
1004 if_match(NULL),
1005 if_nomatch(NULL),
1006 copy_source(NULL),
1007 copy_source_range(NULL),
1008 copy_source_range_fst(0),
1009 copy_source_range_lst(0),
1010 chunked_upload(0),
1011 dlo_manifest(NULL),
1012 slo_info(NULL),
1013 olh_epoch(0) {}
1014
1015 ~RGWPutObj() override {
1016 delete slo_info;
1017 }
1018
1019 void init(RGWRados *store, struct req_state *s, RGWHandler *h) override {
1020 RGWOp::init(store, s, h);
1021 policy.set_ctx(s->cct);
1022 }
1023
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 */
1026 }
1027
1028 virtual RGWPutObjProcessor *select_processor(RGWObjectCtx& obj_ctx, bool *is_multipart);
1029 void dispose_processor(RGWPutObjDataProcessor *processor);
1030
1031 int verify_permission() override;
1032 void pre_exec() override;
1033 void execute() override;
1034
1035 /* this is for cases when copying data from other object */
1036 virtual int get_decrypt_filter(std::unique_ptr<RGWGetDataCB>* filter,
1037 RGWGetDataCB* cb,
1038 map<string, bufferlist>& attrs,
1039 bufferlist* manifest_bl) {
1040 *filter = nullptr;
1041 return 0;
1042 }
1043 virtual int get_encrypt_filter(std::unique_ptr<RGWPutObjDataProcessor> *filter, RGWPutObjDataProcessor* cb) {
1044 *filter = nullptr;
1045 return 0;
1046 }
1047
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);
1050
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; }
1057};
1058
1059class RGWPutObj_Filter : public RGWPutObjDataProcessor
1060{
1061protected:
1062 RGWPutObjDataProcessor* next;
1063public:
1064 RGWPutObj_Filter(RGWPutObjDataProcessor* next) :
1065 next(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);
1069 }
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);
1072 }
1073}; /* RGWPutObj_Filter */
1074
1075class RGWPostObj : public RGWOp {
1076protected:
1077 off_t min_len;
1078 off_t max_len;
1079 int len;
1080 off_t ofs;
1081 const char *supplied_md5_b64;
1082 const char *supplied_etag;
1083 string etag;
1084 RGWAccessControlPolicy policy;
1085 map<string, bufferlist> attrs;
1086 boost::optional<ceph::real_time> delete_at;
1087
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() {
1092 return false;
1093 }
1094public:
1095 RGWPostObj() : min_len(0),
1096 max_len(LLONG_MAX),
1097 len(0),
1098 ofs(0),
1099 supplied_md5_b64(nullptr),
1100 supplied_etag(nullptr) {
1101 }
1102
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 */
1105 }
1106
1107 void init(RGWRados *store, struct req_state *s, RGWHandler *h) override {
1108 RGWOp::init(store, s, h);
1109 policy.set_ctx(s->cct);
1110 }
1111
1112 int verify_permission() override;
1113 void pre_exec() override;
1114 void execute() override;
1115
1116 virtual int get_encrypt_filter(std::unique_ptr<RGWPutObjDataProcessor> *filter, RGWPutObjDataProcessor* cb) {
1117 *filter = nullptr;
1118 return 0;
1119 }
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; }
1126};
1127
1128class RGWPutMetadataAccount : public RGWOp {
1129protected:
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;
1135
1136 RGWObjVersionTracker acct_op_tracker;
1137
1138 RGWAccessControlPolicy policy;
1139 bool has_policy;
1140
1141public:
1142 RGWPutMetadataAccount()
1143 : new_quota_extracted(false),
1144 has_policy(false) {
1145 }
1146
1147 void init(RGWRados *store, struct req_state *s, RGWHandler *h) override {
1148 RGWOp::init(store, s, h);
1149 policy.set_ctx(s->cct);
1150 }
1151 int init_processing() override;
1152 int verify_permission() override;
1153 void pre_exec() override { }
1154 void execute() override;
1155
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; }
1164};
1165
1166class RGWPutMetadataBucket : public RGWOp {
1167protected:
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;
1176
1177public:
1178 RGWPutMetadataBucket()
1179 : has_policy(false), has_cors(false), policy_rw_mask(0)
1180 {}
1181
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 */
1184 }
1185
1186 void init(RGWRados *store, struct req_state *s, RGWHandler *h) override {
1187 RGWOp::init(store, s, h);
1188 policy.set_ctx(s->cct);
1189 }
1190
1191 int verify_permission() override;
1192 void pre_exec() override;
1193 void execute() override;
1194
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; }
1200};
1201
1202class RGWPutMetadataObject : public RGWOp {
1203protected:
1204 RGWAccessControlPolicy policy;
1205 string placement_rule;
1206 boost::optional<ceph::real_time> delete_at;
1207 const char *dlo_manifest;
1208
1209public:
1210 RGWPutMetadataObject()
1211 : dlo_manifest(NULL)
1212 {}
1213
1214 void init(RGWRados *store, struct req_state *s, RGWHandler *h) override {
1215 RGWOp::init(store, s, h);
1216 policy.set_ctx(s->cct);
1217 }
1218 int verify_permission() override;
1219 void pre_exec() override;
1220 void execute() override;
1221
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; }
1228};
1229
1230class RGWDeleteObj : public RGWOp {
1231protected:
1232 bool delete_marker;
1233 bool multipart_delete;
1234 string version_id;
1235 ceph::real_time unmod_since; /* if unmodified since */
1236 bool no_precondition_error;
1237 std::unique_ptr<RGWBulkDelete::Deleter> deleter;
1238
1239public:
1240 RGWDeleteObj()
1241 : delete_marker(false),
1242 multipart_delete(false),
1243 no_precondition_error(false),
1244 deleter(nullptr) {
1245 }
1246
1247 int verify_permission() override;
1248 void pre_exec() override;
1249 void execute() override;
1250 int handle_slo_manifest(bufferlist& bl);
1251
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; }
1258};
1259
1260class RGWCopyObj : public RGWOp {
1261protected:
1262 RGWAccessControlPolicy dest_policy;
1263 const char *if_mod;
1264 const char *if_unmod;
1265 const char *if_match;
1266 const char *if_nomatch;
1267 off_t ofs;
1268 off_t len;
1269 off_t end;
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;
1280 string dest_object;
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;
1286 string source_zone;
1287 string client_id;
1288 string op_id;
1289 ceph::buffer::list etag;
1290
1291 off_t last_ofs;
1292
1293 string version_id;
1294 uint64_t olh_epoch;
1295
1296 boost::optional<ceph::real_time> delete_at;
1297 bool copy_if_newer;
1298
1299 int init_common();
1300
1301public:
1302 RGWCopyObj() {
1303 if_mod = NULL;
1304 if_unmod = NULL;
1305 if_match = NULL;
1306 if_nomatch = NULL;
1307 ofs = 0;
1308 len = 0;
1309 end = -1;
1310 mod_ptr = NULL;
1311 unmod_ptr = NULL;
1312 attrs_mod = RGWRados::ATTRSMOD_NONE;
1313 last_ofs = 0;
1314 olh_epoch = 0;
1315 copy_if_newer = false;
1316 }
1317
1318 static bool parse_copy_location(const string& src,
1319 string& bucket_name,
1320 rgw_obj_key& object);
1321
1322 void emplace_attr(std::string&& key, buffer::list&& bl) {
1323 attrs.emplace(std::move(key), std::move(bl));
1324 }
1325
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);
1329 }
1330 int verify_permission() override;
1331 void pre_exec() override;
1332 void execute() override;
1333 void progress_cb(off_t ofs);
1334
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; }
1342};
1343
1344class RGWGetACLs : public RGWOp {
1345protected:
1346 string acls;
1347
1348public:
1349 RGWGetACLs() {}
1350
1351 int verify_permission() override;
1352 void pre_exec() override;
1353 void execute() override;
1354
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; }
1359};
1360
1361class RGWPutACLs : public RGWOp {
1362protected:
1363 int len;
1364 char *data;
1365 ACLOwner owner;
1366
1367public:
1368 RGWPutACLs() {
1369 len = 0;
1370 data = NULL;
1371 }
1372 ~RGWPutACLs() override {
1373 free(data);
1374 }
1375
1376 int verify_permission() override;
1377 void pre_exec() override;
1378 void execute() override;
1379
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; }
1386};
1387
1388class RGWGetLC : public RGWOp {
1389protected:
1390
1391public:
1392 RGWGetLC() { }
1393 ~RGWGetLC() override { }
1394
1395 int verify_permission() override;
1396 void pre_exec() override;
1397 void execute() override = 0;
1398
1399 void send_response() override = 0;
1400 const string name() override { return "get_lifecycle"; }
d2e6a577 1401 RGWOpType get_type() override { return RGW_OP_GET_LC; }
7c673cae
FG
1402 uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
1403};
1404
1405class RGWPutLC : public RGWOp {
1406protected:
1407 int len;
1408 char *data;
1409 string cookie;
1410
1411public:
1412 RGWPutLC() {
1413 len = 0;
1414 data = NULL;
1415 }
1416 ~RGWPutLC() override {
1417 free(data);
1418 }
1419
1420 void init(RGWRados *store, struct req_state *s, RGWHandler *dialect_handler) override {
1421#define COOKIE_LEN 16
1422 char buf[COOKIE_LEN + 1];
1423
1424 RGWOp::init(store, s, dialect_handler);
1425 gen_rand_alphanumeric(s->cct, buf, sizeof(buf) - 1);
1426 cookie = buf;
1427 }
1428
1429 int verify_permission() override;
1430 void pre_exec() override;
1431 void execute() override;
1432
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"; }
d2e6a577 1437 RGWOpType get_type() override { return RGW_OP_PUT_LC; }
7c673cae
FG
1438 uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
1439};
1440
1441class RGWDeleteLC : public RGWOp {
1442protected:
1443 size_t len;
1444 char *data;
1445
1446public:
1447 RGWDeleteLC() {
1448 len = 0;
1449 data = NULL;
1450 }
1451 ~RGWDeleteLC() override {
1452 free(data);
1453 }
1454
1455 int verify_permission() override;
1456 void pre_exec() override;
1457 void execute() override;
1458
1459 void send_response() override = 0;
1460 const string name() override { return "delete_lifecycle"; }
d2e6a577 1461 RGWOpType get_type() override { return RGW_OP_DELETE_LC; }
7c673cae
FG
1462 uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
1463};
1464
1465class RGWGetCORS : public RGWOp {
1466protected:
1467
1468public:
1469 RGWGetCORS() {}
1470
1471 int verify_permission() override;
1472 void execute() override;
1473
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; }
1478};
1479
1480class RGWPutCORS : public RGWOp {
1481protected:
1482 bufferlist cors_bl;
31f18b77 1483 bufferlist in_data;
7c673cae
FG
1484
1485public:
1486 RGWPutCORS() {}
1487 ~RGWPutCORS() override {}
1488
1489 int verify_permission() override;
1490 void execute() override;
1491
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; }
1497};
1498
1499class RGWDeleteCORS : public RGWOp {
1500protected:
1501
1502public:
1503 RGWDeleteCORS() {}
1504
1505 int verify_permission() override;
1506 void execute() override;
1507
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; }
1512};
1513
1514class RGWOptionsCORS : public RGWOp {
1515protected:
1516 RGWCORSRule *rule;
1517 const char *origin, *req_hdrs, *req_meth;
1518
1519public:
1520 RGWOptionsCORS() : rule(NULL), origin(NULL),
1521 req_hdrs(NULL), req_meth(NULL) {
1522 }
1523
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; }
1532};
1533
1534class RGWGetRequestPayment : public RGWOp {
1535protected:
1536 bool requester_pays;
1537
1538public:
1539 RGWGetRequestPayment() : requester_pays(0) {}
1540
1541 int verify_permission() override;
1542 void pre_exec() override;
1543 void execute() override;
1544
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; }
1549};
1550
1551class RGWSetRequestPayment : public RGWOp {
1552protected:
1553 bool requester_pays;
1554public:
1555 RGWSetRequestPayment() : requester_pays(false) {}
1556
1557 int verify_permission() override;
1558 void pre_exec() override;
1559 void execute() override;
1560
1561 virtual int get_params() { return 0; }
1562
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; }
1567};
1568
1569class RGWInitMultipart : public RGWOp {
1570protected:
1571 string upload_id;
1572 RGWAccessControlPolicy policy;
1573
1574public:
1575 RGWInitMultipart() {}
1576
1577 void init(RGWRados *store, struct req_state *s, RGWHandler *h) override {
1578 RGWOp::init(store, s, h);
1579 policy.set_ctx(s->cct);
1580 }
1581 int verify_permission() override;
1582 void pre_exec() override;
1583 void execute() override;
1584
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; }
1591};
1592
1593class RGWCompleteMultipart : public RGWOp {
1594protected:
1595 string upload_id;
1596 string etag;
1597 char *data;
1598 int len;
1599
3efd9988
FG
1600 struct MPSerializer {
1601 librados::IoCtx ioctx;
1602 rados::cls::lock::Lock lock;
1603 librados::ObjectWriteOperation op;
1604 std::string oid;
1605 bool locked;
1606
1607 MPSerializer() : lock("RGWCompleteMultipart"), locked(false)
1608 {}
1609
1610 int try_lock(const std::string& oid, utime_t dur);
1611
1612 int unlock() {
1613 return lock.unlock(&ioctx, oid);
1614 }
1615
1616 void clear_locked() {
1617 locked = false;
1618 }
1619 } serializer;
1620
7c673cae
FG
1621public:
1622 RGWCompleteMultipart() {
1623 data = NULL;
1624 len = 0;
1625 }
1626 ~RGWCompleteMultipart() override {
1627 free(data);
1628 }
1629
1630 int verify_permission() override;
1631 void pre_exec() override;
1632 void execute() override;
3efd9988 1633 void complete() override;
7c673cae
FG
1634
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; }
1640};
1641
1642class RGWAbortMultipart : public RGWOp {
1643public:
1644 RGWAbortMultipart() {}
1645
1646 int verify_permission() override;
1647 void pre_exec() override;
1648 void execute() override;
1649
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; }
1654};
1655
1656class RGWListMultipart : public RGWOp {
1657protected:
1658 string upload_id;
1659 map<uint32_t, RGWUploadPartInfo> parts;
1660 int max_parts;
1661 int marker;
1662 RGWAccessControlPolicy policy;
1663 bool truncated;
1664
1665public:
1666 RGWListMultipart() {
1667 max_parts = 1000;
1668 marker = 0;
1669 truncated = false;
1670 }
1671
1672 void init(RGWRados *store, struct req_state *s, RGWHandler *h) override {
1673 RGWOp::init(store, s, h);
1674 policy = RGWAccessControlPolicy(s->cct);
1675 }
1676 int verify_permission() override;
1677 void pre_exec() override;
1678 void execute() override;
1679
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; }
1685};
1686
1687struct RGWMultipartUploadEntry {
1688 rgw_bucket_dir_entry obj;
1689 RGWMPObj mp;
1690};
1691
1692class RGWListBucketMultiparts : public RGWOp {
1693protected:
1694 string prefix;
1695 RGWMPObj marker;
1696 RGWMultipartUploadEntry next_marker;
1697 int max_uploads;
1698 string delimiter;
1699 vector<RGWMultipartUploadEntry> uploads;
1700 map<string, bool> common_prefixes;
1701 bool is_truncated;
1702 int default_max;
1703
1704public:
1705 RGWListBucketMultiparts() {
1706 max_uploads = 0;
1707 is_truncated = false;
1708 default_max = 0;
1709 }
1710
1711 void init(RGWRados *store, struct req_state *s, RGWHandler *h) override {
1712 RGWOp::init(store, s, h);
1713 max_uploads = default_max;
1714 }
1715
1716 int verify_permission() override;
1717 void pre_exec() override;
1718 void execute() override;
1719
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; }
1725};
1726
1727
1728class RGWGetCrossDomainPolicy : public RGWOp {
1729public:
1730 RGWGetCrossDomainPolicy() = default;
1731 ~RGWGetCrossDomainPolicy() override = default;
1732
1733 int verify_permission() override {
1734 return 0;
1735 }
1736
1737 void execute() override {
1738 op_ret = 0;
1739 }
1740
1741 const string name() override {
1742 return "get_crossdomain_policy";
1743 }
1744
1745 RGWOpType get_type() override {
1746 return RGW_OP_GET_CROSS_DOMAIN_POLICY;
1747 }
1748
1749 uint32_t op_mask() override {
1750 return RGW_OP_TYPE_READ;
1751 }
1752};
1753
1754
1755class RGWGetHealthCheck : public RGWOp {
1756public:
1757 RGWGetHealthCheck() = default;
1758 ~RGWGetHealthCheck() override = default;
1759
1760 int verify_permission() override {
1761 return 0;
1762 }
1763
1764 void execute() override;
1765
1766 const string name() override {
1767 return "get_health_check";
1768 }
1769
1770 RGWOpType get_type() override {
1771 return RGW_OP_GET_HEALTH_CHECK;
1772 }
1773
1774 uint32_t op_mask() override {
1775 return RGW_OP_TYPE_READ;
1776 }
1777};
1778
1779
1780class RGWDeleteMultiObj : public RGWOp {
1781protected:
1782 int max_to_delete;
1783 int len;
1784 char *data;
1785 rgw_bucket bucket;
1786 bool quiet;
1787 bool status_dumped;
31f18b77 1788 bool acl_allowed = false;
7c673cae
FG
1789
1790public:
1791 RGWDeleteMultiObj() {
1792 max_to_delete = 1000;
1793 len = 0;
1794 data = NULL;
1795 quiet = false;
1796 status_dumped = false;
1797 }
1798 int verify_permission() override;
1799 void pre_exec() override;
1800 void execute() override;
1801
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; }
1811};
1812
1813class RGWInfo: public RGWOp {
1814public:
1815 RGWInfo() = default;
1816 ~RGWInfo() override = default;
1817
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; }
1822};
1823
1824extern int rgw_build_bucket_policies(RGWRados* store, struct req_state* s);
1825extern int rgw_build_object_policies(RGWRados *store, struct req_state *s,
31f18b77
FG
1826 bool prefetch_data);
1827extern rgw::IAM::Environment rgw_build_iam_environment(RGWRados* store,
1828 struct req_state* s);
7c673cae
FG
1829
1830static inline int put_data_and_throttle(RGWPutObjDataProcessor *processor,
1831 bufferlist& data, off_t ofs,
1832 bool need_to_wait)
1833{
1834 bool again = false;
1835 do {
1836 void *handle = nullptr;
1837 rgw_raw_obj obj;
1838
1839 uint64_t size = data.length();
1840
1841 int ret = processor->handle_data(data, ofs, &handle, &obj, &again);
1842 if (ret < 0)
1843 return ret;
1844 if (handle != nullptr)
1845 {
1846 ret = processor->throttle_data(handle, obj, size, need_to_wait);
1847 if (ret < 0)
1848 return ret;
1849 }
1850 else
1851 break;
1852 need_to_wait = false; /* the need to wait only applies to the first
1853 * iteration */
1854 } while (again);
1855
1856 return 0;
1857} /* put_data_and_throttle */
1858
1859
1860
1861
1862
1863static inline int get_system_versioning_params(req_state *s,
1864 uint64_t *olh_epoch,
1865 string *version_id)
1866{
1867 if (!s->system_request) {
1868 return 0;
1869 }
1870
1871 if (olh_epoch) {
1872 string epoch_str = s->info.args.get(RGW_SYS_PARAM_PREFIX "versioned-epoch");
1873 if (!epoch_str.empty()) {
1874 string err;
1875 *olh_epoch = strict_strtol(epoch_str.c_str(), 10, &err);
1876 if (!err.empty()) {
1877 lsubdout(s->cct, rgw, 0) << "failed to parse versioned-epoch param"
1878 << dendl;
1879 return -EINVAL;
1880 }
1881 }
1882 }
1883
1884 if (version_id) {
1885 *version_id = s->info.args.get(RGW_SYS_PARAM_PREFIX "version-id");
1886 }
1887
1888 return 0;
1889} /* get_system_versioning_params */
1890
1891static inline void format_xattr(std::string &xattr)
1892{
1893 /* If the extended attribute is not valid UTF-8, we encode it using
1894 * quoted-printable encoding.
1895 */
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);
1907 xattr.assign(mime);
1908 delete [] mime;
1909 }
1910} /* format_xattr */
1911
1912/**
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>
3efd9988
FG
1917 * On success returns 0.
1918 * On failure returns a negative error code.
7c673cae
FG
1919 *
1920 */
3efd9988
FG
1921static 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)
7c673cae
FG
1925{
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"
1930 };
3efd9988
FG
1931
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;
1936
7c673cae
FG
1937 if (blacklisted_headers.count(name) == 1) {
1938 lsubdout(cct, rgw, 10) << "skipping x>> " << name << dendl;
1939 continue;
3efd9988 1940 } else if (allow_empty_attrs || !xattr.empty()) {
7c673cae
FG
1941 lsubdout(cct, rgw, 10) << "x>> " << name << ":" << xattr << dendl;
1942 format_xattr(xattr);
3efd9988
FG
1943
1944 std::string attr_name(RGW_ATTR_PREFIX);
7c673cae 1945 attr_name.append(name);
3efd9988
FG
1946
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;
1955 }
1956
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) {
1962 return -EFBIG;
1963 }
1964
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) {
1971 return -E2BIG;
1972 }
1973
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. */
1977
1978 ceph::bufferlist& bl = rval.first->second;
7c673cae
FG
1979 bl.append(xattr.c_str(), xattr.size() + 1);
1980 }
1981 }
3efd9988
FG
1982
1983 return 0;
7c673cae
FG
1984} /* rgw_get_request_metadata */
1985
1986static inline void encode_delete_at_attr(boost::optional<ceph::real_time> delete_at,
1987 map<string, bufferlist>& attrs)
1988{
1989 if (delete_at == boost::none) {
1990 return;
1991 }
1992
1993 bufferlist delatbl;
1994 ::encode(*delete_at, delatbl);
1995 attrs[RGW_ATTR_DELETE_AT] = delatbl;
1996} /* encode_delete_at_attr */
1997
224ce89b
WB
1998static inline void encode_obj_tags_attr(RGWObjTags* obj_tags, map<string, bufferlist>& attrs)
1999{
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
2004 return;
2005 }
2006
2007 bufferlist tagsbl;
2008 obj_tags->encode(tagsbl);
2009 attrs[RGW_ATTR_TAGS] = tagsbl;
2010}
2011
7c673cae
FG
2012static inline int encode_dlo_manifest_attr(const char * const dlo_manifest,
2013 map<string, bufferlist>& attrs)
2014{
2015 string dm = dlo_manifest;
2016
2017 if (dm.find('/') == string::npos) {
2018 return -EINVAL;
2019 }
2020
2021 bufferlist manifest_bl;
2022 manifest_bl.append(dlo_manifest, strlen(dlo_manifest) + 1);
2023 attrs[RGW_ATTR_USER_MANIFEST] = manifest_bl;
2024
2025 return 0;
2026} /* encode_dlo_manifest_attr */
2027
2028static inline void complete_etag(MD5& hash, string *etag)
2029{
2030 char etag_buf[CEPH_CRYPTO_MD5_DIGESTSIZE];
2031 char etag_buf_str[CEPH_CRYPTO_MD5_DIGESTSIZE * 2 + 16];
2032
2033 hash.Final((byte *)etag_buf);
2034 buf_to_hex((const unsigned char *)etag_buf, CEPH_CRYPTO_MD5_DIGESTSIZE,
2035 etag_buf_str);
2036
2037 *etag = etag_buf_str;
2038} /* complete_etag */
2039
2040class RGWSetAttrs : public RGWOp {
2041protected:
2042 map<string, buffer::list> attrs;
2043
2044public:
2045 RGWSetAttrs() {}
2046 ~RGWSetAttrs() override {}
2047
2048 void emplace_attr(std::string&& key, buffer::list&& bl) {
2049 attrs.emplace(std::move(key), std::move(bl));
2050 }
2051
2052 int verify_permission() override;
2053 void pre_exec() override;
2054 void execute() override;
2055
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; }
2061};
2062
2063class RGWGetObjLayout : public RGWOp {
2064protected:
2065 RGWObjManifest *manifest{nullptr};
2066 rgw_raw_obj head_obj;
2067
2068public:
2069 RGWGetObjLayout() {
2070 }
2071
2072 int check_caps(RGWUserCaps& caps) {
2073 return caps.check_cap("admin", RGW_CAP_READ);
2074 }
2075 int verify_permission() {
2076 return check_caps(s->user->caps);
2077 }
2078 void pre_exec();
2079 void execute();
2080
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; }
2085};
2086
31f18b77
FG
2087class RGWPutBucketPolicy : public RGWOp {
2088 int len;
2089 char *data = nullptr;
2090public:
2091 RGWPutBucketPolicy() = default;
2092 ~RGWPutBucketPolicy() {
2093 if (data) {
2094 free(static_cast<void*>(data));
2095 }
2096 }
2097 void send_response() override;
2098 int verify_permission() override;
2099 uint32_t op_mask() override {
2100 return RGW_OP_TYPE_WRITE;
2101 }
2102 void execute() override;
2103 int get_params();
2104 const std::string name() override {
2105 return "put_bucket_policy";
2106 }
2107 RGWOpType get_type() override {
2108 return RGW_OP_PUT_BUCKET_POLICY;
2109 }
2110};
7c673cae 2111
31f18b77
FG
2112class RGWGetBucketPolicy : public RGWOp {
2113 buffer::list policy;
2114public:
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;
2120 }
2121 void execute() override;
2122 const std::string name() override {
2123 return "get_bucket_policy";
2124 }
2125 RGWOpType get_type() override {
2126 return RGW_OP_GET_BUCKET_POLICY;
2127 }
2128};
2129
2130class RGWDeleteBucketPolicy : public RGWOp {
2131public:
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;
2137 }
2138 void execute() override;
2139 int get_params();
2140 const std::string name() override {
2141 return "delete_bucket_policy";
2142 }
2143 RGWOpType get_type() override {
2144 return RGW_OP_DELETE_BUCKET_POLICY;
2145 }
2146};
2147
2148
2149class RGWConfigBucketMetaSearch : public RGWOp {
2150protected:
2151 std::map<std::string, uint32_t> mdsearch_config;
2152public:
2153 RGWConfigBucketMetaSearch() {}
2154
2155 int verify_permission();
2156 void pre_exec();
2157 void execute();
2158
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; }
2164};
2165
2166class RGWGetBucketMetaSearch : public RGWOp {
2167public:
2168 RGWGetBucketMetaSearch() {}
2169
2170 int verify_permission();
2171 void pre_exec();
2172 void execute() {}
2173
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; }
2178};
2179
2180class RGWDelBucketMetaSearch : public RGWOp {
2181public:
2182 RGWDelBucketMetaSearch() {}
2183
2184 int verify_permission();
2185 void pre_exec();
2186 void execute();
2187
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; }
2192};
7c673cae
FG
2193
2194#endif /* CEPH_RGW_OP_H */