]> git.proxmox.com Git - ceph.git/blob - ceph/src/rgw/rgw_rest.h
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / rgw / rgw_rest.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
6 #define TIME_BUF_SIZE 128
7
8 #include <string_view>
9 #include <boost/container/flat_set.hpp>
10 #include "common/sstring.hh"
11 #include "common/ceph_json.h"
12 #include "include/ceph_assert.h" /* needed because of common/ceph_json.h */
13 #include "rgw_op.h"
14 #include "rgw_formats.h"
15 #include "rgw_client_io.h"
16
17 extern std::map<std::string, std::string> rgw_to_http_attrs;
18
19 extern void rgw_rest_init(CephContext *cct, const RGWZoneGroup& zone_group);
20
21 extern void rgw_flush_formatter_and_reset(struct req_state *s,
22 ceph::Formatter *formatter);
23
24 extern void rgw_flush_formatter(struct req_state *s,
25 ceph::Formatter *formatter);
26
27 std::tuple<int, bufferlist > rgw_rest_read_all_input(struct req_state *s,
28 const uint64_t max_len,
29 const bool allow_chunked=true);
30
31 inline std::string_view rgw_sanitized_hdrval(ceph::buffer::list& raw)
32 {
33 /* std::string and thus std::string_view ARE OBLIGED to carry multiple
34 * 0x00 and count them to the length of a string. We need to take that
35 * into consideration and sanitize the size of a ceph::buffer::list used
36 * to store metadata values (x-amz-meta-*, X-Container-Meta-*, etags).
37 * Otherwise we might send 0x00 to clients. */
38 const char* const data = raw.c_str();
39 size_t len = raw.length();
40
41 if (len && data[len - 1] == '\0') {
42 /* That's the case - the null byte has been included at the last position
43 * of the bufferlist. We need to restore the proper string length we'll
44 * pass to string_ref. */
45 len--;
46 }
47
48 return std::string_view(data, len);
49 }
50
51 template <class T>
52 int rgw_rest_get_json_input(CephContext *cct, req_state *s, T& out,
53 uint64_t max_len, bool *empty)
54 {
55 if (empty)
56 *empty = false;
57
58 int rv = 0;
59 bufferlist data;
60 std::tie(rv, data) = rgw_rest_read_all_input(s, max_len);
61 if (rv < 0) {
62 return rv;
63 }
64
65 if (!data.length()) {
66 if (empty) {
67 *empty = true;
68 }
69
70 return -EINVAL;
71 }
72
73 JSONParser parser;
74
75 if (!parser.parse(data.c_str(), data.length())) {
76 return -EINVAL;
77 }
78
79 try {
80 decode_json_obj(out, &parser);
81 } catch (JSONDecoder::err& e) {
82 return -EINVAL;
83 }
84
85 return 0;
86 }
87
88 template <class T>
89 std::tuple<int, bufferlist > rgw_rest_get_json_input_keep_data(CephContext *cct, req_state *s, T& out, uint64_t max_len)
90 {
91 int rv = 0;
92 bufferlist data;
93 std::tie(rv, data) = rgw_rest_read_all_input(s, max_len);
94 if (rv < 0) {
95 return std::make_tuple(rv, std::move(data));
96 }
97
98 if (!data.length()) {
99 return std::make_tuple(-EINVAL, std::move(data));
100 }
101
102 JSONParser parser;
103
104 if (!parser.parse(data.c_str(), data.length())) {
105 return std::make_tuple(-EINVAL, std::move(data));
106 }
107
108 try {
109 decode_json_obj(out, &parser);
110 } catch (JSONDecoder::err& e) {
111 return std::make_tuple(-EINVAL, std::move(data));
112 }
113
114 return std::make_tuple(0, std::move(data));
115 }
116
117 class RESTArgs {
118 public:
119 static int get_string(struct req_state *s, const string& name,
120 const string& def_val, string *val,
121 bool *existed = NULL);
122 static int get_uint64(struct req_state *s, const string& name,
123 uint64_t def_val, uint64_t *val, bool *existed = NULL);
124 static int get_int64(struct req_state *s, const string& name,
125 int64_t def_val, int64_t *val, bool *existed = NULL);
126 static int get_uint32(struct req_state *s, const string& name,
127 uint32_t def_val, uint32_t *val, bool *existed = NULL);
128 static int get_int32(struct req_state *s, const string& name,
129 int32_t def_val, int32_t *val, bool *existed = NULL);
130 static int get_time(struct req_state *s, const string& name,
131 const utime_t& def_val, utime_t *val,
132 bool *existed = NULL);
133 static int get_epoch(struct req_state *s, const string& name,
134 uint64_t def_val, uint64_t *epoch,
135 bool *existed = NULL);
136 static int get_bool(struct req_state *s, const string& name, bool def_val,
137 bool *val, bool *existed = NULL);
138 };
139
140 class RGWRESTFlusher : public RGWFormatterFlusher {
141 struct req_state *s;
142 RGWOp *op;
143 protected:
144 void do_flush() override;
145 void do_start(int ret) override;
146 public:
147 RGWRESTFlusher(struct req_state *_s, RGWOp *_op) :
148 RGWFormatterFlusher(_s->formatter), s(_s), op(_op) {}
149 RGWRESTFlusher() : RGWFormatterFlusher(NULL), s(NULL), op(NULL) {}
150
151 void init(struct req_state *_s, RGWOp *_op) {
152 s = _s;
153 op = _op;
154 set_formatter(s->formatter);
155 }
156 };
157
158 class RGWGetObj_ObjStore : public RGWGetObj
159 {
160 protected:
161 bool sent_header;
162 public:
163 RGWGetObj_ObjStore() : sent_header(false) {}
164
165 void init(rgw::sal::RGWRadosStore *store, struct req_state *s, RGWHandler *h) override {
166 RGWGetObj::init(store, s, h);
167 sent_header = false;
168 }
169
170 int get_params(optional_yield y) override;
171 };
172
173 class RGWGetObjTags_ObjStore : public RGWGetObjTags {
174 public:
175 RGWGetObjTags_ObjStore() {};
176 ~RGWGetObjTags_ObjStore() {};
177 };
178
179 class RGWPutObjTags_ObjStore: public RGWPutObjTags {
180 public:
181 RGWPutObjTags_ObjStore() {};
182 ~RGWPutObjTags_ObjStore() {};
183 };
184
185 class RGWGetBucketTags_ObjStore : public RGWGetBucketTags {
186 public:
187 RGWGetBucketTags_ObjStore() = default;
188 virtual ~RGWGetBucketTags_ObjStore() = default;
189 };
190
191 class RGWPutBucketTags_ObjStore: public RGWPutBucketTags {
192 public:
193 RGWPutBucketTags_ObjStore() = default;
194 virtual ~RGWPutBucketTags_ObjStore() = default;
195 };
196
197 class RGWGetBucketReplication_ObjStore : public RGWGetBucketReplication {
198 public:
199 RGWGetBucketReplication_ObjStore() {};
200 ~RGWGetBucketReplication_ObjStore() {};
201 };
202
203 class RGWPutBucketReplication_ObjStore: public RGWPutBucketReplication {
204 public:
205 RGWPutBucketReplication_ObjStore() = default;
206 virtual ~RGWPutBucketReplication_ObjStore() = default;
207 };
208
209 class RGWDeleteBucketReplication_ObjStore: public RGWDeleteBucketReplication {
210 public:
211 RGWDeleteBucketReplication_ObjStore() = default;
212 virtual ~RGWDeleteBucketReplication_ObjStore() = default;
213 };
214
215 class RGWListBuckets_ObjStore : public RGWListBuckets {
216 public:
217 RGWListBuckets_ObjStore() {}
218 ~RGWListBuckets_ObjStore() override {}
219 };
220
221 class RGWGetUsage_ObjStore : public RGWGetUsage {
222 public:
223 RGWGetUsage_ObjStore() {}
224 ~RGWGetUsage_ObjStore() override {}
225 };
226
227 class RGWListBucket_ObjStore : public RGWListBucket {
228 public:
229 RGWListBucket_ObjStore() {}
230 ~RGWListBucket_ObjStore() override {}
231 };
232
233 class RGWStatAccount_ObjStore : public RGWStatAccount {
234 public:
235 RGWStatAccount_ObjStore() {}
236 ~RGWStatAccount_ObjStore() override {}
237 };
238
239 class RGWStatBucket_ObjStore : public RGWStatBucket {
240 public:
241 RGWStatBucket_ObjStore() {}
242 ~RGWStatBucket_ObjStore() override {}
243 };
244
245 class RGWCreateBucket_ObjStore : public RGWCreateBucket {
246 public:
247 RGWCreateBucket_ObjStore() {}
248 ~RGWCreateBucket_ObjStore() override {}
249 };
250
251 class RGWDeleteBucket_ObjStore : public RGWDeleteBucket {
252 public:
253 RGWDeleteBucket_ObjStore() {}
254 ~RGWDeleteBucket_ObjStore() override {}
255 };
256
257 class RGWPutObj_ObjStore : public RGWPutObj
258 {
259 public:
260 RGWPutObj_ObjStore() {}
261 ~RGWPutObj_ObjStore() override {}
262
263 int verify_params() override;
264 int get_params(optional_yield y) override;
265 int get_data(bufferlist& bl) override;
266 };
267
268 class RGWPostObj_ObjStore : public RGWPostObj
269 {
270 std::string boundary;
271
272 public:
273 struct post_part_field {
274 std::string val;
275 std::map<std::string, std::string> params;
276 };
277
278 struct post_form_part {
279 std::string name;
280 std::map<std::string, post_part_field, ltstr_nocase> fields;
281 ceph::bufferlist data;
282 };
283
284 protected:
285 using parts_collection_t = \
286 std::map<std::string, post_form_part, const ltstr_nocase>;
287
288 std::string err_msg;
289 ceph::bufferlist in_data;
290
291 int read_with_boundary(ceph::bufferlist& bl,
292 uint64_t max,
293 bool check_eol,
294 bool& reached_boundary,
295 bool& done);
296
297 int read_line(ceph::bufferlist& bl,
298 uint64_t max,
299 bool& reached_boundary,
300 bool& done);
301
302 int read_data(ceph::bufferlist& bl,
303 uint64_t max,
304 bool& reached_boundary,
305 bool& done);
306
307 int read_form_part_header(struct post_form_part *part, bool& done);
308
309 int get_params(optional_yield y) override;
310
311 static int parse_part_field(const std::string& line,
312 std::string& field_name, /* out */
313 post_part_field& field); /* out */
314
315 static void parse_boundary_params(const std::string& params_str,
316 std::string& first,
317 std::map<std::string, std::string>& params);
318
319 static bool part_str(parts_collection_t& parts,
320 const std::string& name,
321 std::string *val);
322
323 static std::string get_part_str(parts_collection_t& parts,
324 const std::string& name,
325 const std::string& def_val = std::string());
326
327 static bool part_bl(parts_collection_t& parts,
328 const std::string& name,
329 ceph::bufferlist *pbl);
330
331 public:
332 RGWPostObj_ObjStore() {}
333 ~RGWPostObj_ObjStore() override {}
334
335 int verify_params() override;
336 };
337
338
339 class RGWPutMetadataAccount_ObjStore : public RGWPutMetadataAccount
340 {
341 public:
342 RGWPutMetadataAccount_ObjStore() {}
343 ~RGWPutMetadataAccount_ObjStore() override {}
344 };
345
346 class RGWPutMetadataBucket_ObjStore : public RGWPutMetadataBucket
347 {
348 public:
349 RGWPutMetadataBucket_ObjStore() {}
350 ~RGWPutMetadataBucket_ObjStore() override {}
351 };
352
353 class RGWPutMetadataObject_ObjStore : public RGWPutMetadataObject
354 {
355 public:
356 RGWPutMetadataObject_ObjStore() {}
357 ~RGWPutMetadataObject_ObjStore() override {}
358 };
359
360 class RGWDeleteObj_ObjStore : public RGWDeleteObj {
361 public:
362 RGWDeleteObj_ObjStore() {}
363 ~RGWDeleteObj_ObjStore() override {}
364 };
365
366 class RGWGetCrossDomainPolicy_ObjStore : public RGWGetCrossDomainPolicy {
367 public:
368 RGWGetCrossDomainPolicy_ObjStore() = default;
369 ~RGWGetCrossDomainPolicy_ObjStore() override = default;
370 };
371
372 class RGWGetHealthCheck_ObjStore : public RGWGetHealthCheck {
373 public:
374 RGWGetHealthCheck_ObjStore() = default;
375 ~RGWGetHealthCheck_ObjStore() override = default;
376 };
377
378 class RGWCopyObj_ObjStore : public RGWCopyObj {
379 public:
380 RGWCopyObj_ObjStore() {}
381 ~RGWCopyObj_ObjStore() override {}
382 };
383
384 class RGWGetACLs_ObjStore : public RGWGetACLs {
385 public:
386 RGWGetACLs_ObjStore() {}
387 ~RGWGetACLs_ObjStore() override {}
388 };
389
390 class RGWPutACLs_ObjStore : public RGWPutACLs {
391 public:
392 RGWPutACLs_ObjStore() {}
393 ~RGWPutACLs_ObjStore() override {}
394
395 int get_params(optional_yield y) override;
396 };
397
398 class RGWGetLC_ObjStore : public RGWGetLC {
399 public:
400 RGWGetLC_ObjStore() {}
401 ~RGWGetLC_ObjStore() override {}
402 };
403
404 class RGWPutLC_ObjStore : public RGWPutLC {
405 public:
406 RGWPutLC_ObjStore() {}
407 ~RGWPutLC_ObjStore() override {}
408
409 int get_params(optional_yield y) override;
410 };
411
412 class RGWDeleteLC_ObjStore : public RGWDeleteLC {
413 public:
414 RGWDeleteLC_ObjStore() {}
415 ~RGWDeleteLC_ObjStore() override {}
416
417 };
418
419 class RGWGetCORS_ObjStore : public RGWGetCORS {
420 public:
421 RGWGetCORS_ObjStore() {}
422 ~RGWGetCORS_ObjStore() override {}
423 };
424
425 class RGWPutCORS_ObjStore : public RGWPutCORS {
426 public:
427 RGWPutCORS_ObjStore() {}
428 ~RGWPutCORS_ObjStore() override {}
429 };
430
431 class RGWDeleteCORS_ObjStore : public RGWDeleteCORS {
432 public:
433 RGWDeleteCORS_ObjStore() {}
434 ~RGWDeleteCORS_ObjStore() override {}
435 };
436
437 class RGWOptionsCORS_ObjStore : public RGWOptionsCORS {
438 public:
439 RGWOptionsCORS_ObjStore() {}
440 ~RGWOptionsCORS_ObjStore() override {}
441 };
442
443 class RGWInitMultipart_ObjStore : public RGWInitMultipart {
444 public:
445 RGWInitMultipart_ObjStore() {}
446 ~RGWInitMultipart_ObjStore() override {}
447 };
448
449 class RGWCompleteMultipart_ObjStore : public RGWCompleteMultipart {
450 public:
451 RGWCompleteMultipart_ObjStore() {}
452 ~RGWCompleteMultipart_ObjStore() override {}
453
454 int get_params(optional_yield y) override;
455 };
456
457 class RGWAbortMultipart_ObjStore : public RGWAbortMultipart {
458 public:
459 RGWAbortMultipart_ObjStore() {}
460 ~RGWAbortMultipart_ObjStore() override {}
461 };
462
463 class RGWListMultipart_ObjStore : public RGWListMultipart {
464 public:
465 RGWListMultipart_ObjStore() {}
466 ~RGWListMultipart_ObjStore() override {}
467
468 int get_params(optional_yield y) override;
469 };
470
471 class RGWListBucketMultiparts_ObjStore : public RGWListBucketMultiparts {
472 public:
473 RGWListBucketMultiparts_ObjStore() {}
474 ~RGWListBucketMultiparts_ObjStore() override {}
475
476 int get_params(optional_yield y) override;
477 };
478
479 class RGWBulkDelete_ObjStore : public RGWBulkDelete {
480 public:
481 RGWBulkDelete_ObjStore() {}
482 ~RGWBulkDelete_ObjStore() override {}
483 };
484
485 class RGWBulkUploadOp_ObjStore : public RGWBulkUploadOp {
486 public:
487 RGWBulkUploadOp_ObjStore() = default;
488 ~RGWBulkUploadOp_ObjStore() = default;
489 };
490
491 class RGWDeleteMultiObj_ObjStore : public RGWDeleteMultiObj {
492 public:
493 RGWDeleteMultiObj_ObjStore() {}
494 ~RGWDeleteMultiObj_ObjStore() override {}
495
496 int get_params(optional_yield y) override;
497 };
498
499 class RGWInfo_ObjStore : public RGWInfo {
500 public:
501 RGWInfo_ObjStore() = default;
502 ~RGWInfo_ObjStore() override = default;
503 };
504
505 class RGWPutBucketObjectLock_ObjStore : public RGWPutBucketObjectLock {
506 public:
507 RGWPutBucketObjectLock_ObjStore() = default;
508 ~RGWPutBucketObjectLock_ObjStore() = default;
509 int get_params(optional_yield y) override;
510 };
511
512 class RGWGetBucketObjectLock_ObjStore : public RGWGetBucketObjectLock {
513 public:
514 RGWGetBucketObjectLock_ObjStore() = default;
515 ~RGWGetBucketObjectLock_ObjStore() override = default;
516 };
517
518 class RGWPutObjRetention_ObjStore : public RGWPutObjRetention {
519 public:
520 RGWPutObjRetention_ObjStore() = default;
521 ~RGWPutObjRetention_ObjStore() override = default;
522 };
523
524 class RGWGetObjRetention_ObjStore : public RGWGetObjRetention {
525 public:
526 RGWGetObjRetention_ObjStore() = default;
527 ~RGWGetObjRetention_ObjStore() = default;
528 };
529
530 class RGWPutObjLegalHold_ObjStore : public RGWPutObjLegalHold {
531 public:
532 RGWPutObjLegalHold_ObjStore() = default;
533 ~RGWPutObjLegalHold_ObjStore() override = default;
534 int get_params(optional_yield y) override;
535 };
536
537 class RGWGetObjLegalHold_ObjStore : public RGWGetObjLegalHold {
538 public:
539 RGWGetObjLegalHold_ObjStore() = default;
540 ~RGWGetObjLegalHold_ObjStore() = default;
541 };
542
543 class RGWRESTOp : public RGWOp {
544 protected:
545 RGWRESTFlusher flusher;
546 public:
547 void init(rgw::sal::RGWRadosStore *store, struct req_state *s,
548 RGWHandler *dialect_handler) override {
549 RGWOp::init(store, s, dialect_handler);
550 flusher.init(s, this);
551 }
552 void send_response() override;
553 virtual int check_caps(const RGWUserCaps& caps)
554 { return -EPERM; } /* should to be implemented! */
555 int verify_permission(optional_yield y) override;
556 dmc::client_id dmclock_client() override { return dmc::client_id::admin; }
557 };
558
559 class RGWHandler_REST : public RGWHandler {
560 protected:
561
562 virtual bool is_obj_update_op() const { return false; }
563 virtual RGWOp *op_get() { return NULL; }
564 virtual RGWOp *op_put() { return NULL; }
565 virtual RGWOp *op_delete() { return NULL; }
566 virtual RGWOp *op_head() { return NULL; }
567 virtual RGWOp *op_post() { return NULL; }
568 virtual RGWOp *op_copy() { return NULL; }
569 virtual RGWOp *op_options() { return NULL; }
570
571 public:
572 static int allocate_formatter(struct req_state *s, int default_formatter,
573 bool configurable);
574
575 static constexpr int MAX_BUCKET_NAME_LEN = 255;
576 static constexpr int MAX_OBJ_NAME_LEN = 1024;
577
578 RGWHandler_REST() {}
579 ~RGWHandler_REST() override {}
580
581 static int validate_bucket_name(const string& bucket);
582 static int validate_object_name(const string& object);
583 static int reallocate_formatter(struct req_state *s, int type);
584
585 int init_permissions(RGWOp* op, optional_yield y) override;
586 int read_permissions(RGWOp* op, optional_yield y) override;
587
588 virtual RGWOp* get_op(void);
589 virtual void put_op(RGWOp* op);
590 };
591
592 class RGWHandler_REST_SWIFT;
593 class RGWHandler_SWIFT_Auth;
594 class RGWHandler_REST_S3;
595
596 namespace rgw::auth {
597
598 class StrategyRegistry;
599
600 }
601
602 class RGWRESTMgr {
603 bool should_log;
604
605 protected:
606 std::map<std::string, RGWRESTMgr*> resource_mgrs;
607 std::multimap<size_t, std::string> resources_by_size;
608 RGWRESTMgr* default_mgr;
609
610 virtual RGWRESTMgr* get_resource_mgr(struct req_state* s,
611 const std::string& uri,
612 std::string* out_uri);
613
614 virtual RGWRESTMgr* get_resource_mgr_as_default(struct req_state* const s,
615 const std::string& uri,
616 std::string* our_uri) {
617 return this;
618 }
619
620 public:
621 RGWRESTMgr()
622 : should_log(false),
623 default_mgr(nullptr) {
624 }
625 virtual ~RGWRESTMgr();
626
627 void register_resource(std::string resource, RGWRESTMgr* mgr);
628 void register_default_mgr(RGWRESTMgr* mgr);
629
630 virtual RGWRESTMgr* get_manager(struct req_state* const s,
631 /* Prefix to be concatenated with @uri
632 * during the lookup. */
633 const std::string& frontend_prefix,
634 const std::string& uri,
635 std::string* out_uri) final {
636 return get_resource_mgr(s, frontend_prefix + uri, out_uri);
637 }
638
639 virtual RGWHandler_REST* get_handler(
640 rgw::sal::RGWRadosStore *store,
641 struct req_state* const s,
642 const rgw::auth::StrategyRegistry& auth_registry,
643 const std::string& frontend_prefix
644 ) {
645 return nullptr;
646 }
647
648 virtual void put_handler(RGWHandler_REST* const handler) {
649 delete handler;
650 }
651
652 void set_logging(bool _should_log) {
653 should_log = _should_log;
654 }
655
656 bool get_logging() const {
657 return should_log;
658 }
659 };
660
661 class RGWLibIO;
662 class RGWRestfulIO;
663
664 class RGWREST {
665 using x_header = basic_sstring<char, uint16_t, 32>;
666 boost::container::flat_set<x_header> x_headers;
667 RGWRESTMgr mgr;
668
669 static int preprocess(struct req_state *s, rgw::io::BasicClient* rio);
670 public:
671 RGWREST() {}
672 RGWHandler_REST *get_handler(rgw::sal::RGWRadosStore *store,
673 struct req_state *s,
674 const rgw::auth::StrategyRegistry& auth_registry,
675 const std::string& frontend_prefix,
676 RGWRestfulIO *rio,
677 RGWRESTMgr **pmgr,
678 int *init_error);
679 #if 0
680 RGWHandler *get_handler(RGWRados *store, struct req_state *s,
681 RGWLibIO *io, RGWRESTMgr **pmgr,
682 int *init_error);
683 #endif
684
685 void put_handler(RGWHandler_REST *handler) {
686 mgr.put_handler(handler);
687 }
688
689 void register_resource(string resource, RGWRESTMgr *m,
690 bool register_empty = false) {
691 if (!register_empty && resource.empty())
692 return;
693
694 mgr.register_resource(resource, m);
695 }
696
697 void register_default_mgr(RGWRESTMgr *m) {
698 mgr.register_default_mgr(m);
699 }
700
701 void register_x_headers(const std::string& headers);
702
703 bool log_x_headers(void) {
704 return (x_headers.size() > 0);
705 }
706
707 bool log_x_header(const std::string& header) {
708 return (x_headers.find(header) != x_headers.end());
709 }
710 };
711
712 static constexpr int64_t NO_CONTENT_LENGTH = -1;
713 static constexpr int64_t CHUNKED_TRANSFER_ENCODING = -2;
714
715 extern void dump_errno(int http_ret, string& out);
716 extern void dump_errno(const struct rgw_err &err, string& out);
717 extern void dump_errno(struct req_state *s);
718 extern void dump_errno(struct req_state *s, int http_ret);
719 extern void end_header(struct req_state *s,
720 RGWOp* op = nullptr,
721 const char *content_type = nullptr,
722 const int64_t proposed_content_length =
723 NO_CONTENT_LENGTH,
724 bool force_content_type = false,
725 bool force_no_error = false);
726 extern void dump_start(struct req_state *s);
727 extern void list_all_buckets_start(struct req_state *s);
728 extern void dump_owner(struct req_state *s, const rgw_user& id, string& name,
729 const char *section = NULL);
730 extern void dump_header(struct req_state* s,
731 const std::string_view& name,
732 const std::string_view& val);
733 extern void dump_header(struct req_state* s,
734 const std::string_view& name,
735 ceph::buffer::list& bl);
736 extern void dump_header(struct req_state* s,
737 const std::string_view& name,
738 long long val);
739 extern void dump_header(struct req_state* s,
740 const std::string_view& name,
741 const utime_t& val);
742
743 template <class... Args>
744 inline void dump_header_prefixed(struct req_state* s,
745 const std::string_view& name_prefix,
746 const std::string_view& name,
747 Args&&... args) {
748 char full_name_buf[name_prefix.size() + name.size() + 1];
749 const auto len = snprintf(full_name_buf, sizeof(full_name_buf), "%.*s%.*s",
750 static_cast<int>(name_prefix.length()),
751 name_prefix.data(),
752 static_cast<int>(name.length()),
753 name.data());
754 std::string_view full_name(full_name_buf, len);
755 return dump_header(s, std::move(full_name), std::forward<Args>(args)...);
756 }
757
758 template <class... Args>
759 inline void dump_header_infixed(struct req_state* s,
760 const std::string_view& prefix,
761 const std::string_view& infix,
762 const std::string_view& sufix,
763 Args&&... args) {
764 char full_name_buf[prefix.size() + infix.size() + sufix.size() + 1];
765 const auto len = snprintf(full_name_buf, sizeof(full_name_buf), "%.*s%.*s%.*s",
766 static_cast<int>(prefix.length()),
767 prefix.data(),
768 static_cast<int>(infix.length()),
769 infix.data(),
770 static_cast<int>(sufix.length()),
771 sufix.data());
772 std::string_view full_name(full_name_buf, len);
773 return dump_header(s, std::move(full_name), std::forward<Args>(args)...);
774 }
775
776 template <class... Args>
777 inline void dump_header_quoted(struct req_state* s,
778 const std::string_view& name,
779 const std::string_view& val) {
780 /* We need two extra bytes for quotes. */
781 char qvalbuf[val.size() + 2 + 1];
782 const auto len = snprintf(qvalbuf, sizeof(qvalbuf), "\"%.*s\"",
783 static_cast<int>(val.length()), val.data());
784 return dump_header(s, name, std::string_view(qvalbuf, len));
785 }
786
787 template <class ValueT>
788 inline void dump_header_if_nonempty(struct req_state* s,
789 const std::string_view& name,
790 const ValueT& value) {
791 if (name.length() > 0 && value.length() > 0) {
792 return dump_header(s, name, value);
793 }
794 }
795
796 inline std::string compute_domain_uri(const struct req_state *s) {
797 std::string uri = (!s->info.domain.empty()) ? s->info.domain :
798 [&s]() -> std::string {
799 RGWEnv const &env(*(s->info.env));
800 std::string uri =
801 env.get("SERVER_PORT_SECURE") ? "https://" : "http://";
802 if (env.exists("SERVER_NAME")) {
803 uri.append(env.get("SERVER_NAME", "<SERVER_NAME>"));
804 } else {
805 uri.append(env.get("HTTP_HOST", "<HTTP_HOST>"));
806 }
807 return uri;
808 }();
809 return uri;
810 }
811
812 extern void dump_content_length(struct req_state *s, uint64_t len);
813 extern int64_t parse_content_length(const char *content_length);
814 extern void dump_etag(struct req_state *s,
815 const std::string_view& etag,
816 bool quoted = false);
817 extern void dump_epoch_header(struct req_state *s, const char *name, real_time t);
818 extern void dump_time_header(struct req_state *s, const char *name, real_time t);
819 extern void dump_last_modified(struct req_state *s, real_time t);
820 extern void abort_early(struct req_state* s, RGWOp* op, int err,
821 RGWHandler* handler, optional_yield y);
822 extern void dump_range(struct req_state* s, uint64_t ofs, uint64_t end,
823 uint64_t total_size);
824 extern void dump_continue(struct req_state *s);
825 extern void list_all_buckets_end(struct req_state *s);
826 extern void dump_time(struct req_state *s, const char *name, real_time *t);
827 extern std::string dump_time_to_str(const real_time& t);
828 extern void dump_bucket_from_state(struct req_state *s);
829 extern void dump_redirect(struct req_state *s, const string& redirect);
830 extern bool is_valid_url(const char *url);
831 extern void dump_access_control(struct req_state *s, const char *origin,
832 const char *meth,
833 const char *hdr, const char *exp_hdr,
834 uint32_t max_age);
835 extern void dump_access_control(req_state *s, RGWOp *op);
836
837 extern int dump_body(struct req_state* s, const char* buf, size_t len);
838 extern int dump_body(struct req_state* s, /* const */ ceph::buffer::list& bl);
839 extern int dump_body(struct req_state* s, const std::string& str);
840 extern int recv_body(struct req_state* s, char* buf, size_t max);