]> git.proxmox.com Git - ceph.git/blob - ceph/src/rgw/rgw_op.h
ed91951aba9dd33e6f61482c5264ad2d625012d0
[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 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 */
211 string version_id;
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;
220 uint64_t action = 0;
221
222 int init_common();
223 public:
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;
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);
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
288 class RGWGetObj_CB : public RGWGetDataCB
289 {
290 RGWGetObj *op;
291 public:
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
300 class RGWGetObj_Filter : public RGWGetDataCB
301 {
302 protected:
303 RGWGetDataCB* next;
304 public:
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
330 class 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
346 class 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
361 class 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
373 class RGWBulkDelete : public RGWOp {
374 public:
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
424 protected:
425 std::unique_ptr<Deleter> deleter;
426
427 public:
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
445 inline ostream& operator<<(ostream& out, const RGWBulkDelete::acct_path_t &o) {
446 return out << o.bucket_name << "/" << o.obj_key;
447 }
448
449
450 class RGWBulkUploadOp : public RGWOp {
451 boost::optional<RGWObjectCtx> dir_ctx;
452
453 protected:
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,
487 const rgw_obj& obj,
488 std::map<std::string, ceph::bufferlist>& battrs,
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
497 public:
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
527 class RGWBulkUploadOp::StreamGetter {
528 public:
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
537 class RGWBulkUploadOp::DecoratedStreamGetter : public StreamGetter {
538 StreamGetter& decoratee;
539
540 protected:
541 StreamGetter& get_decoratee() {
542 return decoratee;
543 }
544
545 public:
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
561 class RGWBulkUploadOp::AlignedStreamGetter
562 : public RGWBulkUploadOp::DecoratedStreamGetter {
563 size_t position;
564 size_t length;
565 size_t alignment;
566
567 public:
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
586 class RGWListBuckets : public RGWOp {
587 protected:
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
604 public:
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
631 class RGWGetUsage : public RGWOp {
632 protected:
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 map<string, cls_user_bucket_entry> buckets_usage;
642 cls_user_header header;
643 public:
644 RGWGetUsage() : sent_data(false), show_log_entries(true), show_log_sum(true){
645 }
646
647 int verify_permission() override;
648 void execute() override;
649
650 virtual int get_params() = 0;
651 void send_response() override {}
652
653 virtual bool should_get_stats() { return false; }
654
655 const string name() override { return "get_usage"; }
656 uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
657 };
658
659 class RGWStatAccount : public RGWOp {
660 protected:
661 uint32_t buckets_count;
662 uint64_t buckets_objcount;
663 uint64_t buckets_size;
664 uint64_t buckets_size_rounded;
665
666 public:
667 RGWStatAccount() {
668 buckets_count = 0;
669 buckets_objcount = 0;
670 buckets_size = 0;
671 buckets_size_rounded = 0;
672 }
673
674 int verify_permission() override;
675 void execute() override;
676
677 void send_response() override = 0;
678 const string name() override { return "stat_account"; }
679 RGWOpType get_type() override { return RGW_OP_STAT_ACCOUNT; }
680 uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
681 };
682
683 class RGWListBucket : public RGWOp {
684 protected:
685 RGWBucketEnt bucket;
686 string prefix;
687 rgw_obj_key marker;
688 rgw_obj_key next_marker;
689 rgw_obj_key end_marker;
690 string max_keys;
691 string delimiter;
692 string encoding_type;
693 bool list_versions;
694 int max;
695 vector<rgw_bucket_dir_entry> objs;
696 map<string, bool> common_prefixes;
697
698 int default_max;
699 bool is_truncated;
700
701 int shard_id;
702
703 int parse_max_keys();
704
705 public:
706 RGWListBucket() : list_versions(false), max(0),
707 default_max(0), is_truncated(false), shard_id(-1) {}
708 int verify_permission() override;
709 void pre_exec() override;
710 void execute() override;
711
712 virtual int get_params() = 0;
713 void send_response() override = 0;
714 const string name() override { return "list_bucket"; }
715 RGWOpType get_type() override { return RGW_OP_LIST_BUCKET; }
716 uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
717 virtual bool need_container_stats() { return false; }
718 };
719
720 class RGWGetBucketLogging : public RGWOp {
721 public:
722 RGWGetBucketLogging() {}
723 int verify_permission() override;
724 void execute() override { }
725
726 void send_response() override = 0;
727 const string name() override { return "get_bucket_logging"; }
728 RGWOpType get_type() override { return RGW_OP_GET_BUCKET_LOGGING; }
729 uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
730 };
731
732 class RGWGetBucketLocation : public RGWOp {
733 public:
734 RGWGetBucketLocation() {}
735 ~RGWGetBucketLocation() override {}
736 int verify_permission() override;
737 void execute() override { }
738
739 void send_response() override = 0;
740 const string name() override { return "get_bucket_location"; }
741 uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
742 };
743
744 class RGWGetBucketVersioning : public RGWOp {
745 protected:
746 bool versioned;
747 bool versioning_enabled;
748 public:
749 RGWGetBucketVersioning() : versioned(false), versioning_enabled(false) {}
750
751 int verify_permission() override;
752 void pre_exec() override;
753 void execute() override;
754
755 void send_response() override = 0;
756 const string name() override { return "get_bucket_versioning"; }
757 RGWOpType get_type() override { return RGW_OP_GET_BUCKET_VERSIONING; }
758 uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
759 };
760
761 class RGWSetBucketVersioning : public RGWOp {
762 protected:
763 bool enable_versioning;
764 bufferlist in_data;
765 public:
766 RGWSetBucketVersioning() : enable_versioning(false) {}
767
768 int verify_permission() override;
769 void pre_exec() override;
770 void execute() override;
771
772 virtual int get_params() { return 0; }
773
774 void send_response() override = 0;
775 const string name() override { return "set_bucket_versioning"; }
776 RGWOpType get_type() override { return RGW_OP_SET_BUCKET_VERSIONING; }
777 uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
778 };
779
780 class RGWGetBucketWebsite : public RGWOp {
781 public:
782 RGWGetBucketWebsite() {}
783
784 int verify_permission() override;
785 void pre_exec() override;
786 void execute() override;
787
788 void send_response() override = 0;
789 const string name() override { return "get_bucket_website"; }
790 RGWOpType get_type() override { return RGW_OP_GET_BUCKET_WEBSITE; }
791 uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
792 };
793
794 class RGWSetBucketWebsite : public RGWOp {
795 protected:
796 bufferlist in_data;
797 RGWBucketWebsiteConf website_conf;
798 public:
799 RGWSetBucketWebsite() {}
800
801 int verify_permission() override;
802 void pre_exec() override;
803 void execute() override;
804
805 virtual int get_params() { return 0; }
806
807 void send_response() override = 0;
808 const string name() override { return "set_bucket_website"; }
809 RGWOpType get_type() override { return RGW_OP_SET_BUCKET_WEBSITE; }
810 uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
811 };
812
813 class RGWDeleteBucketWebsite : public RGWOp {
814 public:
815 RGWDeleteBucketWebsite() {}
816
817 int verify_permission() override;
818 void pre_exec() override;
819 void execute() override;
820
821 void send_response() override = 0;
822 const string name() override { return "delete_bucket_website"; }
823 RGWOpType get_type() override { return RGW_OP_SET_BUCKET_WEBSITE; }
824 uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
825 };
826
827 class RGWStatBucket : public RGWOp {
828 protected:
829 RGWBucketEnt bucket;
830
831 public:
832 RGWStatBucket() {}
833 ~RGWStatBucket() override {}
834
835 int verify_permission() override;
836 void pre_exec() override;
837 void execute() override;
838
839 void send_response() override = 0;
840 const string name() override { return "stat_bucket"; }
841 RGWOpType get_type() override { return RGW_OP_STAT_BUCKET; }
842 uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
843 };
844
845 class RGWCreateBucket : public RGWOp {
846 protected:
847 RGWAccessControlPolicy policy;
848 string location_constraint;
849 string placement_rule;
850 RGWBucketInfo info;
851 obj_version ep_objv;
852 bool has_cors;
853 RGWCORSConfiguration cors_config;
854 boost::optional<std::string> swift_ver_location;
855 map<string, buffer::list> attrs;
856 set<string> rmattr_names;
857
858 bufferlist in_data;
859
860 virtual bool need_metadata_upload() const { return false; }
861
862 public:
863 RGWCreateBucket() : has_cors(false) {}
864
865 void emplace_attr(std::string&& key, buffer::list&& bl) {
866 attrs.emplace(std::move(key), std::move(bl)); /* key and bl are r-value refs */
867 }
868
869 int verify_permission() override;
870 void pre_exec() override;
871 void execute() override;
872 void init(RGWRados *store, struct req_state *s, RGWHandler *h) override {
873 RGWOp::init(store, s, h);
874 policy.set_ctx(s->cct);
875 }
876 virtual int get_params() { return 0; }
877 void send_response() override = 0;
878 const string name() override { return "create_bucket"; }
879 RGWOpType get_type() override { return RGW_OP_CREATE_BUCKET; }
880 uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
881 };
882
883 class RGWDeleteBucket : public RGWOp {
884 protected:
885 RGWObjVersionTracker objv_tracker;
886
887 public:
888 RGWDeleteBucket() {}
889
890 int verify_permission() override;
891 void pre_exec() override;
892 void execute() override;
893
894 void send_response() override = 0;
895 const string name() override { return "delete_bucket"; }
896 RGWOpType get_type() override { return RGW_OP_DELETE_BUCKET; }
897 uint32_t op_mask() override { return RGW_OP_TYPE_DELETE; }
898 };
899
900 struct rgw_slo_entry {
901 string path;
902 string etag;
903 uint64_t size_bytes;
904
905 rgw_slo_entry() : size_bytes(0) {}
906
907 void encode(bufferlist& bl) const {
908 ENCODE_START(1, 1, bl);
909 ::encode(path, bl);
910 ::encode(etag, bl);
911 ::encode(size_bytes, bl);
912 ENCODE_FINISH(bl);
913 }
914
915 void decode(bufferlist::iterator& bl) {
916 DECODE_START(1, bl);
917 ::decode(path, bl);
918 ::decode(etag, bl);
919 ::decode(size_bytes, bl);
920 DECODE_FINISH(bl);
921 }
922
923 void decode_json(JSONObj *obj);
924 };
925 WRITE_CLASS_ENCODER(rgw_slo_entry)
926
927 struct RGWSLOInfo {
928 vector<rgw_slo_entry> entries;
929 uint64_t total_size;
930
931 /* in memory only */
932 char *raw_data;
933 int raw_data_len;
934
935 RGWSLOInfo() : total_size(0), raw_data(NULL), raw_data_len(0) {}
936 ~RGWSLOInfo() {
937 free(raw_data);
938 }
939
940 void encode(bufferlist& bl) const {
941 ENCODE_START(1, 1, bl);
942 ::encode(entries, bl);
943 ::encode(total_size, bl);
944 ENCODE_FINISH(bl);
945 }
946
947 void decode(bufferlist::iterator& bl) {
948 DECODE_START(1, bl);
949 ::decode(entries, bl);
950 ::decode(total_size, bl);
951 DECODE_FINISH(bl);
952 }
953 };
954 WRITE_CLASS_ENCODER(RGWSLOInfo)
955
956 class RGWPutObj : public RGWOp {
957
958 friend class RGWPutObjProcessor;
959
960 protected:
961 seed torrent;
962 off_t ofs;
963 const char *supplied_md5_b64;
964 const char *supplied_etag;
965 const char *if_match;
966 const char *if_nomatch;
967 const char *copy_source;
968 const char *copy_source_range;
969 RGWBucketInfo copy_source_bucket_info;
970 string copy_source_tenant_name;
971 string copy_source_bucket_name;
972 string copy_source_object_name;
973 string copy_source_version_id;
974 off_t copy_source_range_fst;
975 off_t copy_source_range_lst;
976 string etag;
977 bool chunked_upload;
978 RGWAccessControlPolicy policy;
979 std::unique_ptr <RGWObjTags> obj_tags;
980 const char *dlo_manifest;
981 RGWSLOInfo *slo_info;
982 map<string, bufferlist> attrs;
983 ceph::real_time mtime;
984 uint64_t olh_epoch;
985 string version_id;
986 bufferlist bl_aux;
987 map<string, string> crypt_http_responses;
988 string user_data;
989
990 boost::optional<ceph::real_time> delete_at;
991
992 public:
993 RGWPutObj() : ofs(0),
994 supplied_md5_b64(NULL),
995 supplied_etag(NULL),
996 if_match(NULL),
997 if_nomatch(NULL),
998 copy_source(NULL),
999 copy_source_range(NULL),
1000 copy_source_range_fst(0),
1001 copy_source_range_lst(0),
1002 chunked_upload(0),
1003 dlo_manifest(NULL),
1004 slo_info(NULL),
1005 olh_epoch(0) {}
1006
1007 ~RGWPutObj() override {
1008 delete slo_info;
1009 }
1010
1011 void init(RGWRados *store, struct req_state *s, RGWHandler *h) override {
1012 RGWOp::init(store, s, h);
1013 policy.set_ctx(s->cct);
1014 }
1015
1016 void emplace_attr(std::string&& key, buffer::list&& bl) {
1017 attrs.emplace(std::move(key), std::move(bl)); /* key and bl are r-value refs */
1018 }
1019
1020 virtual RGWPutObjProcessor *select_processor(RGWObjectCtx& obj_ctx, bool *is_multipart);
1021 void dispose_processor(RGWPutObjDataProcessor *processor);
1022
1023 int verify_permission() override;
1024 void pre_exec() override;
1025 void execute() override;
1026
1027 /* this is for cases when copying data from other object */
1028 virtual int get_decrypt_filter(std::unique_ptr<RGWGetDataCB>* filter,
1029 RGWGetDataCB* cb,
1030 map<string, bufferlist>& attrs,
1031 bufferlist* manifest_bl) {
1032 *filter = nullptr;
1033 return 0;
1034 }
1035 virtual int get_encrypt_filter(std::unique_ptr<RGWPutObjDataProcessor> *filter, RGWPutObjDataProcessor* cb) {
1036 *filter = nullptr;
1037 return 0;
1038 }
1039
1040 int get_data_cb(bufferlist& bl, off_t bl_ofs, off_t bl_len);
1041 int get_data(const off_t fst, const off_t lst, bufferlist& bl);
1042
1043 virtual int get_params() = 0;
1044 virtual int get_data(bufferlist& bl) = 0;
1045 void send_response() override = 0;
1046 const string name() override { return "put_obj"; }
1047 RGWOpType get_type() override { return RGW_OP_PUT_OBJ; }
1048 uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
1049 };
1050
1051 class RGWPutObj_Filter : public RGWPutObjDataProcessor
1052 {
1053 protected:
1054 RGWPutObjDataProcessor* next;
1055 public:
1056 RGWPutObj_Filter(RGWPutObjDataProcessor* next) :
1057 next(next){}
1058 ~RGWPutObj_Filter() override {}
1059 int handle_data(bufferlist& bl, off_t ofs, void **phandle, rgw_raw_obj *pobj, bool *again) override {
1060 return next->handle_data(bl, ofs, phandle, pobj, again);
1061 }
1062 int throttle_data(void *handle, const rgw_raw_obj& obj, uint64_t size, bool need_to_wait) override {
1063 return next->throttle_data(handle, obj, size, need_to_wait);
1064 }
1065 }; /* RGWPutObj_Filter */
1066
1067 class RGWPostObj : public RGWOp {
1068 protected:
1069 off_t min_len;
1070 off_t max_len;
1071 int len;
1072 off_t ofs;
1073 const char *supplied_md5_b64;
1074 const char *supplied_etag;
1075 string etag;
1076 RGWAccessControlPolicy policy;
1077 map<string, bufferlist> attrs;
1078 boost::optional<ceph::real_time> delete_at;
1079
1080 /* Must be called after get_data() or the result is undefined. */
1081 virtual std::string get_current_filename() const = 0;
1082 virtual std::string get_current_content_type() const = 0;
1083 virtual bool is_next_file_to_upload() {
1084 return false;
1085 }
1086 public:
1087 RGWPostObj() : min_len(0),
1088 max_len(LLONG_MAX),
1089 len(0),
1090 ofs(0),
1091 supplied_md5_b64(nullptr),
1092 supplied_etag(nullptr) {
1093 }
1094
1095 void emplace_attr(std::string&& key, buffer::list&& bl) {
1096 attrs.emplace(std::move(key), std::move(bl)); /* key and bl are r-value refs */
1097 }
1098
1099 void init(RGWRados *store, struct req_state *s, RGWHandler *h) override {
1100 RGWOp::init(store, s, h);
1101 policy.set_ctx(s->cct);
1102 }
1103
1104 int verify_permission() override;
1105 void pre_exec() override;
1106 void execute() override;
1107
1108 virtual int get_encrypt_filter(std::unique_ptr<RGWPutObjDataProcessor> *filter, RGWPutObjDataProcessor* cb) {
1109 *filter = nullptr;
1110 return 0;
1111 }
1112 virtual int get_params() = 0;
1113 virtual int get_data(ceph::bufferlist& bl, bool& again) = 0;
1114 void send_response() override = 0;
1115 const std::string name() override { return "post_obj"; }
1116 RGWOpType get_type() override { return RGW_OP_POST_OBJ; }
1117 uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
1118 };
1119
1120 class RGWPutMetadataAccount : public RGWOp {
1121 protected:
1122 std::set<std::string> rmattr_names;
1123 std::map<std::string, bufferlist> attrs, orig_attrs;
1124 std::map<int, std::string> temp_url_keys;
1125 RGWQuotaInfo new_quota;
1126 bool new_quota_extracted;
1127
1128 RGWObjVersionTracker acct_op_tracker;
1129
1130 RGWAccessControlPolicy policy;
1131 bool has_policy;
1132
1133 public:
1134 RGWPutMetadataAccount()
1135 : new_quota_extracted(false),
1136 has_policy(false) {
1137 }
1138
1139 void init(RGWRados *store, struct req_state *s, RGWHandler *h) override {
1140 RGWOp::init(store, s, h);
1141 policy.set_ctx(s->cct);
1142 }
1143 int init_processing() override;
1144 int verify_permission() override;
1145 void pre_exec() override { }
1146 void execute() override;
1147
1148 virtual int get_params() = 0;
1149 void send_response() override = 0;
1150 virtual void filter_out_temp_url(map<string, bufferlist>& add_attrs,
1151 const set<string>& rmattr_names,
1152 map<int, string>& temp_url_keys);
1153 const string name() override { return "put_account_metadata"; }
1154 RGWOpType get_type() override { return RGW_OP_PUT_METADATA_ACCOUNT; }
1155 uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
1156 };
1157
1158 class RGWPutMetadataBucket : public RGWOp {
1159 protected:
1160 map<string, buffer::list> attrs;
1161 set<string> rmattr_names;
1162 bool has_policy, has_cors;
1163 uint32_t policy_rw_mask;
1164 RGWAccessControlPolicy policy;
1165 RGWCORSConfiguration cors_config;
1166 string placement_rule;
1167 boost::optional<std::string> swift_ver_location;
1168
1169 public:
1170 RGWPutMetadataBucket()
1171 : has_policy(false), has_cors(false), policy_rw_mask(0)
1172 {}
1173
1174 void emplace_attr(std::string&& key, buffer::list&& bl) {
1175 attrs.emplace(std::move(key), std::move(bl)); /* key and bl are r-value refs */
1176 }
1177
1178 void init(RGWRados *store, struct req_state *s, RGWHandler *h) override {
1179 RGWOp::init(store, s, h);
1180 policy.set_ctx(s->cct);
1181 }
1182
1183 int verify_permission() override;
1184 void pre_exec() override;
1185 void execute() override;
1186
1187 virtual int get_params() = 0;
1188 void send_response() override = 0;
1189 const string name() override { return "put_bucket_metadata"; }
1190 RGWOpType get_type() override { return RGW_OP_PUT_METADATA_BUCKET; }
1191 uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
1192 };
1193
1194 class RGWPutMetadataObject : public RGWOp {
1195 protected:
1196 RGWAccessControlPolicy policy;
1197 string placement_rule;
1198 boost::optional<ceph::real_time> delete_at;
1199 const char *dlo_manifest;
1200
1201 public:
1202 RGWPutMetadataObject()
1203 : dlo_manifest(NULL)
1204 {}
1205
1206 void init(RGWRados *store, struct req_state *s, RGWHandler *h) override {
1207 RGWOp::init(store, s, h);
1208 policy.set_ctx(s->cct);
1209 }
1210 int verify_permission() override;
1211 void pre_exec() override;
1212 void execute() override;
1213
1214 virtual int get_params() = 0;
1215 void send_response() override = 0;
1216 const string name() override { return "put_obj_metadata"; }
1217 RGWOpType get_type() override { return RGW_OP_PUT_METADATA_OBJECT; }
1218 uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
1219 virtual bool need_object_expiration() { return false; }
1220 };
1221
1222 class RGWDeleteObj : public RGWOp {
1223 protected:
1224 bool delete_marker;
1225 bool multipart_delete;
1226 string version_id;
1227 ceph::real_time unmod_since; /* if unmodified since */
1228 bool no_precondition_error;
1229 std::unique_ptr<RGWBulkDelete::Deleter> deleter;
1230
1231 public:
1232 RGWDeleteObj()
1233 : delete_marker(false),
1234 multipart_delete(false),
1235 no_precondition_error(false),
1236 deleter(nullptr) {
1237 }
1238
1239 int verify_permission() override;
1240 void pre_exec() override;
1241 void execute() override;
1242 int handle_slo_manifest(bufferlist& bl);
1243
1244 virtual int get_params() { return 0; }
1245 void send_response() override = 0;
1246 const string name() override { return "delete_obj"; }
1247 RGWOpType get_type() override { return RGW_OP_DELETE_OBJ; }
1248 uint32_t op_mask() override { return RGW_OP_TYPE_DELETE; }
1249 virtual bool need_object_expiration() { return false; }
1250 };
1251
1252 class RGWCopyObj : public RGWOp {
1253 protected:
1254 RGWAccessControlPolicy dest_policy;
1255 const char *if_mod;
1256 const char *if_unmod;
1257 const char *if_match;
1258 const char *if_nomatch;
1259 off_t ofs;
1260 off_t len;
1261 off_t end;
1262 ceph::real_time mod_time;
1263 ceph::real_time unmod_time;
1264 ceph::real_time *mod_ptr;
1265 ceph::real_time *unmod_ptr;
1266 map<string, buffer::list> attrs;
1267 string src_tenant_name, src_bucket_name;
1268 rgw_bucket src_bucket;
1269 rgw_obj_key src_object;
1270 string dest_tenant_name, dest_bucket_name;
1271 rgw_bucket dest_bucket;
1272 string dest_object;
1273 ceph::real_time src_mtime;
1274 ceph::real_time mtime;
1275 RGWRados::AttrsMod attrs_mod;
1276 RGWBucketInfo src_bucket_info;
1277 RGWBucketInfo dest_bucket_info;
1278 string source_zone;
1279 string client_id;
1280 string op_id;
1281 ceph::buffer::list etag;
1282
1283 off_t last_ofs;
1284
1285 string version_id;
1286 uint64_t olh_epoch;
1287
1288 boost::optional<ceph::real_time> delete_at;
1289 bool copy_if_newer;
1290
1291 int init_common();
1292
1293 public:
1294 RGWCopyObj() {
1295 if_mod = NULL;
1296 if_unmod = NULL;
1297 if_match = NULL;
1298 if_nomatch = NULL;
1299 ofs = 0;
1300 len = 0;
1301 end = -1;
1302 mod_ptr = NULL;
1303 unmod_ptr = NULL;
1304 attrs_mod = RGWRados::ATTRSMOD_NONE;
1305 last_ofs = 0;
1306 olh_epoch = 0;
1307 copy_if_newer = false;
1308 }
1309
1310 static bool parse_copy_location(const string& src,
1311 string& bucket_name,
1312 rgw_obj_key& object);
1313
1314 void emplace_attr(std::string&& key, buffer::list&& bl) {
1315 attrs.emplace(std::move(key), std::move(bl));
1316 }
1317
1318 void init(RGWRados *store, struct req_state *s, RGWHandler *h) override {
1319 RGWOp::init(store, s, h);
1320 dest_policy.set_ctx(s->cct);
1321 }
1322 int verify_permission() override;
1323 void pre_exec() override;
1324 void execute() override;
1325 void progress_cb(off_t ofs);
1326
1327 virtual int init_dest_policy() { return 0; }
1328 virtual int get_params() = 0;
1329 virtual void send_partial_response(off_t ofs) {}
1330 void send_response() override = 0;
1331 const string name() override { return "copy_obj"; }
1332 RGWOpType get_type() override { return RGW_OP_COPY_OBJ; }
1333 uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
1334 };
1335
1336 class RGWGetACLs : public RGWOp {
1337 protected:
1338 string acls;
1339
1340 public:
1341 RGWGetACLs() {}
1342
1343 int verify_permission() override;
1344 void pre_exec() override;
1345 void execute() override;
1346
1347 void send_response() override = 0;
1348 const string name() override { return "get_acls"; }
1349 RGWOpType get_type() override { return RGW_OP_GET_ACLS; }
1350 uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
1351 };
1352
1353 class RGWPutACLs : public RGWOp {
1354 protected:
1355 int len;
1356 char *data;
1357 ACLOwner owner;
1358
1359 public:
1360 RGWPutACLs() {
1361 len = 0;
1362 data = NULL;
1363 }
1364 ~RGWPutACLs() override {
1365 free(data);
1366 }
1367
1368 int verify_permission() override;
1369 void pre_exec() override;
1370 void execute() override;
1371
1372 virtual int get_policy_from_state(RGWRados *store, struct req_state *s, stringstream& ss) { return 0; }
1373 virtual int get_params() = 0;
1374 void send_response() override = 0;
1375 const string name() override { return "put_acls"; }
1376 RGWOpType get_type() override { return RGW_OP_PUT_ACLS; }
1377 uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
1378 };
1379
1380 class RGWGetLC : public RGWOp {
1381 protected:
1382
1383 public:
1384 RGWGetLC() { }
1385 ~RGWGetLC() override { }
1386
1387 int verify_permission() override;
1388 void pre_exec() override;
1389 void execute() override = 0;
1390
1391 void send_response() override = 0;
1392 const string name() override { return "get_lifecycle"; }
1393 uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
1394 };
1395
1396 class RGWPutLC : public RGWOp {
1397 protected:
1398 int len;
1399 char *data;
1400 string cookie;
1401
1402 public:
1403 RGWPutLC() {
1404 len = 0;
1405 data = NULL;
1406 }
1407 ~RGWPutLC() override {
1408 free(data);
1409 }
1410
1411 void init(RGWRados *store, struct req_state *s, RGWHandler *dialect_handler) override {
1412 #define COOKIE_LEN 16
1413 char buf[COOKIE_LEN + 1];
1414
1415 RGWOp::init(store, s, dialect_handler);
1416 gen_rand_alphanumeric(s->cct, buf, sizeof(buf) - 1);
1417 cookie = buf;
1418 }
1419
1420 int verify_permission() override;
1421 void pre_exec() override;
1422 void execute() override;
1423
1424 // virtual int get_policy_from_state(RGWRados *store, struct req_state *s, stringstream& ss) { return 0; }
1425 virtual int get_params() = 0;
1426 void send_response() override = 0;
1427 const string name() override { return "put_lifecycle"; }
1428 uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
1429 };
1430
1431 class RGWDeleteLC : public RGWOp {
1432 protected:
1433 size_t len;
1434 char *data;
1435
1436 public:
1437 RGWDeleteLC() {
1438 len = 0;
1439 data = NULL;
1440 }
1441 ~RGWDeleteLC() override {
1442 free(data);
1443 }
1444
1445 int verify_permission() override;
1446 void pre_exec() override;
1447 void execute() override;
1448
1449 void send_response() override = 0;
1450 const string name() override { return "delete_lifecycle"; }
1451 uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
1452 };
1453
1454 class RGWGetCORS : public RGWOp {
1455 protected:
1456
1457 public:
1458 RGWGetCORS() {}
1459
1460 int verify_permission() override;
1461 void execute() override;
1462
1463 void send_response() override = 0;
1464 const string name() override { return "get_cors"; }
1465 RGWOpType get_type() override { return RGW_OP_GET_CORS; }
1466 uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
1467 };
1468
1469 class RGWPutCORS : public RGWOp {
1470 protected:
1471 bufferlist cors_bl;
1472 bufferlist in_data;
1473
1474 public:
1475 RGWPutCORS() {}
1476 ~RGWPutCORS() override {}
1477
1478 int verify_permission() override;
1479 void execute() override;
1480
1481 virtual int get_params() = 0;
1482 void send_response() override = 0;
1483 const string name() override { return "put_cors"; }
1484 RGWOpType get_type() override { return RGW_OP_PUT_CORS; }
1485 uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
1486 };
1487
1488 class RGWDeleteCORS : public RGWOp {
1489 protected:
1490
1491 public:
1492 RGWDeleteCORS() {}
1493
1494 int verify_permission() override;
1495 void execute() override;
1496
1497 void send_response() override = 0;
1498 const string name() override { return "delete_cors"; }
1499 RGWOpType get_type() override { return RGW_OP_DELETE_CORS; }
1500 uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
1501 };
1502
1503 class RGWOptionsCORS : public RGWOp {
1504 protected:
1505 RGWCORSRule *rule;
1506 const char *origin, *req_hdrs, *req_meth;
1507
1508 public:
1509 RGWOptionsCORS() : rule(NULL), origin(NULL),
1510 req_hdrs(NULL), req_meth(NULL) {
1511 }
1512
1513 int verify_permission() override {return 0;}
1514 int validate_cors_request(RGWCORSConfiguration *cc);
1515 void execute() override;
1516 void get_response_params(string& allowed_hdrs, string& exp_hdrs, unsigned *max_age);
1517 void send_response() override = 0;
1518 const string name() override { return "options_cors"; }
1519 RGWOpType get_type() override { return RGW_OP_OPTIONS_CORS; }
1520 uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
1521 };
1522
1523 class RGWGetRequestPayment : public RGWOp {
1524 protected:
1525 bool requester_pays;
1526
1527 public:
1528 RGWGetRequestPayment() : requester_pays(0) {}
1529
1530 int verify_permission() override;
1531 void pre_exec() override;
1532 void execute() override;
1533
1534 void send_response() override = 0;
1535 const string name() override { return "get_request_payment"; }
1536 RGWOpType get_type() override { return RGW_OP_GET_REQUEST_PAYMENT; }
1537 uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
1538 };
1539
1540 class RGWSetRequestPayment : public RGWOp {
1541 protected:
1542 bool requester_pays;
1543 public:
1544 RGWSetRequestPayment() : requester_pays(false) {}
1545
1546 int verify_permission() override;
1547 void pre_exec() override;
1548 void execute() override;
1549
1550 virtual int get_params() { return 0; }
1551
1552 void send_response() override = 0;
1553 const string name() override { return "set_request_payment"; }
1554 RGWOpType get_type() override { return RGW_OP_SET_REQUEST_PAYMENT; }
1555 uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
1556 };
1557
1558 class RGWInitMultipart : public RGWOp {
1559 protected:
1560 string upload_id;
1561 RGWAccessControlPolicy policy;
1562
1563 public:
1564 RGWInitMultipart() {}
1565
1566 void init(RGWRados *store, struct req_state *s, RGWHandler *h) override {
1567 RGWOp::init(store, s, h);
1568 policy.set_ctx(s->cct);
1569 }
1570 int verify_permission() override;
1571 void pre_exec() override;
1572 void execute() override;
1573
1574 virtual int get_params() = 0;
1575 void send_response() override = 0;
1576 const string name() override { return "init_multipart"; }
1577 RGWOpType get_type() override { return RGW_OP_INIT_MULTIPART; }
1578 uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
1579 virtual int prepare_encryption(map<string, bufferlist>& attrs) { return 0; }
1580 };
1581
1582 class RGWCompleteMultipart : public RGWOp {
1583 protected:
1584 string upload_id;
1585 string etag;
1586 char *data;
1587 int len;
1588
1589 public:
1590 RGWCompleteMultipart() {
1591 data = NULL;
1592 len = 0;
1593 }
1594 ~RGWCompleteMultipart() override {
1595 free(data);
1596 }
1597
1598 int verify_permission() override;
1599 void pre_exec() override;
1600 void execute() override;
1601
1602 virtual int get_params() = 0;
1603 void send_response() override = 0;
1604 const string name() override { return "complete_multipart"; }
1605 RGWOpType get_type() override { return RGW_OP_COMPLETE_MULTIPART; }
1606 uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
1607 };
1608
1609 class RGWAbortMultipart : public RGWOp {
1610 public:
1611 RGWAbortMultipart() {}
1612
1613 int verify_permission() override;
1614 void pre_exec() override;
1615 void execute() override;
1616
1617 void send_response() override = 0;
1618 const string name() override { return "abort_multipart"; }
1619 RGWOpType get_type() override { return RGW_OP_ABORT_MULTIPART; }
1620 uint32_t op_mask() override { return RGW_OP_TYPE_DELETE; }
1621 };
1622
1623 class RGWListMultipart : public RGWOp {
1624 protected:
1625 string upload_id;
1626 map<uint32_t, RGWUploadPartInfo> parts;
1627 int max_parts;
1628 int marker;
1629 RGWAccessControlPolicy policy;
1630 bool truncated;
1631
1632 public:
1633 RGWListMultipart() {
1634 max_parts = 1000;
1635 marker = 0;
1636 truncated = false;
1637 }
1638
1639 void init(RGWRados *store, struct req_state *s, RGWHandler *h) override {
1640 RGWOp::init(store, s, h);
1641 policy = RGWAccessControlPolicy(s->cct);
1642 }
1643 int verify_permission() override;
1644 void pre_exec() override;
1645 void execute() override;
1646
1647 virtual int get_params() = 0;
1648 void send_response() override = 0;
1649 const string name() override { return "list_multipart"; }
1650 RGWOpType get_type() override { return RGW_OP_LIST_MULTIPART; }
1651 uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
1652 };
1653
1654 struct RGWMultipartUploadEntry {
1655 rgw_bucket_dir_entry obj;
1656 RGWMPObj mp;
1657 };
1658
1659 class RGWListBucketMultiparts : public RGWOp {
1660 protected:
1661 string prefix;
1662 RGWMPObj marker;
1663 RGWMultipartUploadEntry next_marker;
1664 int max_uploads;
1665 string delimiter;
1666 vector<RGWMultipartUploadEntry> uploads;
1667 map<string, bool> common_prefixes;
1668 bool is_truncated;
1669 int default_max;
1670
1671 public:
1672 RGWListBucketMultiparts() {
1673 max_uploads = 0;
1674 is_truncated = false;
1675 default_max = 0;
1676 }
1677
1678 void init(RGWRados *store, struct req_state *s, RGWHandler *h) override {
1679 RGWOp::init(store, s, h);
1680 max_uploads = default_max;
1681 }
1682
1683 int verify_permission() override;
1684 void pre_exec() override;
1685 void execute() override;
1686
1687 virtual int get_params() = 0;
1688 void send_response() override = 0;
1689 const string name() override { return "list_bucket_multiparts"; }
1690 RGWOpType get_type() override { return RGW_OP_LIST_BUCKET_MULTIPARTS; }
1691 uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
1692 };
1693
1694
1695 class RGWGetCrossDomainPolicy : public RGWOp {
1696 public:
1697 RGWGetCrossDomainPolicy() = default;
1698 ~RGWGetCrossDomainPolicy() override = default;
1699
1700 int verify_permission() override {
1701 return 0;
1702 }
1703
1704 void execute() override {
1705 op_ret = 0;
1706 }
1707
1708 const string name() override {
1709 return "get_crossdomain_policy";
1710 }
1711
1712 RGWOpType get_type() override {
1713 return RGW_OP_GET_CROSS_DOMAIN_POLICY;
1714 }
1715
1716 uint32_t op_mask() override {
1717 return RGW_OP_TYPE_READ;
1718 }
1719 };
1720
1721
1722 class RGWGetHealthCheck : public RGWOp {
1723 public:
1724 RGWGetHealthCheck() = default;
1725 ~RGWGetHealthCheck() override = default;
1726
1727 int verify_permission() override {
1728 return 0;
1729 }
1730
1731 void execute() override;
1732
1733 const string name() override {
1734 return "get_health_check";
1735 }
1736
1737 RGWOpType get_type() override {
1738 return RGW_OP_GET_HEALTH_CHECK;
1739 }
1740
1741 uint32_t op_mask() override {
1742 return RGW_OP_TYPE_READ;
1743 }
1744 };
1745
1746
1747 class RGWDeleteMultiObj : public RGWOp {
1748 protected:
1749 int max_to_delete;
1750 int len;
1751 char *data;
1752 rgw_bucket bucket;
1753 bool quiet;
1754 bool status_dumped;
1755 bool acl_allowed = false;
1756
1757 public:
1758 RGWDeleteMultiObj() {
1759 max_to_delete = 1000;
1760 len = 0;
1761 data = NULL;
1762 quiet = false;
1763 status_dumped = false;
1764 }
1765 int verify_permission() override;
1766 void pre_exec() override;
1767 void execute() override;
1768
1769 virtual int get_params() = 0;
1770 virtual void send_status() = 0;
1771 virtual void begin_response() = 0;
1772 virtual void send_partial_response(rgw_obj_key& key, bool delete_marker,
1773 const string& marker_version_id, int ret) = 0;
1774 virtual void end_response() = 0;
1775 const string name() override { return "multi_object_delete"; }
1776 RGWOpType get_type() override { return RGW_OP_DELETE_MULTI_OBJ; }
1777 uint32_t op_mask() override { return RGW_OP_TYPE_DELETE; }
1778 };
1779
1780 class RGWInfo: public RGWOp {
1781 public:
1782 RGWInfo() = default;
1783 ~RGWInfo() override = default;
1784
1785 int verify_permission() override { return 0; }
1786 const string name() override { return "get info"; }
1787 RGWOpType get_type() override { return RGW_OP_GET_INFO; }
1788 uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
1789 };
1790
1791 extern int rgw_build_bucket_policies(RGWRados* store, struct req_state* s);
1792 extern int rgw_build_object_policies(RGWRados *store, struct req_state *s,
1793 bool prefetch_data);
1794 extern rgw::IAM::Environment rgw_build_iam_environment(RGWRados* store,
1795 struct req_state* s);
1796
1797 static inline int put_data_and_throttle(RGWPutObjDataProcessor *processor,
1798 bufferlist& data, off_t ofs,
1799 bool need_to_wait)
1800 {
1801 bool again = false;
1802 do {
1803 void *handle = nullptr;
1804 rgw_raw_obj obj;
1805
1806 uint64_t size = data.length();
1807
1808 int ret = processor->handle_data(data, ofs, &handle, &obj, &again);
1809 if (ret < 0)
1810 return ret;
1811 if (handle != nullptr)
1812 {
1813 ret = processor->throttle_data(handle, obj, size, need_to_wait);
1814 if (ret < 0)
1815 return ret;
1816 }
1817 else
1818 break;
1819 need_to_wait = false; /* the need to wait only applies to the first
1820 * iteration */
1821 } while (again);
1822
1823 return 0;
1824 } /* put_data_and_throttle */
1825
1826
1827
1828
1829
1830 static inline int get_system_versioning_params(req_state *s,
1831 uint64_t *olh_epoch,
1832 string *version_id)
1833 {
1834 if (!s->system_request) {
1835 return 0;
1836 }
1837
1838 if (olh_epoch) {
1839 string epoch_str = s->info.args.get(RGW_SYS_PARAM_PREFIX "versioned-epoch");
1840 if (!epoch_str.empty()) {
1841 string err;
1842 *olh_epoch = strict_strtol(epoch_str.c_str(), 10, &err);
1843 if (!err.empty()) {
1844 lsubdout(s->cct, rgw, 0) << "failed to parse versioned-epoch param"
1845 << dendl;
1846 return -EINVAL;
1847 }
1848 }
1849 }
1850
1851 if (version_id) {
1852 *version_id = s->info.args.get(RGW_SYS_PARAM_PREFIX "version-id");
1853 }
1854
1855 return 0;
1856 } /* get_system_versioning_params */
1857
1858 static inline void format_xattr(std::string &xattr)
1859 {
1860 /* If the extended attribute is not valid UTF-8, we encode it using
1861 * quoted-printable encoding.
1862 */
1863 if ((check_utf8(xattr.c_str(), xattr.length()) != 0) ||
1864 (check_for_control_characters(xattr.c_str(), xattr.length()) != 0)) {
1865 static const char MIME_PREFIX_STR[] = "=?UTF-8?Q?";
1866 static const int MIME_PREFIX_LEN = sizeof(MIME_PREFIX_STR) - 1;
1867 static const char MIME_SUFFIX_STR[] = "?=";
1868 static const int MIME_SUFFIX_LEN = sizeof(MIME_SUFFIX_STR) - 1;
1869 int mlen = mime_encode_as_qp(xattr.c_str(), NULL, 0);
1870 char *mime = new char[MIME_PREFIX_LEN + mlen + MIME_SUFFIX_LEN + 1];
1871 strcpy(mime, MIME_PREFIX_STR);
1872 mime_encode_as_qp(xattr.c_str(), mime + MIME_PREFIX_LEN, mlen);
1873 strcpy(mime + MIME_PREFIX_LEN + (mlen - 1), MIME_SUFFIX_STR);
1874 xattr.assign(mime);
1875 delete [] mime;
1876 }
1877 } /* format_xattr */
1878
1879 /**
1880 * Get the HTTP request metadata out of the req_state as a
1881 * map(<attr_name, attr_contents>, where attr_name is RGW_ATTR_PREFIX.HTTP_NAME)
1882 * s: The request state
1883 * attrs: will be filled up with attrs mapped as <attr_name, attr_contents>
1884 *
1885 */
1886 static inline void rgw_get_request_metadata(CephContext *cct,
1887 struct req_info& info,
1888 map<string, bufferlist>& attrs,
1889 const bool allow_empty_attrs = true)
1890 {
1891 static const std::set<std::string> blacklisted_headers = {
1892 "x-amz-server-side-encryption-customer-algorithm",
1893 "x-amz-server-side-encryption-customer-key",
1894 "x-amz-server-side-encryption-customer-key-md5"
1895 };
1896 map<string, string>::iterator iter;
1897 for (iter = info.x_meta_map.begin(); iter != info.x_meta_map.end(); ++iter) {
1898 const string &name(iter->first);
1899 string &xattr(iter->second);
1900 if (blacklisted_headers.count(name) == 1) {
1901 lsubdout(cct, rgw, 10) << "skipping x>> " << name << dendl;
1902 continue;
1903 }
1904 if (allow_empty_attrs || !xattr.empty()) {
1905 lsubdout(cct, rgw, 10) << "x>> " << name << ":" << xattr << dendl;
1906 format_xattr(xattr);
1907 string attr_name(RGW_ATTR_PREFIX);
1908 attr_name.append(name);
1909 map<string, bufferlist>::value_type v(attr_name, bufferlist());
1910 std::pair < map<string, bufferlist>::iterator, bool >
1911 rval(attrs.insert(v));
1912 bufferlist& bl(rval.first->second);
1913 bl.append(xattr.c_str(), xattr.size() + 1);
1914 }
1915 }
1916 } /* rgw_get_request_metadata */
1917
1918 static inline void encode_delete_at_attr(boost::optional<ceph::real_time> delete_at,
1919 map<string, bufferlist>& attrs)
1920 {
1921 if (delete_at == boost::none) {
1922 return;
1923 }
1924
1925 bufferlist delatbl;
1926 ::encode(*delete_at, delatbl);
1927 attrs[RGW_ATTR_DELETE_AT] = delatbl;
1928 } /* encode_delete_at_attr */
1929
1930 static inline void encode_obj_tags_attr(RGWObjTags* obj_tags, map<string, bufferlist>& attrs)
1931 {
1932 if (obj_tags == nullptr){
1933 // we assume the user submitted a tag format which we couldn't parse since
1934 // this wouldn't be parsed later by get/put obj tags, lets delete if the
1935 // attr was populated
1936 return;
1937 }
1938
1939 bufferlist tagsbl;
1940 obj_tags->encode(tagsbl);
1941 attrs[RGW_ATTR_TAGS] = tagsbl;
1942 }
1943
1944 static inline int encode_dlo_manifest_attr(const char * const dlo_manifest,
1945 map<string, bufferlist>& attrs)
1946 {
1947 string dm = dlo_manifest;
1948
1949 if (dm.find('/') == string::npos) {
1950 return -EINVAL;
1951 }
1952
1953 bufferlist manifest_bl;
1954 manifest_bl.append(dlo_manifest, strlen(dlo_manifest) + 1);
1955 attrs[RGW_ATTR_USER_MANIFEST] = manifest_bl;
1956
1957 return 0;
1958 } /* encode_dlo_manifest_attr */
1959
1960 static inline void complete_etag(MD5& hash, string *etag)
1961 {
1962 char etag_buf[CEPH_CRYPTO_MD5_DIGESTSIZE];
1963 char etag_buf_str[CEPH_CRYPTO_MD5_DIGESTSIZE * 2 + 16];
1964
1965 hash.Final((byte *)etag_buf);
1966 buf_to_hex((const unsigned char *)etag_buf, CEPH_CRYPTO_MD5_DIGESTSIZE,
1967 etag_buf_str);
1968
1969 *etag = etag_buf_str;
1970 } /* complete_etag */
1971
1972 class RGWSetAttrs : public RGWOp {
1973 protected:
1974 map<string, buffer::list> attrs;
1975
1976 public:
1977 RGWSetAttrs() {}
1978 ~RGWSetAttrs() override {}
1979
1980 void emplace_attr(std::string&& key, buffer::list&& bl) {
1981 attrs.emplace(std::move(key), std::move(bl));
1982 }
1983
1984 int verify_permission() override;
1985 void pre_exec() override;
1986 void execute() override;
1987
1988 virtual int get_params() = 0;
1989 void send_response() override = 0;
1990 const string name() override { return "set_attrs"; }
1991 RGWOpType get_type() override { return RGW_OP_SET_ATTRS; }
1992 uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
1993 };
1994
1995 class RGWGetObjLayout : public RGWOp {
1996 protected:
1997 RGWObjManifest *manifest{nullptr};
1998 rgw_raw_obj head_obj;
1999
2000 public:
2001 RGWGetObjLayout() {
2002 }
2003
2004 int check_caps(RGWUserCaps& caps) {
2005 return caps.check_cap("admin", RGW_CAP_READ);
2006 }
2007 int verify_permission() {
2008 return check_caps(s->user->caps);
2009 }
2010 void pre_exec();
2011 void execute();
2012
2013 virtual void send_response() = 0;
2014 virtual const string name() { return "get_obj_layout"; }
2015 virtual RGWOpType get_type() { return RGW_OP_GET_OBJ_LAYOUT; }
2016 virtual uint32_t op_mask() { return RGW_OP_TYPE_READ; }
2017 };
2018
2019 class RGWPutBucketPolicy : public RGWOp {
2020 int len;
2021 char *data = nullptr;
2022 public:
2023 RGWPutBucketPolicy() = default;
2024 ~RGWPutBucketPolicy() {
2025 if (data) {
2026 free(static_cast<void*>(data));
2027 }
2028 }
2029 void send_response() override;
2030 int verify_permission() override;
2031 uint32_t op_mask() override {
2032 return RGW_OP_TYPE_WRITE;
2033 }
2034 void execute() override;
2035 int get_params();
2036 const std::string name() override {
2037 return "put_bucket_policy";
2038 }
2039 RGWOpType get_type() override {
2040 return RGW_OP_PUT_BUCKET_POLICY;
2041 }
2042 };
2043
2044 class RGWGetBucketPolicy : public RGWOp {
2045 buffer::list policy;
2046 public:
2047 RGWGetBucketPolicy() = default;
2048 void send_response() override;
2049 int verify_permission() override;
2050 uint32_t op_mask() override {
2051 return RGW_OP_TYPE_READ;
2052 }
2053 void execute() override;
2054 const std::string name() override {
2055 return "get_bucket_policy";
2056 }
2057 RGWOpType get_type() override {
2058 return RGW_OP_GET_BUCKET_POLICY;
2059 }
2060 };
2061
2062 class RGWDeleteBucketPolicy : public RGWOp {
2063 public:
2064 RGWDeleteBucketPolicy() = default;
2065 void send_response() override;
2066 int verify_permission() override;
2067 uint32_t op_mask() override {
2068 return RGW_OP_TYPE_WRITE;
2069 }
2070 void execute() override;
2071 int get_params();
2072 const std::string name() override {
2073 return "delete_bucket_policy";
2074 }
2075 RGWOpType get_type() override {
2076 return RGW_OP_DELETE_BUCKET_POLICY;
2077 }
2078 };
2079
2080
2081 class RGWConfigBucketMetaSearch : public RGWOp {
2082 protected:
2083 std::map<std::string, uint32_t> mdsearch_config;
2084 public:
2085 RGWConfigBucketMetaSearch() {}
2086
2087 int verify_permission();
2088 void pre_exec();
2089 void execute();
2090
2091 virtual int get_params() = 0;
2092 virtual void send_response() = 0;
2093 virtual const string name() { return "config_bucket_meta_search"; }
2094 virtual RGWOpType get_type() { return RGW_OP_CONFIG_BUCKET_META_SEARCH; }
2095 virtual uint32_t op_mask() { return RGW_OP_TYPE_WRITE; }
2096 };
2097
2098 class RGWGetBucketMetaSearch : public RGWOp {
2099 public:
2100 RGWGetBucketMetaSearch() {}
2101
2102 int verify_permission();
2103 void pre_exec();
2104 void execute() {}
2105
2106 virtual void send_response() = 0;
2107 virtual const string name() { return "get_bucket_meta_search"; }
2108 virtual RGWOpType get_type() { return RGW_OP_GET_BUCKET_META_SEARCH; }
2109 virtual uint32_t op_mask() { return RGW_OP_TYPE_READ; }
2110 };
2111
2112 class RGWDelBucketMetaSearch : public RGWOp {
2113 public:
2114 RGWDelBucketMetaSearch() {}
2115
2116 int verify_permission();
2117 void pre_exec();
2118 void execute();
2119
2120 virtual void send_response() = 0;
2121 virtual const string name() { return "delete_bucket_meta_search"; }
2122 virtual RGWOpType delete_type() { return RGW_OP_DEL_BUCKET_META_SEARCH; }
2123 virtual uint32_t op_mask() { return RGW_OP_TYPE_WRITE; }
2124 };
2125
2126 #endif /* CEPH_RGW_OP_H */