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