1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab ft=cpp
6 #define TIME_BUF_SIZE 128
8 #include <boost/utility/string_ref.hpp>
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 */
14 #include "rgw_formats.h"
15 #include "rgw_client_io.h"
17 extern std::map
<std::string
, std::string
> rgw_to_http_attrs
;
19 extern void rgw_rest_init(CephContext
*cct
, const RGWZoneGroup
& zone_group
);
21 extern void rgw_flush_formatter_and_reset(struct req_state
*s
,
22 ceph::Formatter
*formatter
);
24 extern void rgw_flush_formatter(struct req_state
*s
,
25 ceph::Formatter
*formatter
);
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);
31 static inline boost::string_ref
rgw_sanitized_hdrval(ceph::buffer::list
& raw
)
33 /* std::string and thus boost::string_ref 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();
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. */
48 return boost::string_ref(data
, len
);
52 int rgw_rest_get_json_input(CephContext
*cct
, req_state
*s
, T
& out
,
53 uint64_t max_len
, bool *empty
)
60 std::tie(rv
, data
) = rgw_rest_read_all_input(s
, max_len
);
75 if (!parser
.parse(data
.c_str(), data
.length())) {
80 decode_json_obj(out
, &parser
);
81 } catch (JSONDecoder::err
& e
) {
89 std::tuple
<int, bufferlist
> rgw_rest_get_json_input_keep_data(CephContext
*cct
, req_state
*s
, T
& out
, uint64_t max_len
)
93 std::tie(rv
, data
) = rgw_rest_read_all_input(s
, max_len
);
95 return std::make_tuple(rv
, std::move(data
));
99 return std::make_tuple(-EINVAL
, std::move(data
));
104 if (!parser
.parse(data
.c_str(), data
.length())) {
105 return std::make_tuple(-EINVAL
, std::move(data
));
109 decode_json_obj(out
, &parser
);
110 } catch (JSONDecoder::err
& e
) {
111 return std::make_tuple(-EINVAL
, std::move(data
));
114 return std::make_tuple(0, std::move(data
));
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
);
140 class RGWRESTFlusher
: public RGWFormatterFlusher
{
144 void do_flush() override
;
145 void do_start(int ret
) override
;
147 RGWRESTFlusher(struct req_state
*_s
, RGWOp
*_op
) :
148 RGWFormatterFlusher(_s
->formatter
), s(_s
), op(_op
) {}
149 RGWRESTFlusher() : RGWFormatterFlusher(NULL
), s(NULL
), op(NULL
) {}
151 void init(struct req_state
*_s
, RGWOp
*_op
) {
154 set_formatter(s
->formatter
);
158 class RGWGetObj_ObjStore
: public RGWGetObj
163 RGWGetObj_ObjStore() : sent_header(false) {}
165 void init(rgw::sal::RGWRadosStore
*store
, struct req_state
*s
, RGWHandler
*h
) override
{
166 RGWGetObj::init(store
, s
, h
);
170 int get_params() override
;
173 class RGWGetObjTags_ObjStore
: public RGWGetObjTags
{
175 RGWGetObjTags_ObjStore() {};
176 ~RGWGetObjTags_ObjStore() {};
179 class RGWPutObjTags_ObjStore
: public RGWPutObjTags
{
181 RGWPutObjTags_ObjStore() {};
182 ~RGWPutObjTags_ObjStore() {};
185 class RGWGetBucketTags_ObjStore
: public RGWGetBucketTags
{
187 RGWGetBucketTags_ObjStore() = default;
188 virtual ~RGWGetBucketTags_ObjStore() = default;
191 class RGWPutBucketTags_ObjStore
: public RGWPutBucketTags
{
193 RGWPutBucketTags_ObjStore() = default;
194 virtual ~RGWPutBucketTags_ObjStore() = default;
197 class RGWGetBucketReplication_ObjStore
: public RGWGetBucketReplication
{
199 RGWGetBucketReplication_ObjStore() {};
200 ~RGWGetBucketReplication_ObjStore() {};
203 class RGWPutBucketReplication_ObjStore
: public RGWPutBucketReplication
{
205 RGWPutBucketReplication_ObjStore() = default;
206 virtual ~RGWPutBucketReplication_ObjStore() = default;
209 class RGWDeleteBucketReplication_ObjStore
: public RGWDeleteBucketReplication
{
211 RGWDeleteBucketReplication_ObjStore() = default;
212 virtual ~RGWDeleteBucketReplication_ObjStore() = default;
215 class RGWListBuckets_ObjStore
: public RGWListBuckets
{
217 RGWListBuckets_ObjStore() {}
218 ~RGWListBuckets_ObjStore() override
{}
221 class RGWGetUsage_ObjStore
: public RGWGetUsage
{
223 RGWGetUsage_ObjStore() {}
224 ~RGWGetUsage_ObjStore() override
{}
227 class RGWListBucket_ObjStore
: public RGWListBucket
{
229 RGWListBucket_ObjStore() {}
230 ~RGWListBucket_ObjStore() override
{}
233 class RGWStatAccount_ObjStore
: public RGWStatAccount
{
235 RGWStatAccount_ObjStore() {}
236 ~RGWStatAccount_ObjStore() override
{}
239 class RGWStatBucket_ObjStore
: public RGWStatBucket
{
241 RGWStatBucket_ObjStore() {}
242 ~RGWStatBucket_ObjStore() override
{}
245 class RGWCreateBucket_ObjStore
: public RGWCreateBucket
{
247 RGWCreateBucket_ObjStore() {}
248 ~RGWCreateBucket_ObjStore() override
{}
251 class RGWDeleteBucket_ObjStore
: public RGWDeleteBucket
{
253 RGWDeleteBucket_ObjStore() {}
254 ~RGWDeleteBucket_ObjStore() override
{}
257 class RGWPutObj_ObjStore
: public RGWPutObj
260 RGWPutObj_ObjStore() {}
261 ~RGWPutObj_ObjStore() override
{}
263 int verify_params() override
;
264 int get_params() override
;
265 int get_data(bufferlist
& bl
) override
;
268 class RGWPostObj_ObjStore
: public RGWPostObj
270 std::string boundary
;
273 struct post_part_field
{
275 std::map
<std::string
, std::string
> params
;
278 struct post_form_part
{
280 std::map
<std::string
, post_part_field
, ltstr_nocase
> fields
;
281 ceph::bufferlist data
;
285 using parts_collection_t
= \
286 std::map
<std::string
, post_form_part
, const ltstr_nocase
>;
289 ceph::bufferlist in_data
;
291 int read_with_boundary(ceph::bufferlist
& bl
,
294 bool& reached_boundary
,
297 int read_line(ceph::bufferlist
& bl
,
299 bool& reached_boundary
,
302 int read_data(ceph::bufferlist
& bl
,
304 bool& reached_boundary
,
307 int read_form_part_header(struct post_form_part
*part
, bool& done
);
309 int get_params() override
;
311 static int parse_part_field(const std::string
& line
,
312 std::string
& field_name
, /* out */
313 post_part_field
& field
); /* out */
315 static void parse_boundary_params(const std::string
& params_str
,
317 std::map
<std::string
, std::string
>& params
);
319 static bool part_str(parts_collection_t
& parts
,
320 const std::string
& name
,
323 static std::string
get_part_str(parts_collection_t
& parts
,
324 const std::string
& name
,
325 const std::string
& def_val
= std::string());
327 static bool part_bl(parts_collection_t
& parts
,
328 const std::string
& name
,
329 ceph::bufferlist
*pbl
);
332 RGWPostObj_ObjStore() {}
333 ~RGWPostObj_ObjStore() override
{}
335 int verify_params() override
;
339 class RGWPutMetadataAccount_ObjStore
: public RGWPutMetadataAccount
342 RGWPutMetadataAccount_ObjStore() {}
343 ~RGWPutMetadataAccount_ObjStore() override
{}
346 class RGWPutMetadataBucket_ObjStore
: public RGWPutMetadataBucket
349 RGWPutMetadataBucket_ObjStore() {}
350 ~RGWPutMetadataBucket_ObjStore() override
{}
353 class RGWPutMetadataObject_ObjStore
: public RGWPutMetadataObject
356 RGWPutMetadataObject_ObjStore() {}
357 ~RGWPutMetadataObject_ObjStore() override
{}
360 class RGWDeleteObj_ObjStore
: public RGWDeleteObj
{
362 RGWDeleteObj_ObjStore() {}
363 ~RGWDeleteObj_ObjStore() override
{}
366 class RGWGetCrossDomainPolicy_ObjStore
: public RGWGetCrossDomainPolicy
{
368 RGWGetCrossDomainPolicy_ObjStore() = default;
369 ~RGWGetCrossDomainPolicy_ObjStore() override
= default;
372 class RGWGetHealthCheck_ObjStore
: public RGWGetHealthCheck
{
374 RGWGetHealthCheck_ObjStore() = default;
375 ~RGWGetHealthCheck_ObjStore() override
= default;
378 class RGWCopyObj_ObjStore
: public RGWCopyObj
{
380 RGWCopyObj_ObjStore() {}
381 ~RGWCopyObj_ObjStore() override
{}
384 class RGWGetACLs_ObjStore
: public RGWGetACLs
{
386 RGWGetACLs_ObjStore() {}
387 ~RGWGetACLs_ObjStore() override
{}
390 class RGWPutACLs_ObjStore
: public RGWPutACLs
{
392 RGWPutACLs_ObjStore() {}
393 ~RGWPutACLs_ObjStore() override
{}
395 int get_params() override
;
398 class RGWGetLC_ObjStore
: public RGWGetLC
{
400 RGWGetLC_ObjStore() {}
401 ~RGWGetLC_ObjStore() override
{}
404 class RGWPutLC_ObjStore
: public RGWPutLC
{
406 RGWPutLC_ObjStore() {}
407 ~RGWPutLC_ObjStore() override
{}
409 int get_params() override
;
412 class RGWDeleteLC_ObjStore
: public RGWDeleteLC
{
414 RGWDeleteLC_ObjStore() {}
415 ~RGWDeleteLC_ObjStore() override
{}
419 class RGWGetCORS_ObjStore
: public RGWGetCORS
{
421 RGWGetCORS_ObjStore() {}
422 ~RGWGetCORS_ObjStore() override
{}
425 class RGWPutCORS_ObjStore
: public RGWPutCORS
{
427 RGWPutCORS_ObjStore() {}
428 ~RGWPutCORS_ObjStore() override
{}
431 class RGWDeleteCORS_ObjStore
: public RGWDeleteCORS
{
433 RGWDeleteCORS_ObjStore() {}
434 ~RGWDeleteCORS_ObjStore() override
{}
437 class RGWOptionsCORS_ObjStore
: public RGWOptionsCORS
{
439 RGWOptionsCORS_ObjStore() {}
440 ~RGWOptionsCORS_ObjStore() override
{}
443 class RGWInitMultipart_ObjStore
: public RGWInitMultipart
{
445 RGWInitMultipart_ObjStore() {}
446 ~RGWInitMultipart_ObjStore() override
{}
449 class RGWCompleteMultipart_ObjStore
: public RGWCompleteMultipart
{
451 RGWCompleteMultipart_ObjStore() {}
452 ~RGWCompleteMultipart_ObjStore() override
{}
454 int get_params() override
;
457 class RGWAbortMultipart_ObjStore
: public RGWAbortMultipart
{
459 RGWAbortMultipart_ObjStore() {}
460 ~RGWAbortMultipart_ObjStore() override
{}
463 class RGWListMultipart_ObjStore
: public RGWListMultipart
{
465 RGWListMultipart_ObjStore() {}
466 ~RGWListMultipart_ObjStore() override
{}
468 int get_params() override
;
471 class RGWListBucketMultiparts_ObjStore
: public RGWListBucketMultiparts
{
473 RGWListBucketMultiparts_ObjStore() {}
474 ~RGWListBucketMultiparts_ObjStore() override
{}
476 int get_params() override
;
479 class RGWBulkDelete_ObjStore
: public RGWBulkDelete
{
481 RGWBulkDelete_ObjStore() {}
482 ~RGWBulkDelete_ObjStore() override
{}
485 class RGWBulkUploadOp_ObjStore
: public RGWBulkUploadOp
{
487 RGWBulkUploadOp_ObjStore() = default;
488 ~RGWBulkUploadOp_ObjStore() = default;
491 class RGWDeleteMultiObj_ObjStore
: public RGWDeleteMultiObj
{
493 RGWDeleteMultiObj_ObjStore() {}
494 ~RGWDeleteMultiObj_ObjStore() override
{}
496 int get_params() override
;
499 class RGWInfo_ObjStore
: public RGWInfo
{
501 RGWInfo_ObjStore() = default;
502 ~RGWInfo_ObjStore() override
= default;
505 class RGWPutBucketObjectLock_ObjStore
: public RGWPutBucketObjectLock
{
507 RGWPutBucketObjectLock_ObjStore() = default;
508 ~RGWPutBucketObjectLock_ObjStore() = default;
509 int get_params() override
;
512 class RGWGetBucketObjectLock_ObjStore
: public RGWGetBucketObjectLock
{
514 RGWGetBucketObjectLock_ObjStore() = default;
515 ~RGWGetBucketObjectLock_ObjStore() override
= default;
518 class RGWPutObjRetention_ObjStore
: public RGWPutObjRetention
{
520 RGWPutObjRetention_ObjStore() = default;
521 ~RGWPutObjRetention_ObjStore() override
= default;
524 class RGWGetObjRetention_ObjStore
: public RGWGetObjRetention
{
526 RGWGetObjRetention_ObjStore() = default;
527 ~RGWGetObjRetention_ObjStore() = default;
530 class RGWPutObjLegalHold_ObjStore
: public RGWPutObjLegalHold
{
532 RGWPutObjLegalHold_ObjStore() = default;
533 ~RGWPutObjLegalHold_ObjStore() override
= default;
534 int get_params() override
;
537 class RGWGetObjLegalHold_ObjStore
: public RGWGetObjLegalHold
{
539 RGWGetObjLegalHold_ObjStore() = default;
540 ~RGWGetObjLegalHold_ObjStore() = default;
543 class RGWRESTOp
: public RGWOp
{
546 RGWRESTFlusher flusher
;
548 RGWRESTOp() : http_ret(0) {}
549 void init(rgw::sal::RGWRadosStore
*store
, struct req_state
*s
,
550 RGWHandler
*dialect_handler
) override
{
551 RGWOp::init(store
, s
, dialect_handler
);
552 flusher
.init(s
, this);
554 void send_response() override
;
555 virtual int check_caps(const RGWUserCaps
& caps
)
556 { return -EPERM
; } /* should to be implemented! */
557 int verify_permission() override
;
558 dmc::client_id
dmclock_client() override
{ return dmc::client_id::admin
; }
561 class RGWHandler_REST
: public RGWHandler
{
564 virtual bool is_obj_update_op() const { return false; }
565 virtual RGWOp
*op_get() { return NULL
; }
566 virtual RGWOp
*op_put() { return NULL
; }
567 virtual RGWOp
*op_delete() { return NULL
; }
568 virtual RGWOp
*op_head() { return NULL
; }
569 virtual RGWOp
*op_post() { return NULL
; }
570 virtual RGWOp
*op_copy() { return NULL
; }
571 virtual RGWOp
*op_options() { return NULL
; }
574 static int allocate_formatter(struct req_state
*s
, int default_formatter
,
577 static constexpr int MAX_BUCKET_NAME_LEN
= 255;
578 static constexpr int MAX_OBJ_NAME_LEN
= 1024;
581 ~RGWHandler_REST() override
{}
583 static int validate_bucket_name(const string
& bucket
);
584 static int validate_object_name(const string
& object
);
585 static int reallocate_formatter(struct req_state
*s
, int type
);
587 int init_permissions(RGWOp
* op
) override
;
588 int read_permissions(RGWOp
* op
) override
;
590 virtual RGWOp
* get_op(void);
591 virtual void put_op(RGWOp
* op
);
594 class RGWHandler_REST_SWIFT
;
595 class RGWHandler_SWIFT_Auth
;
596 class RGWHandler_REST_S3
;
598 namespace rgw::auth
{
600 class StrategyRegistry
;
608 std::map
<std::string
, RGWRESTMgr
*> resource_mgrs
;
609 std::multimap
<size_t, std::string
> resources_by_size
;
610 RGWRESTMgr
* default_mgr
;
612 virtual RGWRESTMgr
* get_resource_mgr(struct req_state
* s
,
613 const std::string
& uri
,
614 std::string
* out_uri
);
616 virtual RGWRESTMgr
* get_resource_mgr_as_default(struct req_state
* const s
,
617 const std::string
& uri
,
618 std::string
* our_uri
) {
625 default_mgr(nullptr) {
627 virtual ~RGWRESTMgr();
629 void register_resource(std::string resource
, RGWRESTMgr
* mgr
);
630 void register_default_mgr(RGWRESTMgr
* mgr
);
632 virtual RGWRESTMgr
* get_manager(struct req_state
* const s
,
633 /* Prefix to be concatenated with @uri
634 * during the lookup. */
635 const std::string
& frontend_prefix
,
636 const std::string
& uri
,
637 std::string
* out_uri
) final
{
638 return get_resource_mgr(s
, frontend_prefix
+ uri
, out_uri
);
641 virtual RGWHandler_REST
* get_handler(
642 struct req_state
* const s
,
643 const rgw::auth::StrategyRegistry
& auth_registry
,
644 const std::string
& frontend_prefix
649 virtual void put_handler(RGWHandler_REST
* const handler
) {
653 void set_logging(bool _should_log
) {
654 should_log
= _should_log
;
657 bool get_logging() const {
666 using x_header
= basic_sstring
<char, uint16_t, 32>;
667 boost::container::flat_set
<x_header
> x_headers
;
670 static int preprocess(struct req_state
*s
, rgw::io::BasicClient
* rio
);
673 RGWHandler_REST
*get_handler(rgw::sal::RGWRadosStore
*store
,
675 const rgw::auth::StrategyRegistry
& auth_registry
,
676 const std::string
& frontend_prefix
,
681 RGWHandler
*get_handler(RGWRados
*store
, struct req_state
*s
,
682 RGWLibIO
*io
, RGWRESTMgr
**pmgr
,
686 void put_handler(RGWHandler_REST
*handler
) {
687 mgr
.put_handler(handler
);
690 void register_resource(string resource
, RGWRESTMgr
*m
,
691 bool register_empty
= false) {
692 if (!register_empty
&& resource
.empty())
695 mgr
.register_resource(resource
, m
);
698 void register_default_mgr(RGWRESTMgr
*m
) {
699 mgr
.register_default_mgr(m
);
702 void register_x_headers(const std::string
& headers
);
704 bool log_x_headers(void) {
705 return (x_headers
.size() > 0);
708 bool log_x_header(const std::string
& header
) {
709 return (x_headers
.find(header
) != x_headers
.end());
713 static constexpr int64_t NO_CONTENT_LENGTH
= -1;
714 static constexpr int64_t CHUNKED_TRANSFER_ENCODING
= -2;
716 extern void dump_errno(int http_ret
, string
& out
);
717 extern void dump_errno(const struct rgw_err
&err
, string
& out
);
718 extern void dump_errno(struct req_state
*s
);
719 extern void dump_errno(struct req_state
*s
, int http_ret
);
720 extern void end_header(struct req_state
*s
,
722 const char *content_type
= nullptr,
723 const int64_t proposed_content_length
=
725 bool force_content_type
= false,
726 bool force_no_error
= false);
727 extern void dump_start(struct req_state
*s
);
728 extern void list_all_buckets_start(struct req_state
*s
);
729 extern void dump_owner(struct req_state
*s
, const rgw_user
& id
, string
& name
,
730 const char *section
= NULL
);
731 extern void dump_header(struct req_state
* s
,
732 const boost::string_ref
& name
,
733 const boost::string_ref
& val
);
734 extern void dump_header(struct req_state
* s
,
735 const boost::string_ref
& name
,
736 ceph::buffer::list
& bl
);
737 extern void dump_header(struct req_state
* s
,
738 const boost::string_ref
& name
,
740 extern void dump_header(struct req_state
* s
,
741 const boost::string_ref
& name
,
744 template <class... Args
>
745 static inline void dump_header_prefixed(struct req_state
* s
,
746 const boost::string_ref
& name_prefix
,
747 const boost::string_ref
& name
,
749 char full_name_buf
[name_prefix
.size() + name
.size() + 1];
750 const auto len
= snprintf(full_name_buf
, sizeof(full_name_buf
), "%.*s%.*s",
751 static_cast<int>(name_prefix
.length()),
753 static_cast<int>(name
.length()),
755 boost::string_ref
full_name(full_name_buf
, len
);
756 return dump_header(s
, std::move(full_name
), std::forward
<Args
>(args
)...);
759 template <class... Args
>
760 static inline void dump_header_infixed(struct req_state
* s
,
761 const boost::string_ref
& prefix
,
762 const boost::string_ref
& infix
,
763 const boost::string_ref
& sufix
,
765 char full_name_buf
[prefix
.size() + infix
.size() + sufix
.size() + 1];
766 const auto len
= snprintf(full_name_buf
, sizeof(full_name_buf
), "%.*s%.*s%.*s",
767 static_cast<int>(prefix
.length()),
769 static_cast<int>(infix
.length()),
771 static_cast<int>(sufix
.length()),
773 boost::string_ref
full_name(full_name_buf
, len
);
774 return dump_header(s
, std::move(full_name
), std::forward
<Args
>(args
)...);
777 template <class... Args
>
778 static inline void dump_header_quoted(struct req_state
* s
,
779 const boost::string_ref
& name
,
780 const boost::string_ref
& val
) {
781 /* We need two extra bytes for quotes. */
782 char qvalbuf
[val
.size() + 2 + 1];
783 const auto len
= snprintf(qvalbuf
, sizeof(qvalbuf
), "\"%.*s\"",
784 static_cast<int>(val
.length()), val
.data());
785 return dump_header(s
, name
, boost::string_ref(qvalbuf
, len
));
788 template <class ValueT
>
789 static inline void dump_header_if_nonempty(struct req_state
* s
,
790 const boost::string_ref
& name
,
791 const ValueT
& value
) {
792 if (name
.length() > 0 && value
.length() > 0) {
793 return dump_header(s
, name
, value
);
797 static inline std::string
compute_domain_uri(const struct req_state
*s
) {
798 std::string uri
= (!s
->info
.domain
.empty()) ? s
->info
.domain
:
799 [&s
]() -> std::string
{
800 RGWEnv
const &env(*(s
->info
.env
));
802 env
.get("SERVER_PORT_SECURE") ? "https://" : "http://";
803 if (env
.exists("SERVER_NAME")) {
804 uri
.append(env
.get("SERVER_NAME", "<SERVER_NAME>"));
806 uri
.append(env
.get("HTTP_HOST", "<HTTP_HOST>"));
813 extern void dump_content_length(struct req_state
*s
, uint64_t len
);
814 extern int64_t parse_content_length(const char *content_length
);
815 extern void dump_etag(struct req_state
*s
,
816 const boost::string_ref
& etag
,
817 bool quoted
= false);
818 extern void dump_epoch_header(struct req_state
*s
, const char *name
, real_time t
);
819 extern void dump_time_header(struct req_state
*s
, const char *name
, real_time t
);
820 extern void dump_last_modified(struct req_state
*s
, real_time t
);
821 extern void abort_early(struct req_state
* s
, RGWOp
* op
, int err
,
822 RGWHandler
* handler
);
823 extern void dump_range(struct req_state
* s
, uint64_t ofs
, uint64_t end
,
824 uint64_t total_size
);
825 extern void dump_continue(struct req_state
*s
);
826 extern void list_all_buckets_end(struct req_state
*s
);
827 extern void dump_time(struct req_state
*s
, const char *name
, real_time
*t
);
828 extern std::string
dump_time_to_str(const real_time
& t
);
829 extern void dump_bucket_from_state(struct req_state
*s
);
830 extern void dump_redirect(struct req_state
*s
, const string
& redirect
);
831 extern bool is_valid_url(const char *url
);
832 extern void dump_access_control(struct req_state
*s
, const char *origin
,
834 const char *hdr
, const char *exp_hdr
,
836 extern void dump_access_control(req_state
*s
, RGWOp
*op
);
838 extern int dump_body(struct req_state
* s
, const char* buf
, size_t len
);
839 extern int dump_body(struct req_state
* s
, /* const */ ceph::buffer::list
& bl
);
840 extern int dump_body(struct req_state
* s
, const std::string
& str
);
841 extern int recv_body(struct req_state
* s
, char* buf
, size_t max
);