]> git.proxmox.com Git - ceph.git/blob - ceph/src/rgw/rgw_rest_swift.h
import quincy 17.2.0
[ceph.git] / ceph / src / rgw / rgw_rest_swift.h
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab ft=cpp
3
4 #pragma once
5 #define TIME_BUF_SIZE 128
6
7 #include <string_view>
8
9 #include <boost/optional.hpp>
10 #include <boost/utility/typed_in_place_factory.hpp>
11
12 #include "rgw_op.h"
13 #include "rgw_rest.h"
14 #include "rgw_swift_auth.h"
15 #include "rgw_http_errors.h"
16
17
18 class RGWGetObj_ObjStore_SWIFT : public RGWGetObj_ObjStore {
19 int custom_http_ret = 0;
20 public:
21 RGWGetObj_ObjStore_SWIFT() {}
22 ~RGWGetObj_ObjStore_SWIFT() override {}
23
24 int verify_permission(optional_yield y) override;
25 int get_params(optional_yield y) override;
26 int send_response_data_error(optional_yield y) override;
27 int send_response_data(bufferlist& bl, off_t ofs, off_t len) override;
28
29 void set_custom_http_response(const int http_ret) {
30 custom_http_ret = http_ret;
31 }
32
33 bool need_object_expiration() override {
34 return true;
35 }
36 };
37
38 class RGWListBuckets_ObjStore_SWIFT : public RGWListBuckets_ObjStore {
39 bool need_stats;
40 bool wants_reversed;
41 std::string prefix;
42 std::vector<rgw::sal::BucketList> reverse_buffer;
43
44 uint64_t get_default_max() const override {
45 return 0;
46 }
47
48 public:
49 RGWListBuckets_ObjStore_SWIFT()
50 : need_stats(true),
51 wants_reversed(false) {
52 }
53 ~RGWListBuckets_ObjStore_SWIFT() override {}
54
55 int get_params(optional_yield y) override;
56 void handle_listing_chunk(rgw::sal::BucketList&& buckets) override;
57 void send_response_begin(bool has_buckets) override;
58 void send_response_data(rgw::sal::BucketList& buckets) override;
59 void send_response_data_reversed(rgw::sal::BucketList& buckets);
60 void dump_bucket_entry(const rgw::sal::Bucket& obj);
61 void send_response_end() override;
62
63 bool should_get_stats() override { return need_stats; }
64 bool supports_account_metadata() override { return true; }
65 };
66
67 class RGWListBucket_ObjStore_SWIFT : public RGWListBucket_ObjStore {
68 std::string path;
69 public:
70 RGWListBucket_ObjStore_SWIFT() {
71 default_max = 10000;
72 }
73 ~RGWListBucket_ObjStore_SWIFT() override {}
74
75 int get_params(optional_yield y) override;
76 void send_response() override;
77 bool need_container_stats() override { return true; }
78 };
79
80 class RGWStatAccount_ObjStore_SWIFT : public RGWStatAccount_ObjStore {
81 std::map<std::string, bufferlist> attrs;
82 public:
83 RGWStatAccount_ObjStore_SWIFT() {
84 }
85 ~RGWStatAccount_ObjStore_SWIFT() override {}
86
87 void execute(optional_yield y) override;
88 void send_response() override;
89 };
90
91 class RGWStatBucket_ObjStore_SWIFT : public RGWStatBucket_ObjStore {
92 public:
93 RGWStatBucket_ObjStore_SWIFT() {}
94 ~RGWStatBucket_ObjStore_SWIFT() override {}
95
96 void send_response() override;
97 };
98
99 class RGWCreateBucket_ObjStore_SWIFT : public RGWCreateBucket_ObjStore {
100 protected:
101 bool need_metadata_upload() const override { return true; }
102 public:
103 RGWCreateBucket_ObjStore_SWIFT() {}
104 ~RGWCreateBucket_ObjStore_SWIFT() override {}
105
106 int get_params(optional_yield y) override;
107 void send_response() override;
108 };
109
110 class RGWDeleteBucket_ObjStore_SWIFT : public RGWDeleteBucket_ObjStore {
111 public:
112 RGWDeleteBucket_ObjStore_SWIFT() {}
113 ~RGWDeleteBucket_ObjStore_SWIFT() override {}
114
115 void send_response() override;
116 };
117
118 class RGWPutObj_ObjStore_SWIFT : public RGWPutObj_ObjStore {
119 std::string lo_etag;
120 public:
121 RGWPutObj_ObjStore_SWIFT() {}
122 ~RGWPutObj_ObjStore_SWIFT() override {}
123
124 int update_slo_segment_size(rgw_slo_entry& entry);
125
126 int verify_permission(optional_yield y) override;
127 int get_params(optional_yield y) override;
128 void send_response() override;
129 };
130
131 class RGWPutMetadataAccount_ObjStore_SWIFT : public RGWPutMetadataAccount_ObjStore {
132 public:
133 RGWPutMetadataAccount_ObjStore_SWIFT() {}
134 ~RGWPutMetadataAccount_ObjStore_SWIFT() override {}
135
136 int get_params(optional_yield y) override;
137 void send_response() override;
138 };
139
140 class RGWPutMetadataBucket_ObjStore_SWIFT : public RGWPutMetadataBucket_ObjStore {
141 public:
142 RGWPutMetadataBucket_ObjStore_SWIFT() {}
143 ~RGWPutMetadataBucket_ObjStore_SWIFT() override {}
144
145 int get_params(optional_yield y) override;
146 void send_response() override;
147 };
148
149 class RGWPutMetadataObject_ObjStore_SWIFT : public RGWPutMetadataObject_ObjStore {
150 public:
151 RGWPutMetadataObject_ObjStore_SWIFT() {}
152 ~RGWPutMetadataObject_ObjStore_SWIFT() override {}
153
154 int get_params(optional_yield y) override;
155 void send_response() override;
156 bool need_object_expiration() override { return true; }
157 };
158
159 class RGWDeleteObj_ObjStore_SWIFT : public RGWDeleteObj_ObjStore {
160 public:
161 RGWDeleteObj_ObjStore_SWIFT() {}
162 ~RGWDeleteObj_ObjStore_SWIFT() override {}
163
164 int verify_permission(optional_yield y) override;
165 int get_params(optional_yield y) override;
166 bool need_object_expiration() override { return true; }
167 void send_response() override;
168 };
169
170 class RGWCopyObj_ObjStore_SWIFT : public RGWCopyObj_ObjStore {
171 bool sent_header;
172 protected:
173 void dump_copy_info();
174 public:
175 RGWCopyObj_ObjStore_SWIFT() : sent_header(false) {}
176 ~RGWCopyObj_ObjStore_SWIFT() override {}
177
178 int init_dest_policy() override;
179 int get_params(optional_yield y) override;
180 void send_response() override;
181 void send_partial_response(off_t ofs) override;
182 };
183
184 class RGWGetACLs_ObjStore_SWIFT : public RGWGetACLs_ObjStore {
185 public:
186 RGWGetACLs_ObjStore_SWIFT() {}
187 ~RGWGetACLs_ObjStore_SWIFT() override {}
188
189 void send_response() override {}
190 };
191
192 class RGWPutACLs_ObjStore_SWIFT : public RGWPutACLs_ObjStore {
193 public:
194 RGWPutACLs_ObjStore_SWIFT() : RGWPutACLs_ObjStore() {}
195 ~RGWPutACLs_ObjStore_SWIFT() override {}
196
197 void send_response() override {}
198 };
199
200 class RGWOptionsCORS_ObjStore_SWIFT : public RGWOptionsCORS_ObjStore {
201 public:
202 RGWOptionsCORS_ObjStore_SWIFT() {}
203 ~RGWOptionsCORS_ObjStore_SWIFT() override {}
204
205 void send_response() override;
206 };
207
208 class RGWBulkDelete_ObjStore_SWIFT : public RGWBulkDelete_ObjStore {
209 public:
210 RGWBulkDelete_ObjStore_SWIFT() {}
211 ~RGWBulkDelete_ObjStore_SWIFT() override {}
212
213 int get_data(std::list<RGWBulkDelete::acct_path_t>& items,
214 bool * is_truncated) override;
215 void send_response() override;
216 };
217
218 class RGWBulkUploadOp_ObjStore_SWIFT : public RGWBulkUploadOp_ObjStore {
219 size_t conlen;
220 size_t curpos;
221
222 public:
223 RGWBulkUploadOp_ObjStore_SWIFT()
224 : conlen(0),
225 curpos(0) {
226 }
227 ~RGWBulkUploadOp_ObjStore_SWIFT() = default;
228
229 std::unique_ptr<StreamGetter> create_stream() override;
230 void send_response() override;
231 };
232
233 class RGWInfo_ObjStore_SWIFT : public RGWInfo_ObjStore {
234 protected:
235 struct info
236 {
237 bool is_admin_info;
238 std::function<void (Formatter&, const ConfigProxy&, rgw::sal::Store*)> list_data;
239 };
240
241 static const std::vector<std::pair<std::string, struct info>> swift_info;
242 public:
243 RGWInfo_ObjStore_SWIFT() {}
244 ~RGWInfo_ObjStore_SWIFT() override {}
245
246 void execute(optional_yield y) override;
247 void send_response() override;
248 static void list_swift_data(Formatter& formatter, const ConfigProxy& config, rgw::sal::Store* store);
249 static void list_tempauth_data(Formatter& formatter, const ConfigProxy& config, rgw::sal::Store* store);
250 static void list_tempurl_data(Formatter& formatter, const ConfigProxy& config, rgw::sal::Store* store);
251 static void list_slo_data(Formatter& formatter, const ConfigProxy& config, rgw::sal::Store* store);
252 static bool is_expired(const std::string& expires, const DoutPrefixProvider* dpp);
253 };
254
255
256 class RGWFormPost : public RGWPostObj_ObjStore {
257 std::string get_current_filename() const override;
258 std::string get_current_content_type() const override;
259 std::size_t get_max_file_size() /*const*/;
260 bool is_next_file_to_upload() override;
261 bool is_integral();
262 bool is_non_expired();
263 void get_owner_info(const req_state* s,
264 RGWUserInfo& owner_info) const;
265
266 parts_collection_t ctrl_parts;
267 boost::optional<post_form_part> current_data_part;
268 std::string prefix;
269 bool stream_done = false;
270
271 class SignatureHelper;
272 public:
273 RGWFormPost() = default;
274 ~RGWFormPost() = default;
275
276 void init(rgw::sal::Store* store,
277 req_state* s,
278 RGWHandler* dialect_handler) override;
279
280 int get_params(optional_yield y) override;
281 int get_data(ceph::bufferlist& bl, bool& again) override;
282 void send_response() override;
283
284 static bool is_formpost_req(req_state* const s);
285 };
286
287 class RGWFormPost::SignatureHelper
288 {
289 private:
290 static constexpr uint32_t output_size =
291 CEPH_CRYPTO_HMACSHA1_DIGESTSIZE * 2 + 1;
292
293 unsigned char dest[CEPH_CRYPTO_HMACSHA1_DIGESTSIZE]; // 20
294 char dest_str[output_size];
295
296 public:
297 SignatureHelper() = default;
298
299 const char* calc(const std::string& key,
300 const std::string_view& path_info,
301 const std::string_view& redirect,
302 const std::string_view& max_file_size,
303 const std::string_view& max_file_count,
304 const std::string_view& expires) {
305 using ceph::crypto::HMACSHA1;
306 using UCHARPTR = const unsigned char*;
307
308 HMACSHA1 hmac((UCHARPTR) key.data(), key.size());
309
310 hmac.Update((UCHARPTR) path_info.data(), path_info.size());
311 hmac.Update((UCHARPTR) "\n", 1);
312
313 hmac.Update((UCHARPTR) redirect.data(), redirect.size());
314 hmac.Update((UCHARPTR) "\n", 1);
315
316 hmac.Update((UCHARPTR) max_file_size.data(), max_file_size.size());
317 hmac.Update((UCHARPTR) "\n", 1);
318
319 hmac.Update((UCHARPTR) max_file_count.data(), max_file_count.size());
320 hmac.Update((UCHARPTR) "\n", 1);
321
322 hmac.Update((UCHARPTR) expires.data(), expires.size());
323
324 hmac.Final(dest);
325
326 buf_to_hex((UCHARPTR) dest, sizeof(dest), dest_str);
327
328 return dest_str;
329 }
330
331 const char* get_signature() const {
332 return dest_str;
333 }
334
335 bool is_equal_to(const std::string& rhs) const {
336 /* never allow out-of-range exception */
337 if (rhs.size() < (output_size - 1)) {
338 return false;
339 }
340 return rhs.compare(0 /* pos */, output_size, dest_str) == 0;
341 }
342
343 }; /* RGWFormPost::SignatureHelper */
344
345
346 class RGWSwiftWebsiteHandler {
347 rgw::sal::Store* const store;
348 req_state* const s;
349 RGWHandler_REST* const handler;
350
351 bool is_web_mode() const;
352 bool can_be_website_req() const;
353 bool is_web_dir() const;
354 bool is_index_present(const std::string& index) const;
355
356 int serve_errordoc(int http_ret, std::string error_doc, optional_yield y);
357
358 RGWOp* get_ws_redirect_op();
359 RGWOp* get_ws_index_op();
360 RGWOp* get_ws_listing_op();
361 public:
362 RGWSwiftWebsiteHandler(rgw::sal::Store* const store,
363 req_state* const s,
364 RGWHandler_REST* const handler)
365 : store(store),
366 s(s),
367 handler(handler) {
368 }
369
370 int error_handler(const int err_no,
371 std::string* const error_content,
372 optional_yield y);
373 int retarget_bucket(RGWOp* op, RGWOp** new_op);
374 int retarget_object(RGWOp* op, RGWOp** new_op);
375 };
376
377
378 class RGWHandler_REST_SWIFT : public RGWHandler_REST {
379 friend class RGWRESTMgr_SWIFT;
380 friend class RGWRESTMgr_SWIFT_Info;
381 protected:
382 const rgw::auth::Strategy& auth_strategy;
383
384 virtual bool is_acl_op() const {
385 return false;
386 }
387
388 static int init_from_header(rgw::sal::Store* store, struct req_state* s,
389 const std::string& frontend_prefix);
390 public:
391 explicit RGWHandler_REST_SWIFT(const rgw::auth::Strategy& auth_strategy)
392 : auth_strategy(auth_strategy) {
393 }
394 ~RGWHandler_REST_SWIFT() override = default;
395
396 int validate_bucket_name(const std::string& bucket);
397
398 int init(rgw::sal::Store* store, struct req_state *s, rgw::io::BasicClient *cio) override;
399 int authorize(const DoutPrefixProvider *dpp, optional_yield y) override;
400 int postauth_init(optional_yield y) override;
401
402 RGWAccessControlPolicy *alloc_policy() { return nullptr; /* return new RGWAccessControlPolicy_SWIFT; */ }
403 void free_policy(RGWAccessControlPolicy *policy) { delete policy; }
404 };
405
406 class RGWHandler_REST_Service_SWIFT : public RGWHandler_REST_SWIFT {
407 protected:
408 RGWOp *op_get() override;
409 RGWOp *op_head() override;
410 RGWOp *op_put() override;
411 RGWOp *op_post() override;
412 RGWOp *op_delete() override;
413 public:
414 using RGWHandler_REST_SWIFT::RGWHandler_REST_SWIFT;
415 ~RGWHandler_REST_Service_SWIFT() override = default;
416 };
417
418 class RGWHandler_REST_Bucket_SWIFT : public RGWHandler_REST_SWIFT {
419 /* We need the boost::optional here only because of handler's late
420 * initialization (see the init() method). */
421 boost::optional<RGWSwiftWebsiteHandler> website_handler;
422 protected:
423 bool is_obj_update_op() const override {
424 return s->op == OP_POST;
425 }
426
427 RGWOp *get_obj_op(bool get_data);
428 RGWOp *op_get() override;
429 RGWOp *op_head() override;
430 RGWOp *op_put() override;
431 RGWOp *op_delete() override;
432 RGWOp *op_post() override;
433 RGWOp *op_options() override;
434 public:
435 using RGWHandler_REST_SWIFT::RGWHandler_REST_SWIFT;
436 ~RGWHandler_REST_Bucket_SWIFT() override = default;
437
438 int error_handler(int err_no, std::string *error_content, optional_yield y) override {
439 return website_handler->error_handler(err_no, error_content, y);
440 }
441
442 int retarget(RGWOp* op, RGWOp** new_op, optional_yield) override {
443 return website_handler->retarget_bucket(op, new_op);
444 }
445
446 int init(rgw::sal::Store* const store,
447 struct req_state* const s,
448 rgw::io::BasicClient* const cio) override {
449 website_handler = boost::in_place<RGWSwiftWebsiteHandler>(store, s, this);
450 return RGWHandler_REST_SWIFT::init(store, s, cio);
451 }
452 };
453
454 class RGWHandler_REST_Obj_SWIFT : public RGWHandler_REST_SWIFT {
455 /* We need the boost::optional here only because of handler's late
456 * initialization (see the init() method). */
457 boost::optional<RGWSwiftWebsiteHandler> website_handler;
458 protected:
459 bool is_obj_update_op() const override {
460 return s->op == OP_POST;
461 }
462
463 RGWOp *get_obj_op(bool get_data);
464 RGWOp *op_get() override;
465 RGWOp *op_head() override;
466 RGWOp *op_put() override;
467 RGWOp *op_delete() override;
468 RGWOp *op_post() override;
469 RGWOp *op_copy() override;
470 RGWOp *op_options() override;
471
472 public:
473 using RGWHandler_REST_SWIFT::RGWHandler_REST_SWIFT;
474 ~RGWHandler_REST_Obj_SWIFT() override = default;
475
476 int error_handler(int err_no, std::string *error_content,
477 optional_yield y) override {
478 return website_handler->error_handler(err_no, error_content, y);
479 }
480
481 int retarget(RGWOp* op, RGWOp** new_op, optional_yield) override {
482 return website_handler->retarget_object(op, new_op);
483 }
484
485 int init(rgw::sal::Store* const store,
486 struct req_state* const s,
487 rgw::io::BasicClient* const cio) override {
488 website_handler = boost::in_place<RGWSwiftWebsiteHandler>(store, s, this);
489 return RGWHandler_REST_SWIFT::init(store, s, cio);
490 }
491 };
492
493 class RGWRESTMgr_SWIFT : public RGWRESTMgr {
494 protected:
495 RGWRESTMgr* get_resource_mgr_as_default(struct req_state* const s,
496 const std::string& uri,
497 std::string* const out_uri) override {
498 return this->get_resource_mgr(s, uri, out_uri);
499 }
500
501 public:
502 RGWRESTMgr_SWIFT() = default;
503 ~RGWRESTMgr_SWIFT() override = default;
504
505 RGWHandler_REST *get_handler(rgw::sal::Store* store,
506 struct req_state *s,
507 const rgw::auth::StrategyRegistry& auth_registry,
508 const std::string& frontend_prefix) override;
509 };
510
511
512 class RGWGetCrossDomainPolicy_ObjStore_SWIFT
513 : public RGWGetCrossDomainPolicy_ObjStore {
514 public:
515 RGWGetCrossDomainPolicy_ObjStore_SWIFT() = default;
516 ~RGWGetCrossDomainPolicy_ObjStore_SWIFT() override = default;
517
518 void send_response() override;
519 };
520
521 class RGWGetHealthCheck_ObjStore_SWIFT
522 : public RGWGetHealthCheck_ObjStore {
523 public:
524 RGWGetHealthCheck_ObjStore_SWIFT() = default;
525 ~RGWGetHealthCheck_ObjStore_SWIFT() override = default;
526
527 void send_response() override;
528 };
529
530 class RGWHandler_SWIFT_CrossDomain : public RGWHandler_REST {
531 public:
532 RGWHandler_SWIFT_CrossDomain() = default;
533 ~RGWHandler_SWIFT_CrossDomain() override = default;
534
535 RGWOp *op_get() override {
536 return new RGWGetCrossDomainPolicy_ObjStore_SWIFT();
537 }
538
539 int init(rgw::sal::Store* const store,
540 struct req_state* const state,
541 rgw::io::BasicClient* const cio) override {
542 state->dialect = "swift";
543 state->formatter = new JSONFormatter;
544 state->format = RGW_FORMAT_JSON;
545
546 return RGWHandler::init(store, state, cio);
547 }
548
549 int authorize(const DoutPrefixProvider *dpp, optional_yield) override {
550 return 0;
551 }
552
553 int postauth_init(optional_yield) override {
554 return 0;
555 }
556
557 int read_permissions(RGWOp *, optional_yield y) override {
558 return 0;
559 }
560
561 virtual RGWAccessControlPolicy *alloc_policy() { return nullptr; }
562 virtual void free_policy(RGWAccessControlPolicy *policy) {}
563 };
564
565 class RGWRESTMgr_SWIFT_CrossDomain : public RGWRESTMgr {
566 protected:
567 RGWRESTMgr *get_resource_mgr(struct req_state* const s,
568 const std::string& uri,
569 std::string* const out_uri) override {
570 return this;
571 }
572
573 public:
574 RGWRESTMgr_SWIFT_CrossDomain() = default;
575 ~RGWRESTMgr_SWIFT_CrossDomain() override = default;
576
577 RGWHandler_REST* get_handler(rgw::sal::Store* store,
578 struct req_state* const s,
579 const rgw::auth::StrategyRegistry&,
580 const std::string&) override {
581 s->prot_flags |= RGW_REST_SWIFT;
582 return new RGWHandler_SWIFT_CrossDomain;
583 }
584 };
585
586
587 class RGWHandler_SWIFT_HealthCheck : public RGWHandler_REST {
588 public:
589 RGWHandler_SWIFT_HealthCheck() = default;
590 ~RGWHandler_SWIFT_HealthCheck() override = default;
591
592 RGWOp *op_get() override {
593 return new RGWGetHealthCheck_ObjStore_SWIFT();
594 }
595
596 int init(rgw::sal::Store* const store,
597 struct req_state* const state,
598 rgw::io::BasicClient* const cio) override {
599 state->dialect = "swift";
600 state->formatter = new JSONFormatter;
601 state->format = RGW_FORMAT_JSON;
602
603 return RGWHandler::init(store, state, cio);
604 }
605
606 int authorize(const DoutPrefixProvider *dpp, optional_yield y) override {
607 return 0;
608 }
609
610 int postauth_init(optional_yield) override {
611 return 0;
612 }
613
614 int read_permissions(RGWOp *, optional_yield y) override {
615 return 0;
616 }
617
618 virtual RGWAccessControlPolicy *alloc_policy() { return nullptr; }
619 virtual void free_policy(RGWAccessControlPolicy *policy) {}
620 };
621
622 class RGWRESTMgr_SWIFT_HealthCheck : public RGWRESTMgr {
623 protected:
624 RGWRESTMgr *get_resource_mgr(struct req_state* const s,
625 const std::string& uri,
626 std::string* const out_uri) override {
627 return this;
628 }
629
630 public:
631 RGWRESTMgr_SWIFT_HealthCheck() = default;
632 ~RGWRESTMgr_SWIFT_HealthCheck() override = default;
633
634 RGWHandler_REST* get_handler(rgw::sal::Store* store,
635 struct req_state* const s,
636 const rgw::auth::StrategyRegistry&,
637 const std::string&) override {
638 s->prot_flags |= RGW_REST_SWIFT;
639 return new RGWHandler_SWIFT_HealthCheck;
640 }
641 };
642
643
644 class RGWHandler_REST_SWIFT_Info : public RGWHandler_REST_SWIFT {
645 public:
646 using RGWHandler_REST_SWIFT::RGWHandler_REST_SWIFT;
647 ~RGWHandler_REST_SWIFT_Info() override = default;
648
649 RGWOp *op_get() override {
650 return new RGWInfo_ObjStore_SWIFT();
651 }
652
653 int init(rgw::sal::Store* const store,
654 struct req_state* const state,
655 rgw::io::BasicClient* const cio) override {
656 state->dialect = "swift";
657 state->formatter = new JSONFormatter;
658 state->format = RGW_FORMAT_JSON;
659
660 return RGWHandler::init(store, state, cio);
661 }
662
663 int authorize(const DoutPrefixProvider *dpp, optional_yield) override {
664 return 0;
665 }
666
667 int postauth_init(optional_yield) override {
668 return 0;
669 }
670
671 int read_permissions(RGWOp *, optional_yield y) override {
672 return 0;
673 }
674 };
675
676 class RGWRESTMgr_SWIFT_Info : public RGWRESTMgr {
677 public:
678 RGWRESTMgr_SWIFT_Info() = default;
679 ~RGWRESTMgr_SWIFT_Info() override = default;
680
681 RGWHandler_REST *get_handler(rgw::sal::Store* store,
682 struct req_state* s,
683 const rgw::auth::StrategyRegistry& auth_registry,
684 const std::string& frontend_prefix) override;
685 };