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