]> git.proxmox.com Git - ceph.git/blame - ceph/src/rgw/rgw_op.h
update sources to v12.2.3
[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();
b32b8144 123
7c673cae
FG
124public:
125 RGWOp()
126 : s(nullptr),
127 dialect_handler(nullptr),
128 store(nullptr),
129 cors_exist(false),
130 op_ret(0) {
131 }
132
133 virtual ~RGWOp() = default;
134
135 int get_ret() const { return op_ret; }
136
137 virtual int init_processing() {
138 op_ret = init_quota();
139 if (op_ret < 0)
140 return op_ret;
141
142 return 0;
143 }
144
145 virtual void init(RGWRados *store, struct req_state *s, RGWHandler *dialect_handler) {
146 this->store = store;
147 this->s = s;
148 this->dialect_handler = dialect_handler;
149 }
150 int read_bucket_cors();
151 bool generate_cors_headers(string& origin, string& method, string& headers, string& exp_headers, unsigned *max_age);
152
153 virtual int verify_params() { return 0; }
154 virtual bool prefetch_data() { return false; }
155
156 /* Authenticate requester -- verify its identity.
157 *
158 * NOTE: typically the procedure is common across all operations of the same
159 * dialect (S3, Swift API). However, there are significant exceptions in
160 * both APIs: browser uploads, /info and OPTIONS handlers. All of them use
161 * different, specific authentication schema driving the need for per-op
162 * authentication. The alternative is to duplicate parts of the method-
163 * dispatch logic in RGWHandler::authorize() and pollute it with a lot
164 * of special cases. */
165 virtual int verify_requester(const rgw::auth::StrategyRegistry& auth_registry) {
166 /* TODO(rzarzynski): rename RGWHandler::authorize to generic_authenticate. */
167 return dialect_handler->authorize();
168 }
169 virtual int verify_permission() = 0;
170 virtual int verify_op_mask();
171 virtual void pre_exec() {}
172 virtual void execute() = 0;
173 virtual void send_response() {}
174 virtual void complete() {
175 send_response();
176 }
177 virtual const string name() = 0;
178 virtual RGWOpType get_type() { return RGW_OP_UNKNOWN; }
179
180 virtual uint32_t op_mask() { return 0; }
181
182 virtual int error_handler(int err_no, string *error_content);
183};
184
185class RGWGetObj : public RGWOp {
186protected:
187 seed torrent; // get torrent
188 const char *range_str;
189 const char *if_mod;
190 const char *if_unmod;
191 const char *if_match;
192 const char *if_nomatch;
193 uint32_t mod_zone_id;
194 uint64_t mod_pg_ver;
195 off_t ofs;
196 uint64_t total_len;
197 off_t start;
198 off_t end;
199 ceph::real_time mod_time;
200 ceph::real_time lastmod;
201 ceph::real_time unmod_time;
202 ceph::real_time *mod_ptr;
203 ceph::real_time *unmod_ptr;
204 map<string, bufferlist> attrs;
205 bool get_data;
206 bool partial_content;
207 bool range_parsed;
208 bool skip_manifest;
181888fb 209 bool skip_decrypt{false};
7c673cae
FG
210 rgw_obj obj;
211 utime_t gc_invalidate_time;
212 bool is_slo;
213 string lo_etag;
214 bool rgwx_stat; /* extended rgw stat operation */
31f18b77 215 string version_id;
7c673cae
FG
216
217 // compression attrs
218 RGWCompressionInfo cs_info;
219 off_t first_block, last_block;
220 off_t q_ofs, q_len;
221 bool first_data;
222 uint64_t cur_ofs;
223 bufferlist waiting;
31f18b77 224 uint64_t action = 0;
7c673cae
FG
225
226 int init_common();
227public:
228 RGWGetObj() {
229 range_str = NULL;
230 if_mod = NULL;
231 if_unmod = NULL;
232 if_match = NULL;
233 if_nomatch = NULL;
234 mod_zone_id = 0;
235 mod_pg_ver = 0;
236 start = 0;
237 ofs = 0;
238 total_len = 0;
239 end = -1;
240 mod_ptr = NULL;
241 unmod_ptr = NULL;
242 get_data = false;
243 partial_content = false;
244 range_parsed = false;
245 skip_manifest = false;
246 is_slo = false;
247 first_block = 0;
248 last_block = 0;
249 q_ofs = 0;
250 q_len = 0;
251 first_data = true;
252 cur_ofs = 0;
253 }
254
255 bool prefetch_data() override;
256
257 void set_get_data(bool get_data) {
258 this->get_data = get_data;
259 }
260 int verify_permission() override;
261 void pre_exec() override;
262 void execute() override;
31f18b77
FG
263 int read_user_manifest_part(
264 rgw_bucket& bucket,
265 const rgw_bucket_dir_entry& ent,
266 RGWAccessControlPolicy * const bucket_acl,
267 const boost::optional<rgw::IAM::Policy>& bucket_policy,
268 const off_t start_ofs,
269 const off_t end_ofs);
7c673cae
FG
270 int handle_user_manifest(const char *prefix);
271 int handle_slo_manifest(bufferlist& bl);
272
273 int get_data_cb(bufferlist& bl, off_t ofs, off_t len);
274
275 virtual int get_params() = 0;
276 virtual int send_response_data_error() = 0;
277 virtual int send_response_data(bufferlist& bl, off_t ofs, off_t len) = 0;
278
279 const string name() override { return "get_obj"; }
280 RGWOpType get_type() override { return RGW_OP_GET_OBJ; }
281 uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
282 virtual bool need_object_expiration() { return false; }
283 /**
284 * calculates filter used to decrypt RGW objects data
285 */
286 virtual int get_decrypt_filter(std::unique_ptr<RGWGetDataCB>* filter, RGWGetDataCB* cb, bufferlist* manifest_bl) {
287 *filter = nullptr;
288 return 0;
289 }
290};
291
292class RGWGetObj_CB : public RGWGetDataCB
293{
294 RGWGetObj *op;
295public:
296 explicit RGWGetObj_CB(RGWGetObj *_op) : op(_op) {}
297 ~RGWGetObj_CB() override {}
298
299 int handle_data(bufferlist& bl, off_t bl_ofs, off_t bl_len) override {
300 return op->get_data_cb(bl, bl_ofs, bl_len);
301 }
302};
303
304class RGWGetObj_Filter : public RGWGetDataCB
305{
306protected:
307 RGWGetDataCB* next;
308public:
309 RGWGetObj_Filter(RGWGetDataCB* next): next(next) {}
310 ~RGWGetObj_Filter() override {}
311 /**
312 * Passes data through filter.
313 * Filter can modify content of bl.
314 * When bl_len == 0 , it means 'flush
315 */
316 int handle_data(bufferlist& bl, off_t bl_ofs, off_t bl_len) override {
317 return next->handle_data(bl, bl_ofs, bl_len);
318 }
319 /**
320 * Flushes any cached data. Used by RGWGetObjFilter.
321 * Return logic same as handle_data.
322 */
323 int flush() override {
324 return next->flush();
325 }
326 /**
327 * Allows filter to extend range required for successful filtering
328 */
329 int fixup_range(off_t& ofs, off_t& end) override {
330 return next->fixup_range(ofs, end);
331 }
332};
333
224ce89b
WB
334class RGWGetObjTags : public RGWOp {
335 protected:
336 bufferlist tags_bl;
337 bool has_tags{false};
338 public:
339 int verify_permission();
340 void execute();
341 void pre_exec();
342
343 virtual void send_response_data(bufferlist& bl) = 0;
344 virtual const string name() noexcept override { return "get_obj_tags"; }
345 virtual uint32_t op_mask() { return RGW_OP_TYPE_READ; }
346 RGWOpType get_type() { return RGW_OP_GET_OBJ_TAGGING; }
347
348};
349
350class RGWPutObjTags : public RGWOp {
351 protected:
352 bufferlist tags_bl;
353 public:
354 int verify_permission();
355 void execute();
356
357 virtual void send_response() = 0;
358 virtual int get_params() = 0;
359 virtual const string name() { return "put_obj_tags"; }
360 virtual uint32_t op_mask() { return RGW_OP_TYPE_WRITE; }
361 RGWOpType get_type() { return RGW_OP_PUT_OBJ_TAGGING; }
362
363};
364
365class RGWDeleteObjTags: public RGWOp {
366 public:
367 void pre_exec();
368 int verify_permission();
369 void execute();
370
371 virtual void send_response() = 0;
372 virtual const string name() { return "delete_obj_tags"; }
373 virtual uint32_t op_mask() { return RGW_OP_TYPE_DELETE; }
374 RGWOpType get_type() { return RGW_OP_DELETE_OBJ_TAGGING;}
375};
376
7c673cae
FG
377class RGWBulkDelete : public RGWOp {
378public:
379 struct acct_path_t {
380 std::string bucket_name;
381 rgw_obj_key obj_key;
382 };
383
384 struct fail_desc_t {
385 int err;
386 acct_path_t path;
387 };
388
389 class Deleter {
390 protected:
391 unsigned int num_deleted;
392 unsigned int num_unfound;
393 std::list<fail_desc_t> failures;
394
395 RGWRados * const store;
396 req_state * const s;
397
398 public:
399 Deleter(RGWRados * const str, req_state * const s)
400 : num_deleted(0),
401 num_unfound(0),
402 store(str),
403 s(s) {
404 }
405
406 unsigned int get_num_deleted() const {
407 return num_deleted;
408 }
409
410 unsigned int get_num_unfound() const {
411 return num_unfound;
412 }
413
414 const std::list<fail_desc_t> get_failures() const {
415 return failures;
416 }
417
418 bool verify_permission(RGWBucketInfo& binfo,
419 map<string, bufferlist>& battrs,
420 ACLOwner& bucket_owner /* out */);
421 bool delete_single(const acct_path_t& path);
422 bool delete_chunk(const std::list<acct_path_t>& paths);
423 };
424 /* End of Deleter subclass */
425
426 static const size_t MAX_CHUNK_ENTRIES = 1024;
427
428protected:
429 std::unique_ptr<Deleter> deleter;
430
431public:
432 RGWBulkDelete()
433 : deleter(nullptr) {
434 }
435
436 int verify_permission() override;
437 void pre_exec() override;
438 void execute() override;
439
440 virtual int get_data(std::list<acct_path_t>& items,
441 bool * is_truncated) = 0;
442 void send_response() override = 0;
443
444 const string name() override { return "bulk_delete"; }
445 RGWOpType get_type() override { return RGW_OP_BULK_DELETE; }
446 uint32_t op_mask() override { return RGW_OP_TYPE_DELETE; }
447};
448
449inline ostream& operator<<(ostream& out, const RGWBulkDelete::acct_path_t &o) {
450 return out << o.bucket_name << "/" << o.obj_key;
451}
452
453
454class RGWBulkUploadOp : public RGWOp {
455 boost::optional<RGWObjectCtx> dir_ctx;
456
457protected:
458 class fail_desc_t {
459 public:
460 fail_desc_t(const int err, std::string path)
461 : err(err),
462 path(std::move(path)) {
463 }
464
465 const int err;
466 const std::string path;
467 };
468
469 static constexpr std::array<int, 2> terminal_errors = {
470 { -EACCES, -EPERM }
471 };
472
473 /* FIXME: boost::container::small_vector<fail_desc_t, 4> failures; */
474 std::vector<fail_desc_t> failures;
475 size_t num_created;
476
477 class StreamGetter;
478 class DecoratedStreamGetter;
479 class AlignedStreamGetter;
480
481 virtual std::unique_ptr<StreamGetter> create_stream() = 0;
482 virtual void send_response() = 0;
483
484 boost::optional<std::pair<std::string, rgw_obj_key>>
485 parse_path(const boost::string_ref& path);
486
487 std::pair<std::string, std::string>
488 handle_upload_path(struct req_state *s);
489
490 bool handle_file_verify_permission(RGWBucketInfo& binfo,
31f18b77
FG
491 const rgw_obj& obj,
492 std::map<std::string, ceph::bufferlist>& battrs,
7c673cae
FG
493 ACLOwner& bucket_owner /* out */);
494 int handle_file(boost::string_ref path,
495 size_t size,
496 AlignedStreamGetter& body);
497
498 int handle_dir_verify_permission();
499 int handle_dir(boost::string_ref path);
500
501public:
502 RGWBulkUploadOp()
503 : num_created(0) {
504 }
505
506 void init(RGWRados* const store,
507 struct req_state* const s,
508 RGWHandler* const h) override {
509 RGWOp::init(store, s, h);
510 dir_ctx.emplace(store);
511 }
512
513 int verify_permission() override;
514 void pre_exec() override;
515 void execute() override;
516
517 const std::string name() override {
518 return "bulk_upload";
519 }
520
521 RGWOpType get_type() override {
522 return RGW_OP_BULK_UPLOAD;
523 }
524
525 uint32_t op_mask() override {
526 return RGW_OP_TYPE_WRITE;
527 }
528}; /* RGWBulkUploadOp */
529
530
531class RGWBulkUploadOp::StreamGetter {
532public:
533 StreamGetter() = default;
534 virtual ~StreamGetter() = default;
535
536 virtual ssize_t get_at_most(size_t want, ceph::bufferlist& dst) = 0;
537 virtual ssize_t get_exactly(size_t want, ceph::bufferlist& dst) = 0;
538}; /* End of nested subclass StreamGetter */
539
540
541class RGWBulkUploadOp::DecoratedStreamGetter : public StreamGetter {
542 StreamGetter& decoratee;
543
544protected:
545 StreamGetter& get_decoratee() {
546 return decoratee;
547 }
548
549public:
550 DecoratedStreamGetter(StreamGetter& decoratee)
551 : decoratee(decoratee) {
552 }
553 virtual ~DecoratedStreamGetter() = default;
554
555 ssize_t get_at_most(const size_t want, ceph::bufferlist& dst) override {
556 return get_decoratee().get_at_most(want, dst);
557 }
558
559 ssize_t get_exactly(const size_t want, ceph::bufferlist& dst) override {
560 return get_decoratee().get_exactly(want, dst);
561 }
562}; /* RGWBulkUploadOp::DecoratedStreamGetter */
563
564
565class RGWBulkUploadOp::AlignedStreamGetter
566 : public RGWBulkUploadOp::DecoratedStreamGetter {
567 size_t position;
568 size_t length;
569 size_t alignment;
570
571public:
572 template <typename U>
573 AlignedStreamGetter(const size_t position,
574 const size_t length,
575 const size_t alignment,
576 U&& decoratee)
577 : DecoratedStreamGetter(std::forward<U>(decoratee)),
578 position(position),
579 length(length),
580 alignment(alignment) {
581 }
582 virtual ~AlignedStreamGetter();
583 ssize_t get_at_most(size_t want, ceph::bufferlist& dst) override;
584 ssize_t get_exactly(size_t want, ceph::bufferlist& dst) override;
585}; /* RGWBulkUploadOp::AlignedStreamGetter */
586
587
3efd9988
FG
588struct RGWUsageStats {
589 uint64_t bytes_used = 0;
590 uint64_t bytes_used_rounded = 0;
591 uint64_t buckets_count = 0;
592 uint64_t objects_count = 0;
593};
594
7c673cae
FG
595#define RGW_LIST_BUCKETS_LIMIT_MAX 10000
596
597class RGWListBuckets : public RGWOp {
598protected:
599 bool sent_data;
3efd9988
FG
600 std::string marker;
601 std::string end_marker;
7c673cae
FG
602 int64_t limit;
603 uint64_t limit_max;
3efd9988 604 std::map<std::string, ceph::bufferlist> attrs;
7c673cae
FG
605 bool is_truncated;
606
3efd9988
FG
607 RGWUsageStats global_stats;
608 std::map<std::string, RGWUsageStats> policies_stats;
609
7c673cae
FG
610 virtual uint64_t get_default_max() const {
611 return 1000;
612 }
613
614public:
3efd9988
FG
615 RGWListBuckets()
616 : sent_data(false),
617 limit(RGW_LIST_BUCKETS_LIMIT_MAX),
618 limit_max(RGW_LIST_BUCKETS_LIMIT_MAX),
619 is_truncated(false) {
7c673cae
FG
620 }
621
622 int verify_permission() override;
623 void execute() override;
624
625 virtual int get_params() = 0;
3efd9988
FG
626 virtual void handle_listing_chunk(RGWUserBuckets&& buckets) {
627 /* The default implementation, used by e.g. S3, just generates a new
628 * part of listing and sends it client immediately. Swift can behave
629 * differently: when the reverse option is requested, all incoming
630 * instances of RGWUserBuckets are buffered and finally reversed. */
631 return send_response_data(buckets);
632 }
7c673cae
FG
633 virtual void send_response_begin(bool has_buckets) = 0;
634 virtual void send_response_data(RGWUserBuckets& buckets) = 0;
635 virtual void send_response_end() = 0;
636 void send_response() override {}
637
638 virtual bool should_get_stats() { return false; }
639 virtual bool supports_account_metadata() { return false; }
640
641 const string name() override { return "list_buckets"; }
642 RGWOpType get_type() override { return RGW_OP_LIST_BUCKETS; }
643 uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
644};
645
646class RGWGetUsage : public RGWOp {
647protected:
648 bool sent_data;
649 string start_date;
650 string end_date;
651 int show_log_entries;
652 int show_log_sum;
653 map<string, bool> categories;
654 map<rgw_user_bucket, rgw_usage_log_entry> usage;
655 map<string, rgw_usage_log_entry> summary_map;
c07f9fc5 656 map<string, cls_user_bucket_entry> buckets_usage;
7c673cae
FG
657 cls_user_header header;
658public:
659 RGWGetUsage() : sent_data(false), show_log_entries(true), show_log_sum(true){
660 }
661
662 int verify_permission() override;
663 void execute() override;
664
665 virtual int get_params() = 0;
666 void send_response() override {}
667
668 virtual bool should_get_stats() { return false; }
669
670 const string name() override { return "get_usage"; }
671 uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
672};
673
674class RGWStatAccount : public RGWOp {
675protected:
3efd9988
FG
676 RGWUsageStats global_stats;
677 std::map<std::string, RGWUsageStats> policies_stats;
7c673cae
FG
678
679public:
3efd9988 680 RGWStatAccount() = default;
7c673cae
FG
681
682 int verify_permission() override;
683 void execute() override;
684
685 void send_response() override = 0;
3efd9988 686 const std::string name() override { return "stat_account"; }
7c673cae
FG
687 RGWOpType get_type() override { return RGW_OP_STAT_ACCOUNT; }
688 uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
689};
690
691class RGWListBucket : public RGWOp {
692protected:
693 RGWBucketEnt bucket;
694 string prefix;
695 rgw_obj_key marker;
696 rgw_obj_key next_marker;
697 rgw_obj_key end_marker;
698 string max_keys;
699 string delimiter;
700 string encoding_type;
701 bool list_versions;
702 int max;
703 vector<rgw_bucket_dir_entry> objs;
704 map<string, bool> common_prefixes;
705
706 int default_max;
707 bool is_truncated;
708
709 int shard_id;
710
711 int parse_max_keys();
712
713public:
714 RGWListBucket() : list_versions(false), max(0),
715 default_max(0), is_truncated(false), shard_id(-1) {}
716 int verify_permission() override;
717 void pre_exec() override;
718 void execute() override;
719
720 virtual int get_params() = 0;
721 void send_response() override = 0;
722 const string name() override { return "list_bucket"; }
723 RGWOpType get_type() override { return RGW_OP_LIST_BUCKET; }
724 uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
725 virtual bool need_container_stats() { return false; }
726};
727
728class RGWGetBucketLogging : public RGWOp {
729public:
730 RGWGetBucketLogging() {}
731 int verify_permission() override;
732 void execute() override { }
733
734 void send_response() override = 0;
735 const string name() override { return "get_bucket_logging"; }
736 RGWOpType get_type() override { return RGW_OP_GET_BUCKET_LOGGING; }
737 uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
738};
739
740class RGWGetBucketLocation : public RGWOp {
741public:
742 RGWGetBucketLocation() {}
743 ~RGWGetBucketLocation() override {}
744 int verify_permission() override;
745 void execute() override { }
746
747 void send_response() override = 0;
748 const string name() override { return "get_bucket_location"; }
3efd9988 749 RGWOpType get_type() override { return RGW_OP_GET_BUCKET_LOCATION; }
7c673cae
FG
750 uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
751};
752
753class RGWGetBucketVersioning : public RGWOp {
754protected:
755 bool versioned;
756 bool versioning_enabled;
757public:
758 RGWGetBucketVersioning() : versioned(false), versioning_enabled(false) {}
759
760 int verify_permission() override;
761 void pre_exec() override;
762 void execute() override;
763
764 void send_response() override = 0;
765 const string name() override { return "get_bucket_versioning"; }
766 RGWOpType get_type() override { return RGW_OP_GET_BUCKET_VERSIONING; }
767 uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
768};
769
770class RGWSetBucketVersioning : public RGWOp {
771protected:
772 bool enable_versioning;
773 bufferlist in_data;
774public:
775 RGWSetBucketVersioning() : enable_versioning(false) {}
776
777 int verify_permission() override;
778 void pre_exec() override;
779 void execute() override;
780
781 virtual int get_params() { return 0; }
782
783 void send_response() override = 0;
784 const string name() override { return "set_bucket_versioning"; }
785 RGWOpType get_type() override { return RGW_OP_SET_BUCKET_VERSIONING; }
786 uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
787};
788
789class RGWGetBucketWebsite : public RGWOp {
790public:
791 RGWGetBucketWebsite() {}
792
793 int verify_permission() override;
794 void pre_exec() override;
795 void execute() override;
796
797 void send_response() override = 0;
798 const string name() override { return "get_bucket_website"; }
799 RGWOpType get_type() override { return RGW_OP_GET_BUCKET_WEBSITE; }
800 uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
801};
802
803class RGWSetBucketWebsite : public RGWOp {
804protected:
31f18b77 805 bufferlist in_data;
7c673cae
FG
806 RGWBucketWebsiteConf website_conf;
807public:
808 RGWSetBucketWebsite() {}
809
810 int verify_permission() override;
811 void pre_exec() override;
812 void execute() override;
813
814 virtual int get_params() { return 0; }
815
816 void send_response() override = 0;
817 const string name() override { return "set_bucket_website"; }
818 RGWOpType get_type() override { return RGW_OP_SET_BUCKET_WEBSITE; }
819 uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
820};
821
822class RGWDeleteBucketWebsite : public RGWOp {
823public:
824 RGWDeleteBucketWebsite() {}
825
826 int verify_permission() override;
827 void pre_exec() override;
828 void execute() override;
829
830 void send_response() override = 0;
831 const string name() override { return "delete_bucket_website"; }
832 RGWOpType get_type() override { return RGW_OP_SET_BUCKET_WEBSITE; }
833 uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
834};
835
836class RGWStatBucket : public RGWOp {
837protected:
838 RGWBucketEnt bucket;
839
840public:
841 RGWStatBucket() {}
842 ~RGWStatBucket() override {}
843
844 int verify_permission() override;
845 void pre_exec() override;
846 void execute() override;
847
848 void send_response() override = 0;
849 const string name() override { return "stat_bucket"; }
850 RGWOpType get_type() override { return RGW_OP_STAT_BUCKET; }
851 uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
852};
853
854class RGWCreateBucket : public RGWOp {
855protected:
856 RGWAccessControlPolicy policy;
857 string location_constraint;
858 string placement_rule;
859 RGWBucketInfo info;
860 obj_version ep_objv;
861 bool has_cors;
862 RGWCORSConfiguration cors_config;
863 boost::optional<std::string> swift_ver_location;
864 map<string, buffer::list> attrs;
865 set<string> rmattr_names;
866
867 bufferlist in_data;
868
869 virtual bool need_metadata_upload() const { return false; }
870
871public:
872 RGWCreateBucket() : has_cors(false) {}
873
874 void emplace_attr(std::string&& key, buffer::list&& bl) {
875 attrs.emplace(std::move(key), std::move(bl)); /* key and bl are r-value refs */
876 }
877
878 int verify_permission() override;
879 void pre_exec() override;
880 void execute() override;
881 void init(RGWRados *store, struct req_state *s, RGWHandler *h) override {
882 RGWOp::init(store, s, h);
883 policy.set_ctx(s->cct);
884 }
885 virtual int get_params() { return 0; }
886 void send_response() override = 0;
887 const string name() override { return "create_bucket"; }
888 RGWOpType get_type() override { return RGW_OP_CREATE_BUCKET; }
889 uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
890};
891
892class RGWDeleteBucket : public RGWOp {
893protected:
894 RGWObjVersionTracker objv_tracker;
895
896public:
897 RGWDeleteBucket() {}
898
899 int verify_permission() override;
900 void pre_exec() override;
901 void execute() override;
902
903 void send_response() override = 0;
904 const string name() override { return "delete_bucket"; }
905 RGWOpType get_type() override { return RGW_OP_DELETE_BUCKET; }
906 uint32_t op_mask() override { return RGW_OP_TYPE_DELETE; }
907};
908
909struct rgw_slo_entry {
910 string path;
911 string etag;
912 uint64_t size_bytes;
913
914 rgw_slo_entry() : size_bytes(0) {}
915
916 void encode(bufferlist& bl) const {
917 ENCODE_START(1, 1, bl);
918 ::encode(path, bl);
919 ::encode(etag, bl);
920 ::encode(size_bytes, bl);
921 ENCODE_FINISH(bl);
922 }
923
924 void decode(bufferlist::iterator& bl) {
925 DECODE_START(1, bl);
926 ::decode(path, bl);
927 ::decode(etag, bl);
928 ::decode(size_bytes, bl);
929 DECODE_FINISH(bl);
930 }
931
932 void decode_json(JSONObj *obj);
933};
934WRITE_CLASS_ENCODER(rgw_slo_entry)
935
936struct RGWSLOInfo {
937 vector<rgw_slo_entry> entries;
938 uint64_t total_size;
939
940 /* in memory only */
941 char *raw_data;
942 int raw_data_len;
943
944 RGWSLOInfo() : total_size(0), raw_data(NULL), raw_data_len(0) {}
945 ~RGWSLOInfo() {
946 free(raw_data);
947 }
948
949 void encode(bufferlist& bl) const {
950 ENCODE_START(1, 1, bl);
951 ::encode(entries, bl);
952 ::encode(total_size, bl);
953 ENCODE_FINISH(bl);
954 }
955
956 void decode(bufferlist::iterator& bl) {
957 DECODE_START(1, bl);
958 ::decode(entries, bl);
959 ::decode(total_size, bl);
960 DECODE_FINISH(bl);
961 }
962};
963WRITE_CLASS_ENCODER(RGWSLOInfo)
964
965class RGWPutObj : public RGWOp {
966
967 friend class RGWPutObjProcessor;
968
969protected:
970 seed torrent;
971 off_t ofs;
972 const char *supplied_md5_b64;
973 const char *supplied_etag;
974 const char *if_match;
975 const char *if_nomatch;
976 const char *copy_source;
977 const char *copy_source_range;
978 RGWBucketInfo copy_source_bucket_info;
979 string copy_source_tenant_name;
980 string copy_source_bucket_name;
981 string copy_source_object_name;
982 string copy_source_version_id;
983 off_t copy_source_range_fst;
984 off_t copy_source_range_lst;
985 string etag;
986 bool chunked_upload;
987 RGWAccessControlPolicy policy;
224ce89b 988 std::unique_ptr <RGWObjTags> obj_tags;
7c673cae
FG
989 const char *dlo_manifest;
990 RGWSLOInfo *slo_info;
991 map<string, bufferlist> attrs;
992 ceph::real_time mtime;
993 uint64_t olh_epoch;
994 string version_id;
995 bufferlist bl_aux;
996 map<string, string> crypt_http_responses;
997 string user_data;
998
999 boost::optional<ceph::real_time> delete_at;
1000
1001public:
1002 RGWPutObj() : ofs(0),
1003 supplied_md5_b64(NULL),
1004 supplied_etag(NULL),
1005 if_match(NULL),
1006 if_nomatch(NULL),
1007 copy_source(NULL),
1008 copy_source_range(NULL),
1009 copy_source_range_fst(0),
1010 copy_source_range_lst(0),
1011 chunked_upload(0),
1012 dlo_manifest(NULL),
1013 slo_info(NULL),
1014 olh_epoch(0) {}
1015
1016 ~RGWPutObj() override {
1017 delete slo_info;
1018 }
1019
1020 void init(RGWRados *store, struct req_state *s, RGWHandler *h) override {
1021 RGWOp::init(store, s, h);
1022 policy.set_ctx(s->cct);
1023 }
1024
1025 void emplace_attr(std::string&& key, buffer::list&& bl) {
1026 attrs.emplace(std::move(key), std::move(bl)); /* key and bl are r-value refs */
1027 }
1028
1029 virtual RGWPutObjProcessor *select_processor(RGWObjectCtx& obj_ctx, bool *is_multipart);
1030 void dispose_processor(RGWPutObjDataProcessor *processor);
1031
1032 int verify_permission() override;
1033 void pre_exec() override;
1034 void execute() override;
1035
1036 /* this is for cases when copying data from other object */
1037 virtual int get_decrypt_filter(std::unique_ptr<RGWGetDataCB>* filter,
1038 RGWGetDataCB* cb,
1039 map<string, bufferlist>& attrs,
1040 bufferlist* manifest_bl) {
1041 *filter = nullptr;
1042 return 0;
1043 }
1044 virtual int get_encrypt_filter(std::unique_ptr<RGWPutObjDataProcessor> *filter, RGWPutObjDataProcessor* cb) {
1045 *filter = nullptr;
1046 return 0;
1047 }
1048
1049 int get_data_cb(bufferlist& bl, off_t bl_ofs, off_t bl_len);
1050 int get_data(const off_t fst, const off_t lst, bufferlist& bl);
1051
1052 virtual int get_params() = 0;
1053 virtual int get_data(bufferlist& bl) = 0;
1054 void send_response() override = 0;
1055 const string name() override { return "put_obj"; }
1056 RGWOpType get_type() override { return RGW_OP_PUT_OBJ; }
1057 uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
1058};
1059
1060class RGWPutObj_Filter : public RGWPutObjDataProcessor
1061{
1062protected:
1063 RGWPutObjDataProcessor* next;
1064public:
1065 RGWPutObj_Filter(RGWPutObjDataProcessor* next) :
1066 next(next){}
1067 ~RGWPutObj_Filter() override {}
1068 int handle_data(bufferlist& bl, off_t ofs, void **phandle, rgw_raw_obj *pobj, bool *again) override {
1069 return next->handle_data(bl, ofs, phandle, pobj, again);
1070 }
1071 int throttle_data(void *handle, const rgw_raw_obj& obj, uint64_t size, bool need_to_wait) override {
1072 return next->throttle_data(handle, obj, size, need_to_wait);
1073 }
1074}; /* RGWPutObj_Filter */
1075
1076class RGWPostObj : public RGWOp {
1077protected:
1078 off_t min_len;
1079 off_t max_len;
1080 int len;
1081 off_t ofs;
1082 const char *supplied_md5_b64;
1083 const char *supplied_etag;
1084 string etag;
1085 RGWAccessControlPolicy policy;
1086 map<string, bufferlist> attrs;
1087 boost::optional<ceph::real_time> delete_at;
1088
1089 /* Must be called after get_data() or the result is undefined. */
1090 virtual std::string get_current_filename() const = 0;
1091 virtual std::string get_current_content_type() const = 0;
1092 virtual bool is_next_file_to_upload() {
1093 return false;
1094 }
1095public:
1096 RGWPostObj() : min_len(0),
1097 max_len(LLONG_MAX),
1098 len(0),
1099 ofs(0),
1100 supplied_md5_b64(nullptr),
1101 supplied_etag(nullptr) {
1102 }
1103
1104 void emplace_attr(std::string&& key, buffer::list&& bl) {
1105 attrs.emplace(std::move(key), std::move(bl)); /* key and bl are r-value refs */
1106 }
1107
1108 void init(RGWRados *store, struct req_state *s, RGWHandler *h) override {
1109 RGWOp::init(store, s, h);
1110 policy.set_ctx(s->cct);
1111 }
1112
1113 int verify_permission() override;
1114 void pre_exec() override;
1115 void execute() override;
1116
1117 virtual int get_encrypt_filter(std::unique_ptr<RGWPutObjDataProcessor> *filter, RGWPutObjDataProcessor* cb) {
1118 *filter = nullptr;
1119 return 0;
1120 }
1121 virtual int get_params() = 0;
1122 virtual int get_data(ceph::bufferlist& bl, bool& again) = 0;
1123 void send_response() override = 0;
1124 const std::string name() override { return "post_obj"; }
1125 RGWOpType get_type() override { return RGW_OP_POST_OBJ; }
1126 uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
1127};
1128
1129class RGWPutMetadataAccount : public RGWOp {
1130protected:
1131 std::set<std::string> rmattr_names;
1132 std::map<std::string, bufferlist> attrs, orig_attrs;
1133 std::map<int, std::string> temp_url_keys;
1134 RGWQuotaInfo new_quota;
1135 bool new_quota_extracted;
1136
1137 RGWObjVersionTracker acct_op_tracker;
1138
1139 RGWAccessControlPolicy policy;
1140 bool has_policy;
1141
1142public:
1143 RGWPutMetadataAccount()
1144 : new_quota_extracted(false),
1145 has_policy(false) {
1146 }
1147
1148 void init(RGWRados *store, struct req_state *s, RGWHandler *h) override {
1149 RGWOp::init(store, s, h);
1150 policy.set_ctx(s->cct);
1151 }
1152 int init_processing() override;
1153 int verify_permission() override;
1154 void pre_exec() override { }
1155 void execute() override;
1156
1157 virtual int get_params() = 0;
1158 void send_response() override = 0;
1159 virtual void filter_out_temp_url(map<string, bufferlist>& add_attrs,
1160 const set<string>& rmattr_names,
1161 map<int, string>& temp_url_keys);
1162 const string name() override { return "put_account_metadata"; }
1163 RGWOpType get_type() override { return RGW_OP_PUT_METADATA_ACCOUNT; }
1164 uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
1165};
1166
1167class RGWPutMetadataBucket : public RGWOp {
1168protected:
1169 map<string, buffer::list> attrs;
1170 set<string> rmattr_names;
1171 bool has_policy, has_cors;
1172 uint32_t policy_rw_mask;
1173 RGWAccessControlPolicy policy;
1174 RGWCORSConfiguration cors_config;
1175 string placement_rule;
1176 boost::optional<std::string> swift_ver_location;
1177
1178public:
1179 RGWPutMetadataBucket()
1180 : has_policy(false), has_cors(false), policy_rw_mask(0)
1181 {}
1182
1183 void emplace_attr(std::string&& key, buffer::list&& bl) {
1184 attrs.emplace(std::move(key), std::move(bl)); /* key and bl are r-value refs */
1185 }
1186
1187 void init(RGWRados *store, struct req_state *s, RGWHandler *h) override {
1188 RGWOp::init(store, s, h);
1189 policy.set_ctx(s->cct);
1190 }
1191
1192 int verify_permission() override;
1193 void pre_exec() override;
1194 void execute() override;
1195
1196 virtual int get_params() = 0;
1197 void send_response() override = 0;
1198 const string name() override { return "put_bucket_metadata"; }
1199 RGWOpType get_type() override { return RGW_OP_PUT_METADATA_BUCKET; }
1200 uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
1201};
1202
1203class RGWPutMetadataObject : public RGWOp {
1204protected:
1205 RGWAccessControlPolicy policy;
1206 string placement_rule;
1207 boost::optional<ceph::real_time> delete_at;
1208 const char *dlo_manifest;
1209
1210public:
1211 RGWPutMetadataObject()
1212 : dlo_manifest(NULL)
1213 {}
1214
1215 void init(RGWRados *store, struct req_state *s, RGWHandler *h) override {
1216 RGWOp::init(store, s, h);
1217 policy.set_ctx(s->cct);
1218 }
1219 int verify_permission() override;
1220 void pre_exec() override;
1221 void execute() override;
1222
1223 virtual int get_params() = 0;
1224 void send_response() override = 0;
1225 const string name() override { return "put_obj_metadata"; }
1226 RGWOpType get_type() override { return RGW_OP_PUT_METADATA_OBJECT; }
1227 uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
1228 virtual bool need_object_expiration() { return false; }
1229};
1230
1231class RGWDeleteObj : public RGWOp {
1232protected:
1233 bool delete_marker;
1234 bool multipart_delete;
1235 string version_id;
1236 ceph::real_time unmod_since; /* if unmodified since */
1237 bool no_precondition_error;
1238 std::unique_ptr<RGWBulkDelete::Deleter> deleter;
1239
1240public:
1241 RGWDeleteObj()
1242 : delete_marker(false),
1243 multipart_delete(false),
1244 no_precondition_error(false),
1245 deleter(nullptr) {
1246 }
1247
1248 int verify_permission() override;
1249 void pre_exec() override;
1250 void execute() override;
1251 int handle_slo_manifest(bufferlist& bl);
1252
1253 virtual int get_params() { return 0; }
1254 void send_response() override = 0;
1255 const string name() override { return "delete_obj"; }
1256 RGWOpType get_type() override { return RGW_OP_DELETE_OBJ; }
1257 uint32_t op_mask() override { return RGW_OP_TYPE_DELETE; }
1258 virtual bool need_object_expiration() { return false; }
1259};
1260
1261class RGWCopyObj : public RGWOp {
1262protected:
1263 RGWAccessControlPolicy dest_policy;
1264 const char *if_mod;
1265 const char *if_unmod;
1266 const char *if_match;
1267 const char *if_nomatch;
1268 off_t ofs;
1269 off_t len;
1270 off_t end;
1271 ceph::real_time mod_time;
1272 ceph::real_time unmod_time;
1273 ceph::real_time *mod_ptr;
1274 ceph::real_time *unmod_ptr;
1275 map<string, buffer::list> attrs;
1276 string src_tenant_name, src_bucket_name;
1277 rgw_bucket src_bucket;
1278 rgw_obj_key src_object;
1279 string dest_tenant_name, dest_bucket_name;
1280 rgw_bucket dest_bucket;
1281 string dest_object;
1282 ceph::real_time src_mtime;
1283 ceph::real_time mtime;
1284 RGWRados::AttrsMod attrs_mod;
1285 RGWBucketInfo src_bucket_info;
1286 RGWBucketInfo dest_bucket_info;
1287 string source_zone;
1288 string client_id;
1289 string op_id;
1290 ceph::buffer::list etag;
1291
1292 off_t last_ofs;
1293
1294 string version_id;
1295 uint64_t olh_epoch;
1296
1297 boost::optional<ceph::real_time> delete_at;
1298 bool copy_if_newer;
1299
1300 int init_common();
1301
1302public:
1303 RGWCopyObj() {
1304 if_mod = NULL;
1305 if_unmod = NULL;
1306 if_match = NULL;
1307 if_nomatch = NULL;
1308 ofs = 0;
1309 len = 0;
1310 end = -1;
1311 mod_ptr = NULL;
1312 unmod_ptr = NULL;
1313 attrs_mod = RGWRados::ATTRSMOD_NONE;
1314 last_ofs = 0;
1315 olh_epoch = 0;
1316 copy_if_newer = false;
1317 }
1318
1319 static bool parse_copy_location(const string& src,
1320 string& bucket_name,
1321 rgw_obj_key& object);
1322
1323 void emplace_attr(std::string&& key, buffer::list&& bl) {
1324 attrs.emplace(std::move(key), std::move(bl));
1325 }
1326
1327 void init(RGWRados *store, struct req_state *s, RGWHandler *h) override {
1328 RGWOp::init(store, s, h);
1329 dest_policy.set_ctx(s->cct);
1330 }
1331 int verify_permission() override;
1332 void pre_exec() override;
1333 void execute() override;
1334 void progress_cb(off_t ofs);
1335
1336 virtual int init_dest_policy() { return 0; }
1337 virtual int get_params() = 0;
1338 virtual void send_partial_response(off_t ofs) {}
1339 void send_response() override = 0;
1340 const string name() override { return "copy_obj"; }
1341 RGWOpType get_type() override { return RGW_OP_COPY_OBJ; }
1342 uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
1343};
1344
1345class RGWGetACLs : public RGWOp {
1346protected:
1347 string acls;
1348
1349public:
1350 RGWGetACLs() {}
1351
1352 int verify_permission() override;
1353 void pre_exec() override;
1354 void execute() override;
1355
1356 void send_response() override = 0;
1357 const string name() override { return "get_acls"; }
1358 RGWOpType get_type() override { return RGW_OP_GET_ACLS; }
1359 uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
1360};
1361
1362class RGWPutACLs : public RGWOp {
1363protected:
1364 int len;
1365 char *data;
1366 ACLOwner owner;
1367
1368public:
1369 RGWPutACLs() {
1370 len = 0;
1371 data = NULL;
1372 }
1373 ~RGWPutACLs() override {
1374 free(data);
1375 }
1376
1377 int verify_permission() override;
1378 void pre_exec() override;
1379 void execute() override;
1380
1381 virtual int get_policy_from_state(RGWRados *store, struct req_state *s, stringstream& ss) { return 0; }
1382 virtual int get_params() = 0;
1383 void send_response() override = 0;
1384 const string name() override { return "put_acls"; }
1385 RGWOpType get_type() override { return RGW_OP_PUT_ACLS; }
1386 uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
1387};
1388
1389class RGWGetLC : public RGWOp {
1390protected:
1391
1392public:
1393 RGWGetLC() { }
1394 ~RGWGetLC() override { }
1395
1396 int verify_permission() override;
1397 void pre_exec() override;
1398 void execute() override = 0;
1399
1400 void send_response() override = 0;
1401 const string name() override { return "get_lifecycle"; }
d2e6a577 1402 RGWOpType get_type() override { return RGW_OP_GET_LC; }
7c673cae
FG
1403 uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
1404};
1405
1406class RGWPutLC : public RGWOp {
1407protected:
1408 int len;
1409 char *data;
b32b8144 1410 const char *content_md5;
7c673cae
FG
1411 string cookie;
1412
1413public:
1414 RGWPutLC() {
1415 len = 0;
b32b8144
FG
1416 data = nullptr;
1417 content_md5 = nullptr;
7c673cae
FG
1418 }
1419 ~RGWPutLC() override {
1420 free(data);
1421 }
1422
1423 void init(RGWRados *store, struct req_state *s, RGWHandler *dialect_handler) override {
1424#define COOKIE_LEN 16
1425 char buf[COOKIE_LEN + 1];
1426
1427 RGWOp::init(store, s, dialect_handler);
1428 gen_rand_alphanumeric(s->cct, buf, sizeof(buf) - 1);
1429 cookie = buf;
1430 }
1431
1432 int verify_permission() override;
1433 void pre_exec() override;
1434 void execute() override;
1435
1436// virtual int get_policy_from_state(RGWRados *store, struct req_state *s, stringstream& ss) { return 0; }
1437 virtual int get_params() = 0;
1438 void send_response() override = 0;
1439 const string name() override { return "put_lifecycle"; }
d2e6a577 1440 RGWOpType get_type() override { return RGW_OP_PUT_LC; }
7c673cae
FG
1441 uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
1442};
1443
1444class RGWDeleteLC : public RGWOp {
1445protected:
1446 size_t len;
1447 char *data;
1448
1449public:
1450 RGWDeleteLC() {
1451 len = 0;
1452 data = NULL;
1453 }
1454 ~RGWDeleteLC() override {
1455 free(data);
1456 }
1457
1458 int verify_permission() override;
1459 void pre_exec() override;
1460 void execute() override;
1461
1462 void send_response() override = 0;
1463 const string name() override { return "delete_lifecycle"; }
d2e6a577 1464 RGWOpType get_type() override { return RGW_OP_DELETE_LC; }
7c673cae
FG
1465 uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
1466};
1467
1468class RGWGetCORS : public RGWOp {
1469protected:
1470
1471public:
1472 RGWGetCORS() {}
1473
1474 int verify_permission() override;
1475 void execute() override;
1476
1477 void send_response() override = 0;
1478 const string name() override { return "get_cors"; }
1479 RGWOpType get_type() override { return RGW_OP_GET_CORS; }
1480 uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
1481};
1482
1483class RGWPutCORS : public RGWOp {
1484protected:
1485 bufferlist cors_bl;
31f18b77 1486 bufferlist in_data;
7c673cae
FG
1487
1488public:
1489 RGWPutCORS() {}
1490 ~RGWPutCORS() override {}
1491
1492 int verify_permission() override;
1493 void execute() override;
1494
1495 virtual int get_params() = 0;
1496 void send_response() override = 0;
1497 const string name() override { return "put_cors"; }
1498 RGWOpType get_type() override { return RGW_OP_PUT_CORS; }
1499 uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
1500};
1501
1502class RGWDeleteCORS : public RGWOp {
1503protected:
1504
1505public:
1506 RGWDeleteCORS() {}
1507
1508 int verify_permission() override;
1509 void execute() override;
1510
1511 void send_response() override = 0;
1512 const string name() override { return "delete_cors"; }
1513 RGWOpType get_type() override { return RGW_OP_DELETE_CORS; }
1514 uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
1515};
1516
1517class RGWOptionsCORS : public RGWOp {
1518protected:
1519 RGWCORSRule *rule;
1520 const char *origin, *req_hdrs, *req_meth;
1521
1522public:
1523 RGWOptionsCORS() : rule(NULL), origin(NULL),
1524 req_hdrs(NULL), req_meth(NULL) {
1525 }
1526
1527 int verify_permission() override {return 0;}
1528 int validate_cors_request(RGWCORSConfiguration *cc);
1529 void execute() override;
1530 void get_response_params(string& allowed_hdrs, string& exp_hdrs, unsigned *max_age);
1531 void send_response() override = 0;
1532 const string name() override { return "options_cors"; }
1533 RGWOpType get_type() override { return RGW_OP_OPTIONS_CORS; }
1534 uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
1535};
1536
1537class RGWGetRequestPayment : public RGWOp {
1538protected:
1539 bool requester_pays;
1540
1541public:
1542 RGWGetRequestPayment() : requester_pays(0) {}
1543
1544 int verify_permission() override;
1545 void pre_exec() override;
1546 void execute() override;
1547
1548 void send_response() override = 0;
1549 const string name() override { return "get_request_payment"; }
1550 RGWOpType get_type() override { return RGW_OP_GET_REQUEST_PAYMENT; }
1551 uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
1552};
1553
1554class RGWSetRequestPayment : public RGWOp {
1555protected:
1556 bool requester_pays;
1557public:
1558 RGWSetRequestPayment() : requester_pays(false) {}
1559
1560 int verify_permission() override;
1561 void pre_exec() override;
1562 void execute() override;
1563
1564 virtual int get_params() { return 0; }
1565
1566 void send_response() override = 0;
1567 const string name() override { return "set_request_payment"; }
1568 RGWOpType get_type() override { return RGW_OP_SET_REQUEST_PAYMENT; }
1569 uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
1570};
1571
1572class RGWInitMultipart : public RGWOp {
1573protected:
1574 string upload_id;
1575 RGWAccessControlPolicy policy;
1576
1577public:
1578 RGWInitMultipart() {}
1579
1580 void init(RGWRados *store, struct req_state *s, RGWHandler *h) override {
1581 RGWOp::init(store, s, h);
1582 policy.set_ctx(s->cct);
1583 }
1584 int verify_permission() override;
1585 void pre_exec() override;
1586 void execute() override;
1587
1588 virtual int get_params() = 0;
1589 void send_response() override = 0;
1590 const string name() override { return "init_multipart"; }
1591 RGWOpType get_type() override { return RGW_OP_INIT_MULTIPART; }
1592 uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
1593 virtual int prepare_encryption(map<string, bufferlist>& attrs) { return 0; }
1594};
1595
1596class RGWCompleteMultipart : public RGWOp {
1597protected:
1598 string upload_id;
1599 string etag;
1600 char *data;
1601 int len;
1602
3efd9988
FG
1603 struct MPSerializer {
1604 librados::IoCtx ioctx;
1605 rados::cls::lock::Lock lock;
1606 librados::ObjectWriteOperation op;
1607 std::string oid;
1608 bool locked;
1609
1610 MPSerializer() : lock("RGWCompleteMultipart"), locked(false)
1611 {}
1612
1613 int try_lock(const std::string& oid, utime_t dur);
1614
1615 int unlock() {
1616 return lock.unlock(&ioctx, oid);
1617 }
1618
1619 void clear_locked() {
1620 locked = false;
1621 }
1622 } serializer;
1623
7c673cae
FG
1624public:
1625 RGWCompleteMultipart() {
1626 data = NULL;
1627 len = 0;
1628 }
1629 ~RGWCompleteMultipart() override {
1630 free(data);
1631 }
1632
1633 int verify_permission() override;
1634 void pre_exec() override;
1635 void execute() override;
3efd9988 1636 void complete() override;
7c673cae
FG
1637
1638 virtual int get_params() = 0;
1639 void send_response() override = 0;
1640 const string name() override { return "complete_multipart"; }
1641 RGWOpType get_type() override { return RGW_OP_COMPLETE_MULTIPART; }
1642 uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
1643};
1644
1645class RGWAbortMultipart : public RGWOp {
1646public:
1647 RGWAbortMultipart() {}
1648
1649 int verify_permission() override;
1650 void pre_exec() override;
1651 void execute() override;
1652
1653 void send_response() override = 0;
1654 const string name() override { return "abort_multipart"; }
1655 RGWOpType get_type() override { return RGW_OP_ABORT_MULTIPART; }
1656 uint32_t op_mask() override { return RGW_OP_TYPE_DELETE; }
1657};
1658
1659class RGWListMultipart : public RGWOp {
1660protected:
1661 string upload_id;
1662 map<uint32_t, RGWUploadPartInfo> parts;
1663 int max_parts;
1664 int marker;
1665 RGWAccessControlPolicy policy;
1666 bool truncated;
1667
1668public:
1669 RGWListMultipart() {
1670 max_parts = 1000;
1671 marker = 0;
1672 truncated = false;
1673 }
1674
1675 void init(RGWRados *store, struct req_state *s, RGWHandler *h) override {
1676 RGWOp::init(store, s, h);
1677 policy = RGWAccessControlPolicy(s->cct);
1678 }
1679 int verify_permission() override;
1680 void pre_exec() override;
1681 void execute() override;
1682
1683 virtual int get_params() = 0;
1684 void send_response() override = 0;
1685 const string name() override { return "list_multipart"; }
1686 RGWOpType get_type() override { return RGW_OP_LIST_MULTIPART; }
1687 uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
1688};
1689
1690struct RGWMultipartUploadEntry {
1691 rgw_bucket_dir_entry obj;
1692 RGWMPObj mp;
1693};
1694
1695class RGWListBucketMultiparts : public RGWOp {
1696protected:
1697 string prefix;
1698 RGWMPObj marker;
1699 RGWMultipartUploadEntry next_marker;
1700 int max_uploads;
1701 string delimiter;
1702 vector<RGWMultipartUploadEntry> uploads;
1703 map<string, bool> common_prefixes;
1704 bool is_truncated;
1705 int default_max;
1706
1707public:
1708 RGWListBucketMultiparts() {
1709 max_uploads = 0;
1710 is_truncated = false;
1711 default_max = 0;
1712 }
1713
1714 void init(RGWRados *store, struct req_state *s, RGWHandler *h) override {
1715 RGWOp::init(store, s, h);
1716 max_uploads = default_max;
1717 }
1718
1719 int verify_permission() override;
1720 void pre_exec() override;
1721 void execute() override;
1722
1723 virtual int get_params() = 0;
1724 void send_response() override = 0;
1725 const string name() override { return "list_bucket_multiparts"; }
1726 RGWOpType get_type() override { return RGW_OP_LIST_BUCKET_MULTIPARTS; }
1727 uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
1728};
1729
1730
1731class RGWGetCrossDomainPolicy : public RGWOp {
1732public:
1733 RGWGetCrossDomainPolicy() = default;
1734 ~RGWGetCrossDomainPolicy() override = default;
1735
1736 int verify_permission() override {
1737 return 0;
1738 }
1739
1740 void execute() override {
1741 op_ret = 0;
1742 }
1743
1744 const string name() override {
1745 return "get_crossdomain_policy";
1746 }
1747
1748 RGWOpType get_type() override {
1749 return RGW_OP_GET_CROSS_DOMAIN_POLICY;
1750 }
1751
1752 uint32_t op_mask() override {
1753 return RGW_OP_TYPE_READ;
1754 }
1755};
1756
1757
1758class RGWGetHealthCheck : public RGWOp {
1759public:
1760 RGWGetHealthCheck() = default;
1761 ~RGWGetHealthCheck() override = default;
1762
1763 int verify_permission() override {
1764 return 0;
1765 }
1766
1767 void execute() override;
1768
1769 const string name() override {
1770 return "get_health_check";
1771 }
1772
1773 RGWOpType get_type() override {
1774 return RGW_OP_GET_HEALTH_CHECK;
1775 }
1776
1777 uint32_t op_mask() override {
1778 return RGW_OP_TYPE_READ;
1779 }
1780};
1781
1782
1783class RGWDeleteMultiObj : public RGWOp {
1784protected:
1785 int max_to_delete;
1786 int len;
1787 char *data;
1788 rgw_bucket bucket;
1789 bool quiet;
1790 bool status_dumped;
31f18b77 1791 bool acl_allowed = false;
7c673cae
FG
1792
1793public:
1794 RGWDeleteMultiObj() {
1795 max_to_delete = 1000;
1796 len = 0;
1797 data = NULL;
1798 quiet = false;
1799 status_dumped = false;
1800 }
1801 int verify_permission() override;
1802 void pre_exec() override;
1803 void execute() override;
1804
1805 virtual int get_params() = 0;
1806 virtual void send_status() = 0;
1807 virtual void begin_response() = 0;
1808 virtual void send_partial_response(rgw_obj_key& key, bool delete_marker,
1809 const string& marker_version_id, int ret) = 0;
1810 virtual void end_response() = 0;
1811 const string name() override { return "multi_object_delete"; }
1812 RGWOpType get_type() override { return RGW_OP_DELETE_MULTI_OBJ; }
1813 uint32_t op_mask() override { return RGW_OP_TYPE_DELETE; }
1814};
1815
1816class RGWInfo: public RGWOp {
1817public:
1818 RGWInfo() = default;
1819 ~RGWInfo() override = default;
1820
1821 int verify_permission() override { return 0; }
1822 const string name() override { return "get info"; }
1823 RGWOpType get_type() override { return RGW_OP_GET_INFO; }
1824 uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
1825};
1826
1827extern int rgw_build_bucket_policies(RGWRados* store, struct req_state* s);
1828extern int rgw_build_object_policies(RGWRados *store, struct req_state *s,
31f18b77
FG
1829 bool prefetch_data);
1830extern rgw::IAM::Environment rgw_build_iam_environment(RGWRados* store,
1831 struct req_state* s);
7c673cae
FG
1832
1833static inline int put_data_and_throttle(RGWPutObjDataProcessor *processor,
1834 bufferlist& data, off_t ofs,
1835 bool need_to_wait)
1836{
1837 bool again = false;
1838 do {
1839 void *handle = nullptr;
1840 rgw_raw_obj obj;
1841
1842 uint64_t size = data.length();
1843
1844 int ret = processor->handle_data(data, ofs, &handle, &obj, &again);
1845 if (ret < 0)
1846 return ret;
1847 if (handle != nullptr)
1848 {
1849 ret = processor->throttle_data(handle, obj, size, need_to_wait);
1850 if (ret < 0)
1851 return ret;
1852 }
1853 else
1854 break;
1855 need_to_wait = false; /* the need to wait only applies to the first
1856 * iteration */
1857 } while (again);
1858
1859 return 0;
1860} /* put_data_and_throttle */
1861
1862
1863
1864
1865
1866static inline int get_system_versioning_params(req_state *s,
1867 uint64_t *olh_epoch,
1868 string *version_id)
1869{
1870 if (!s->system_request) {
1871 return 0;
1872 }
1873
1874 if (olh_epoch) {
1875 string epoch_str = s->info.args.get(RGW_SYS_PARAM_PREFIX "versioned-epoch");
1876 if (!epoch_str.empty()) {
1877 string err;
1878 *olh_epoch = strict_strtol(epoch_str.c_str(), 10, &err);
1879 if (!err.empty()) {
1880 lsubdout(s->cct, rgw, 0) << "failed to parse versioned-epoch param"
1881 << dendl;
1882 return -EINVAL;
1883 }
1884 }
1885 }
1886
1887 if (version_id) {
1888 *version_id = s->info.args.get(RGW_SYS_PARAM_PREFIX "version-id");
1889 }
1890
1891 return 0;
1892} /* get_system_versioning_params */
1893
1894static inline void format_xattr(std::string &xattr)
1895{
1896 /* If the extended attribute is not valid UTF-8, we encode it using
1897 * quoted-printable encoding.
1898 */
1899 if ((check_utf8(xattr.c_str(), xattr.length()) != 0) ||
1900 (check_for_control_characters(xattr.c_str(), xattr.length()) != 0)) {
1901 static const char MIME_PREFIX_STR[] = "=?UTF-8?Q?";
1902 static const int MIME_PREFIX_LEN = sizeof(MIME_PREFIX_STR) - 1;
1903 static const char MIME_SUFFIX_STR[] = "?=";
1904 static const int MIME_SUFFIX_LEN = sizeof(MIME_SUFFIX_STR) - 1;
1905 int mlen = mime_encode_as_qp(xattr.c_str(), NULL, 0);
1906 char *mime = new char[MIME_PREFIX_LEN + mlen + MIME_SUFFIX_LEN + 1];
1907 strcpy(mime, MIME_PREFIX_STR);
1908 mime_encode_as_qp(xattr.c_str(), mime + MIME_PREFIX_LEN, mlen);
1909 strcpy(mime + MIME_PREFIX_LEN + (mlen - 1), MIME_SUFFIX_STR);
1910 xattr.assign(mime);
1911 delete [] mime;
1912 }
1913} /* format_xattr */
1914
1915/**
1916 * Get the HTTP request metadata out of the req_state as a
1917 * map(<attr_name, attr_contents>, where attr_name is RGW_ATTR_PREFIX.HTTP_NAME)
1918 * s: The request state
1919 * attrs: will be filled up with attrs mapped as <attr_name, attr_contents>
3efd9988
FG
1920 * On success returns 0.
1921 * On failure returns a negative error code.
7c673cae
FG
1922 *
1923 */
3efd9988
FG
1924static inline int rgw_get_request_metadata(CephContext* const cct,
1925 struct req_info& info,
1926 std::map<std::string, ceph::bufferlist>& attrs,
1927 const bool allow_empty_attrs = true)
7c673cae
FG
1928{
1929 static const std::set<std::string> blacklisted_headers = {
1930 "x-amz-server-side-encryption-customer-algorithm",
1931 "x-amz-server-side-encryption-customer-key",
1932 "x-amz-server-side-encryption-customer-key-md5"
1933 };
3efd9988
FG
1934
1935 size_t valid_meta_count = 0;
1936 for (auto& kv : info.x_meta_map) {
1937 const std::string& name = kv.first;
1938 std::string& xattr = kv.second;
1939
7c673cae
FG
1940 if (blacklisted_headers.count(name) == 1) {
1941 lsubdout(cct, rgw, 10) << "skipping x>> " << name << dendl;
1942 continue;
3efd9988 1943 } else if (allow_empty_attrs || !xattr.empty()) {
7c673cae
FG
1944 lsubdout(cct, rgw, 10) << "x>> " << name << ":" << xattr << dendl;
1945 format_xattr(xattr);
3efd9988
FG
1946
1947 std::string attr_name(RGW_ATTR_PREFIX);
7c673cae 1948 attr_name.append(name);
3efd9988
FG
1949
1950 /* Check roughly whether we aren't going behind the limit on attribute
1951 * name. Passing here doesn't guarantee that an OSD will accept that
1952 * as ObjectStore::get_max_attr_name_length() can set the limit even
1953 * lower than the "osd_max_attr_name_len" configurable. */
1954 const size_t max_attr_name_len = \
1955 cct->_conf->get_val<size_t>("rgw_max_attr_name_len");
1956 if (max_attr_name_len && attr_name.length() > max_attr_name_len) {
1957 return -ENAMETOOLONG;
1958 }
1959
1960 /* Similar remarks apply to the check for value size. We're veryfing
1961 * it early at the RGW's side as it's being claimed in /info. */
1962 const size_t max_attr_size = \
1963 cct->_conf->get_val<size_t>("rgw_max_attr_size");
1964 if (max_attr_size && xattr.length() > max_attr_size) {
1965 return -EFBIG;
1966 }
1967
1968 /* Swift allows administrators to limit the number of metadats items
1969 * send _in a single request_. */
1970 const auto rgw_max_attrs_num_in_req = \
1971 cct->_conf->get_val<size_t>("rgw_max_attrs_num_in_req");
1972 if (rgw_max_attrs_num_in_req &&
1973 ++valid_meta_count > rgw_max_attrs_num_in_req) {
1974 return -E2BIG;
1975 }
1976
1977 auto rval = attrs.emplace(std::move(attr_name), ceph::bufferlist());
1978 /* At the moment the value of the freshly created attribute key-value
1979 * pair is an empty bufferlist. */
1980
1981 ceph::bufferlist& bl = rval.first->second;
7c673cae
FG
1982 bl.append(xattr.c_str(), xattr.size() + 1);
1983 }
1984 }
3efd9988
FG
1985
1986 return 0;
7c673cae
FG
1987} /* rgw_get_request_metadata */
1988
1989static inline void encode_delete_at_attr(boost::optional<ceph::real_time> delete_at,
1990 map<string, bufferlist>& attrs)
1991{
1992 if (delete_at == boost::none) {
1993 return;
1994 }
1995
1996 bufferlist delatbl;
1997 ::encode(*delete_at, delatbl);
1998 attrs[RGW_ATTR_DELETE_AT] = delatbl;
1999} /* encode_delete_at_attr */
2000
224ce89b
WB
2001static inline void encode_obj_tags_attr(RGWObjTags* obj_tags, map<string, bufferlist>& attrs)
2002{
2003 if (obj_tags == nullptr){
2004 // we assume the user submitted a tag format which we couldn't parse since
2005 // this wouldn't be parsed later by get/put obj tags, lets delete if the
2006 // attr was populated
2007 return;
2008 }
2009
2010 bufferlist tagsbl;
2011 obj_tags->encode(tagsbl);
2012 attrs[RGW_ATTR_TAGS] = tagsbl;
2013}
2014
7c673cae
FG
2015static inline int encode_dlo_manifest_attr(const char * const dlo_manifest,
2016 map<string, bufferlist>& attrs)
2017{
2018 string dm = dlo_manifest;
2019
2020 if (dm.find('/') == string::npos) {
2021 return -EINVAL;
2022 }
2023
2024 bufferlist manifest_bl;
2025 manifest_bl.append(dlo_manifest, strlen(dlo_manifest) + 1);
2026 attrs[RGW_ATTR_USER_MANIFEST] = manifest_bl;
2027
2028 return 0;
2029} /* encode_dlo_manifest_attr */
2030
2031static inline void complete_etag(MD5& hash, string *etag)
2032{
2033 char etag_buf[CEPH_CRYPTO_MD5_DIGESTSIZE];
2034 char etag_buf_str[CEPH_CRYPTO_MD5_DIGESTSIZE * 2 + 16];
2035
2036 hash.Final((byte *)etag_buf);
2037 buf_to_hex((const unsigned char *)etag_buf, CEPH_CRYPTO_MD5_DIGESTSIZE,
2038 etag_buf_str);
2039
2040 *etag = etag_buf_str;
2041} /* complete_etag */
2042
2043class RGWSetAttrs : public RGWOp {
2044protected:
2045 map<string, buffer::list> attrs;
2046
2047public:
2048 RGWSetAttrs() {}
2049 ~RGWSetAttrs() override {}
2050
2051 void emplace_attr(std::string&& key, buffer::list&& bl) {
2052 attrs.emplace(std::move(key), std::move(bl));
2053 }
2054
2055 int verify_permission() override;
2056 void pre_exec() override;
2057 void execute() override;
2058
2059 virtual int get_params() = 0;
2060 void send_response() override = 0;
2061 const string name() override { return "set_attrs"; }
2062 RGWOpType get_type() override { return RGW_OP_SET_ATTRS; }
2063 uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
2064};
2065
2066class RGWGetObjLayout : public RGWOp {
2067protected:
2068 RGWObjManifest *manifest{nullptr};
2069 rgw_raw_obj head_obj;
2070
2071public:
2072 RGWGetObjLayout() {
2073 }
2074
2075 int check_caps(RGWUserCaps& caps) {
2076 return caps.check_cap("admin", RGW_CAP_READ);
2077 }
2078 int verify_permission() {
2079 return check_caps(s->user->caps);
2080 }
2081 void pre_exec();
2082 void execute();
2083
2084 virtual void send_response() = 0;
2085 virtual const string name() { return "get_obj_layout"; }
2086 virtual RGWOpType get_type() { return RGW_OP_GET_OBJ_LAYOUT; }
2087 virtual uint32_t op_mask() { return RGW_OP_TYPE_READ; }
2088};
2089
31f18b77
FG
2090class RGWPutBucketPolicy : public RGWOp {
2091 int len;
2092 char *data = nullptr;
2093public:
2094 RGWPutBucketPolicy() = default;
2095 ~RGWPutBucketPolicy() {
2096 if (data) {
2097 free(static_cast<void*>(data));
2098 }
2099 }
2100 void send_response() override;
2101 int verify_permission() override;
2102 uint32_t op_mask() override {
2103 return RGW_OP_TYPE_WRITE;
2104 }
2105 void execute() override;
2106 int get_params();
2107 const std::string name() override {
2108 return "put_bucket_policy";
2109 }
2110 RGWOpType get_type() override {
2111 return RGW_OP_PUT_BUCKET_POLICY;
2112 }
2113};
7c673cae 2114
31f18b77
FG
2115class RGWGetBucketPolicy : public RGWOp {
2116 buffer::list policy;
2117public:
2118 RGWGetBucketPolicy() = default;
2119 void send_response() override;
2120 int verify_permission() override;
2121 uint32_t op_mask() override {
2122 return RGW_OP_TYPE_READ;
2123 }
2124 void execute() override;
2125 const std::string name() override {
2126 return "get_bucket_policy";
2127 }
2128 RGWOpType get_type() override {
2129 return RGW_OP_GET_BUCKET_POLICY;
2130 }
2131};
2132
2133class RGWDeleteBucketPolicy : public RGWOp {
2134public:
2135 RGWDeleteBucketPolicy() = default;
2136 void send_response() override;
2137 int verify_permission() override;
2138 uint32_t op_mask() override {
2139 return RGW_OP_TYPE_WRITE;
2140 }
2141 void execute() override;
2142 int get_params();
2143 const std::string name() override {
2144 return "delete_bucket_policy";
2145 }
2146 RGWOpType get_type() override {
2147 return RGW_OP_DELETE_BUCKET_POLICY;
2148 }
2149};
2150
2151
2152class RGWConfigBucketMetaSearch : public RGWOp {
2153protected:
2154 std::map<std::string, uint32_t> mdsearch_config;
2155public:
2156 RGWConfigBucketMetaSearch() {}
2157
2158 int verify_permission();
2159 void pre_exec();
2160 void execute();
2161
2162 virtual int get_params() = 0;
2163 virtual void send_response() = 0;
2164 virtual const string name() { return "config_bucket_meta_search"; }
2165 virtual RGWOpType get_type() { return RGW_OP_CONFIG_BUCKET_META_SEARCH; }
2166 virtual uint32_t op_mask() { return RGW_OP_TYPE_WRITE; }
2167};
2168
2169class RGWGetBucketMetaSearch : public RGWOp {
2170public:
2171 RGWGetBucketMetaSearch() {}
2172
2173 int verify_permission();
2174 void pre_exec();
2175 void execute() {}
2176
2177 virtual void send_response() = 0;
2178 virtual const string name() { return "get_bucket_meta_search"; }
2179 virtual RGWOpType get_type() { return RGW_OP_GET_BUCKET_META_SEARCH; }
2180 virtual uint32_t op_mask() { return RGW_OP_TYPE_READ; }
2181};
2182
2183class RGWDelBucketMetaSearch : public RGWOp {
2184public:
2185 RGWDelBucketMetaSearch() {}
2186
2187 int verify_permission();
2188 void pre_exec();
2189 void execute();
2190
2191 virtual void send_response() = 0;
2192 virtual const string name() { return "delete_bucket_meta_search"; }
2193 virtual RGWOpType delete_type() { return RGW_OP_DEL_BUCKET_META_SEARCH; }
2194 virtual uint32_t op_mask() { return RGW_OP_TYPE_WRITE; }
2195};
7c673cae
FG
2196
2197#endif /* CEPH_RGW_OP_H */