]> git.proxmox.com Git - ceph.git/blame - ceph/src/rgw/rgw_op.h
update sources to v12.2.1
[ceph.git] / ceph / src / rgw / rgw_op.h
CommitLineData
31f18b77 1// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
7c673cae
FG
2// vim: ts=8 sw=2 smarttab
3/**
4 * All operations via the rados gateway are carried out by
5 * small classes known as RGWOps. This class contains a req_state
6 * and each possible command is a subclass of this with a defined
7 * execute() method that does whatever the subclass name implies.
8 * These subclasses must be further subclassed (by interface type)
9 * to provide additional virtual methods such as send_response or get_params.
10 */
11#ifndef CEPH_RGW_OP_H
12#define CEPH_RGW_OP_H
13
14#include <limits.h>
15
16#include <array>
17#include <memory>
18#include <string>
19#include <set>
20#include <map>
21#include <vector>
22
23#include <boost/optional.hpp>
24#include <boost/utility/in_place_factory.hpp>
31f18b77 25#include <boost/function.hpp>
7c673cae
FG
26
27#include "common/armor.h"
28#include "common/mime.h"
29#include "common/utf8.h"
30#include "common/ceph_json.h"
31#include "common/utf8.h"
32#include "common/ceph_time.h"
33
34#include "rgw_common.h"
35#include "rgw_rados.h"
36#include "rgw_user.h"
37#include "rgw_bucket.h"
38#include "rgw_acl.h"
39#include "rgw_cors.h"
40#include "rgw_quota.h"
41
42#include "rgw_lc.h"
43#include "rgw_torrent.h"
224ce89b 44#include "rgw_tag.h"
7c673cae
FG
45
46#include "include/assert.h"
47
7c673cae
FG
48using ceph::crypto::SHA1;
49
50struct req_state;
51class RGWOp;
52
53
54namespace rgw {
55namespace auth {
56namespace registry {
57
58class StrategyRegistry;
59
60}
61}
62}
63
64
65class RGWHandler {
66protected:
67 RGWRados* store;
68 struct req_state* s;
69
70 int do_init_permissions();
71 int do_read_permissions(RGWOp* op, bool only_bucket);
72
73public:
74 RGWHandler()
75 : store(nullptr),
76 s(nullptr) {
77 }
78 virtual ~RGWHandler();
79
80 virtual int init(RGWRados* store,
81 struct req_state* _s,
82 rgw::io::BasicClient* cio);
83
84 virtual int init_permissions(RGWOp*) {
85 return 0;
86 }
87
88 virtual int retarget(RGWOp* op, RGWOp** new_op) {
89 *new_op = op;
90 return 0;
91 }
92
93 virtual int read_permissions(RGWOp* op) = 0;
94 virtual int authorize() = 0;
95 virtual int postauth_init() = 0;
96 virtual int error_handler(int err_no, std::string* error_content);
31f18b77 97 virtual void dump(const string& code, const string& message) const {}
7c673cae
FG
98};
99
100
31f18b77
FG
101
102void rgw_bucket_object_pre_exec(struct req_state *s);
103
7c673cae
FG
104/**
105 * Provide the base class for all ops.
106 */
107class RGWOp {
108protected:
109 struct req_state *s;
110 RGWHandler *dialect_handler;
111 RGWRados *store;
112 RGWCORSConfiguration bucket_cors;
113 bool cors_exist;
114 RGWQuotaInfo bucket_quota;
115 RGWQuotaInfo user_quota;
116 int op_ret;
117
118 int do_aws4_auth_completion();
119
120 virtual int init_quota();
121public:
122 RGWOp()
123 : s(nullptr),
124 dialect_handler(nullptr),
125 store(nullptr),
126 cors_exist(false),
127 op_ret(0) {
128 }
129
130 virtual ~RGWOp() = default;
131
132 int get_ret() const { return op_ret; }
133
134 virtual int init_processing() {
135 op_ret = init_quota();
136 if (op_ret < 0)
137 return op_ret;
138
139 return 0;
140 }
141
142 virtual void init(RGWRados *store, struct req_state *s, RGWHandler *dialect_handler) {
143 this->store = store;
144 this->s = s;
145 this->dialect_handler = dialect_handler;
146 }
147 int read_bucket_cors();
148 bool generate_cors_headers(string& origin, string& method, string& headers, string& exp_headers, unsigned *max_age);
149
150 virtual int verify_params() { return 0; }
151 virtual bool prefetch_data() { return false; }
152
153 /* Authenticate requester -- verify its identity.
154 *
155 * NOTE: typically the procedure is common across all operations of the same
156 * dialect (S3, Swift API). However, there are significant exceptions in
157 * both APIs: browser uploads, /info and OPTIONS handlers. All of them use
158 * different, specific authentication schema driving the need for per-op
159 * authentication. The alternative is to duplicate parts of the method-
160 * dispatch logic in RGWHandler::authorize() and pollute it with a lot
161 * of special cases. */
162 virtual int verify_requester(const rgw::auth::StrategyRegistry& auth_registry) {
163 /* TODO(rzarzynski): rename RGWHandler::authorize to generic_authenticate. */
164 return dialect_handler->authorize();
165 }
166 virtual int verify_permission() = 0;
167 virtual int verify_op_mask();
168 virtual void pre_exec() {}
169 virtual void execute() = 0;
170 virtual void send_response() {}
171 virtual void complete() {
172 send_response();
173 }
174 virtual const string name() = 0;
175 virtual RGWOpType get_type() { return RGW_OP_UNKNOWN; }
176
177 virtual uint32_t op_mask() { return 0; }
178
179 virtual int error_handler(int err_no, string *error_content);
180};
181
182class RGWGetObj : public RGWOp {
183protected:
184 seed torrent; // get torrent
185 const char *range_str;
186 const char *if_mod;
187 const char *if_unmod;
188 const char *if_match;
189 const char *if_nomatch;
190 uint32_t mod_zone_id;
191 uint64_t mod_pg_ver;
192 off_t ofs;
193 uint64_t total_len;
194 off_t start;
195 off_t end;
196 ceph::real_time mod_time;
197 ceph::real_time lastmod;
198 ceph::real_time unmod_time;
199 ceph::real_time *mod_ptr;
200 ceph::real_time *unmod_ptr;
201 map<string, bufferlist> attrs;
202 bool get_data;
203 bool partial_content;
204 bool range_parsed;
205 bool skip_manifest;
181888fb 206 bool skip_decrypt{false};
7c673cae
FG
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 */
31f18b77 212 string version_id;
7c673cae
FG
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;
31f18b77 221 uint64_t action = 0;
7c673cae
FG
222
223 int init_common();
224public:
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;
31f18b77
FG
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);
7c673cae
FG
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
289class RGWGetObj_CB : public RGWGetDataCB
290{
291 RGWGetObj *op;
292public:
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
301class RGWGetObj_Filter : public RGWGetDataCB
302{
303protected:
304 RGWGetDataCB* next;
305public:
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
224ce89b
WB
331class 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
347class 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
362class 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
7c673cae
FG
374class RGWBulkDelete : public RGWOp {
375public:
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
425protected:
426 std::unique_ptr<Deleter> deleter;
427
428public:
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
446inline ostream& operator<<(ostream& out, const RGWBulkDelete::acct_path_t &o) {
447 return out << o.bucket_name << "/" << o.obj_key;
448}
449
450
451class RGWBulkUploadOp : public RGWOp {
452 boost::optional<RGWObjectCtx> dir_ctx;
453
454protected:
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,
31f18b77
FG
488 const rgw_obj& obj,
489 std::map<std::string, ceph::bufferlist>& battrs,
7c673cae
FG
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
498public:
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
528class RGWBulkUploadOp::StreamGetter {
529public:
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
538class RGWBulkUploadOp::DecoratedStreamGetter : public StreamGetter {
539 StreamGetter& decoratee;
540
541protected:
542 StreamGetter& get_decoratee() {
543 return decoratee;
544 }
545
546public:
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
562class RGWBulkUploadOp::AlignedStreamGetter
563 : public RGWBulkUploadOp::DecoratedStreamGetter {
564 size_t position;
565 size_t length;
566 size_t alignment;
567
568public:
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
587class RGWListBuckets : public RGWOp {
588protected:
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
605public:
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
632class RGWGetUsage : public RGWOp {
633protected:
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;
c07f9fc5 642 map<string, cls_user_bucket_entry> buckets_usage;
7c673cae
FG
643 cls_user_header header;
644public:
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
660class RGWStatAccount : public RGWOp {
661protected:
662 uint32_t buckets_count;
663 uint64_t buckets_objcount;
664 uint64_t buckets_size;
665 uint64_t buckets_size_rounded;
666
667public:
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
684class RGWListBucket : public RGWOp {
685protected:
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
706public:
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
721class RGWGetBucketLogging : public RGWOp {
722public:
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
733class RGWGetBucketLocation : public RGWOp {
734public:
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
745class RGWGetBucketVersioning : public RGWOp {
746protected:
747 bool versioned;
748 bool versioning_enabled;
749public:
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
762class RGWSetBucketVersioning : public RGWOp {
763protected:
764 bool enable_versioning;
765 bufferlist in_data;
766public:
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
781class RGWGetBucketWebsite : public RGWOp {
782public:
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
795class RGWSetBucketWebsite : public RGWOp {
796protected:
31f18b77 797 bufferlist in_data;
7c673cae
FG
798 RGWBucketWebsiteConf website_conf;
799public:
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
814class RGWDeleteBucketWebsite : public RGWOp {
815public:
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
828class RGWStatBucket : public RGWOp {
829protected:
830 RGWBucketEnt bucket;
831
832public:
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
846class RGWCreateBucket : public RGWOp {
847protected:
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
863public:
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
884class RGWDeleteBucket : public RGWOp {
885protected:
886 RGWObjVersionTracker objv_tracker;
887
888public:
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
901struct 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};
926WRITE_CLASS_ENCODER(rgw_slo_entry)
927
928struct 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};
955WRITE_CLASS_ENCODER(RGWSLOInfo)
956
957class RGWPutObj : public RGWOp {
958
959 friend class RGWPutObjProcessor;
960
961protected:
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;
224ce89b 980 std::unique_ptr <RGWObjTags> obj_tags;
7c673cae
FG
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
993public:
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
1052class RGWPutObj_Filter : public RGWPutObjDataProcessor
1053{
1054protected:
1055 RGWPutObjDataProcessor* next;
1056public:
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
1068class RGWPostObj : public RGWOp {
1069protected:
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 }
1087public:
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
1121class RGWPutMetadataAccount : public RGWOp {
1122protected:
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
1134public:
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
1159class RGWPutMetadataBucket : public RGWOp {
1160protected:
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
1170public:
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
1195class RGWPutMetadataObject : public RGWOp {
1196protected:
1197 RGWAccessControlPolicy policy;
1198 string placement_rule;
1199 boost::optional<ceph::real_time> delete_at;
1200 const char *dlo_manifest;
1201
1202public:
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
1223class RGWDeleteObj : public RGWOp {
1224protected:
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
1232public:
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
1253class RGWCopyObj : public RGWOp {
1254protected:
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
1294public:
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
1337class RGWGetACLs : public RGWOp {
1338protected:
1339 string acls;
1340
1341public:
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
1354class RGWPutACLs : public RGWOp {
1355protected:
1356 int len;
1357 char *data;
1358 ACLOwner owner;
1359
1360public:
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
1381class RGWGetLC : public RGWOp {
1382protected:
1383
1384public:
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"; }
d2e6a577 1394 RGWOpType get_type() override { return RGW_OP_GET_LC; }
7c673cae
FG
1395 uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
1396};
1397
1398class RGWPutLC : public RGWOp {
1399protected:
1400 int len;
1401 char *data;
1402 string cookie;
1403
1404public:
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"; }
d2e6a577 1430 RGWOpType get_type() override { return RGW_OP_PUT_LC; }
7c673cae
FG
1431 uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
1432};
1433
1434class RGWDeleteLC : public RGWOp {
1435protected:
1436 size_t len;
1437 char *data;
1438
1439public:
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"; }
d2e6a577 1454 RGWOpType get_type() override { return RGW_OP_DELETE_LC; }
7c673cae
FG
1455 uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
1456};
1457
1458class RGWGetCORS : public RGWOp {
1459protected:
1460
1461public:
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
1473class RGWPutCORS : public RGWOp {
1474protected:
1475 bufferlist cors_bl;
31f18b77 1476 bufferlist in_data;
7c673cae
FG
1477
1478public:
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
1492class RGWDeleteCORS : public RGWOp {
1493protected:
1494
1495public:
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
1507class RGWOptionsCORS : public RGWOp {
1508protected:
1509 RGWCORSRule *rule;
1510 const char *origin, *req_hdrs, *req_meth;
1511
1512public:
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
1527class RGWGetRequestPayment : public RGWOp {
1528protected:
1529 bool requester_pays;
1530
1531public:
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
1544class RGWSetRequestPayment : public RGWOp {
1545protected:
1546 bool requester_pays;
1547public:
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
1562class RGWInitMultipart : public RGWOp {
1563protected:
1564 string upload_id;
1565 RGWAccessControlPolicy policy;
1566
1567public:
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
1586class RGWCompleteMultipart : public RGWOp {
1587protected:
1588 string upload_id;
1589 string etag;
1590 char *data;
1591 int len;
1592
1593public:
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
1613class RGWAbortMultipart : public RGWOp {
1614public:
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
1627class RGWListMultipart : public RGWOp {
1628protected:
1629 string upload_id;
1630 map<uint32_t, RGWUploadPartInfo> parts;
1631 int max_parts;
1632 int marker;
1633 RGWAccessControlPolicy policy;
1634 bool truncated;
1635
1636public:
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
1658struct RGWMultipartUploadEntry {
1659 rgw_bucket_dir_entry obj;
1660 RGWMPObj mp;
1661};
1662
1663class RGWListBucketMultiparts : public RGWOp {
1664protected:
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
1675public:
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
1699class RGWGetCrossDomainPolicy : public RGWOp {
1700public:
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
1726class RGWGetHealthCheck : public RGWOp {
1727public:
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
1751class RGWDeleteMultiObj : public RGWOp {
1752protected:
1753 int max_to_delete;
1754 int len;
1755 char *data;
1756 rgw_bucket bucket;
1757 bool quiet;
1758 bool status_dumped;
31f18b77 1759 bool acl_allowed = false;
7c673cae
FG
1760
1761public:
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
1784class RGWInfo: public RGWOp {
1785public:
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
1795extern int rgw_build_bucket_policies(RGWRados* store, struct req_state* s);
1796extern int rgw_build_object_policies(RGWRados *store, struct req_state *s,
31f18b77
FG
1797 bool prefetch_data);
1798extern rgw::IAM::Environment rgw_build_iam_environment(RGWRados* store,
1799 struct req_state* s);
7c673cae
FG
1800
1801static 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
1834static 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
1862static 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 */
1890static 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
1922static 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
224ce89b
WB
1934static 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
7c673cae
FG
1948static 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
1964static 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
1976class RGWSetAttrs : public RGWOp {
1977protected:
1978 map<string, buffer::list> attrs;
1979
1980public:
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
1999class RGWGetObjLayout : public RGWOp {
2000protected:
2001 RGWObjManifest *manifest{nullptr};
2002 rgw_raw_obj head_obj;
2003
2004public:
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
31f18b77
FG
2023class RGWPutBucketPolicy : public RGWOp {
2024 int len;
2025 char *data = nullptr;
2026public:
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};
7c673cae 2047
31f18b77
FG
2048class RGWGetBucketPolicy : public RGWOp {
2049 buffer::list policy;
2050public:
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
2066class RGWDeleteBucketPolicy : public RGWOp {
2067public:
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
2085class RGWConfigBucketMetaSearch : public RGWOp {
2086protected:
2087 std::map<std::string, uint32_t> mdsearch_config;
2088public:
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
2102class RGWGetBucketMetaSearch : public RGWOp {
2103public:
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
2116class RGWDelBucketMetaSearch : public RGWOp {
2117public:
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};
7c673cae
FG
2129
2130#endif /* CEPH_RGW_OP_H */