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