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