size_t sent = 0;
if (! has_content_length) {
- constexpr char TRANSFER_CHUNKED[] = "Transfer-Enconding: chunked\r\n";
-
- sent += RGWDecoratedStreamIO<T>::write_data(TRANSFER_CHUNKED,
- sizeof(TRANSFER_CHUNKED) - 1);
+ sent += RGWDecoratedStreamIO<T>::send_header("Transfer-Enconding",
+ "chunked");
chunking_enabled = true;
}
dump_status(s, http_ret, http_status_names[http_ret]);
}
-void dump_string_header(struct req_state *s, const char *name, const char *val)
+void dump_header(struct req_state* const s,
+ const boost::string_ref& name,
+ const boost::string_ref& val)
{
- int r = STREAM_IO(s)->print("%s: %s\r\n", name, val);
+ const int r = STREAM_IO(s)->send_header(name, val);
if (r < 0) {
- ldout(s->cct, 0) << "ERROR: s->cio->print() returned err=" << r << dendl;
+ ldout(s->cct, 0) << "ERROR: s->cio->send_header() returned err="
+ << r << dendl;
}
}
-void dump_content_length(struct req_state *s, uint64_t len)
+void dump_header(struct req_state* const s,
+ const boost::string_ref& name,
+ ceph::buffer::list& bl)
+{
+ return dump_header(s, name, boost::string_ref(bl.c_str(), bl.length()));
+}
+
+void dump_header(struct req_state* const s,
+ const boost::string_ref& name,
+ const long long val)
+{
+ char buf[32];
+ const auto len = snprintf(buf, sizeof(buf), "%lld", val);
+
+ return dump_header(s, name, boost::string_ref(buf, len));
+}
+
+void dump_header(struct req_state* const s,
+ const boost::string_ref& name,
+ const utime_t& ut)
+{
+ char buf[32];
+ const auto len = snprintf(buf, sizeof(buf), "%lld.%05d",
+ static_cast<long long>(ut.sec()),
+ static_cast<int>(ut.usec() / 10));
+
+ return dump_header(s, name, boost::string_ref(buf, len));
+}
+
+void dump_content_length(struct req_state* const s, const uint64_t len)
{
int r = STREAM_IO(s)->send_content_length(len);
if (r < 0) {
ldout(s->cct, 0) << "ERROR: s->cio->send_content_length() returned err="
<< r << dendl;
}
- r = STREAM_IO(s)->print("Accept-Ranges: bytes\r\n");
- if (r < 0) {
- ldout(s->cct, 0) << "ERROR: s->cio->print() returned err=" << r << dendl;
- }
+ dump_header(s, "Accept-Ranges", "bytes");
}
-void dump_etag(struct req_state * const s, const char * const etag)
+void dump_etag(struct req_state* const s, const boost::string_ref& etag)
{
- if ('\0' == *etag) {
+ if (etag.empty()) {
return;
}
- int r;
if (s->prot_flags & RGW_REST_SWIFT) {
- r = STREAM_IO(s)->print("etag: %s\r\n", etag);
+ return dump_header(s, "etag", etag);
} else {
- r = STREAM_IO(s)->print("ETag: \"%s\"\r\n", etag);
- }
- if (r < 0) {
- ldout(s->cct, 0) << "ERROR: s->cio->print() returned err=" << r << dendl;
+ /* We need two extra bytes for quotes. */
+ char buf[etag.size() + 2 + 1];
+ const auto len = snprintf(buf, sizeof(buf), "\"%s\"", etag.data());
+
+ return dump_header(s, "ETag", boost::string_ref(buf, len));
}
}
-void dump_pair(struct req_state *s, const char *key, const char *value)
+void dump_etag(struct req_state* const s, ceph::buffer::list& bl_etag)
+{
+ return dump_etag(s, boost::string_ref(bl_etag.c_str(), bl_etag.length()));
+}
+
+void dump_pair(struct req_state* const s,
+ const char* const key,
+ const char* const value)
{
if ( (strlen(key) > 0) && (strlen(value) > 0))
- STREAM_IO(s)->print("%s: %s\r\n", key, value);
+ STREAM_IO(s)->send_header(key, value);
}
void dump_bucket_from_state(struct req_state *s)
} else {
url_encode(s->bucket_name, b);
}
- STREAM_IO(s)->print("Bucket: %s\r\n", b.c_str());
+ STREAM_IO(s)->send_header("Bucket", b);
}
}
}
location += "/";
if (!s->object.empty()) {
location += s->object.name;
- STREAM_IO(s)->print("Location: %s\r\n", location.c_str());
+ dump_header(s, "Location", location);
}
}
- }
- else {
- STREAM_IO(s)->print("Location: \"%s\"\r\n", s->info.request_uri.c_str());
+ } else {
+ dump_header(s, "Location", "\"" + s->info.request_uri + "\"");
}
}
if (redirect.empty())
return;
- STREAM_IO(s)->print("Location: %s\r\n", redirect.c_str());
+ STREAM_IO(s)->send_header("Location", redirect);
}
-static bool dump_time_header_impl(char (×tr)[TIME_BUF_SIZE],
- const real_time t)
+static std::size_t dump_time_header_impl(char (×tr)[TIME_BUF_SIZE],
+ const real_time t)
{
const utime_t ut(t);
time_t secs = static_cast<time_t>(ut.sec());
struct tm result;
const struct tm * const tmp = gmtime_r(&secs, &result);
if (tmp == nullptr) {
- return false;
- }
-
- if (strftime(timestr, sizeof(timestr),
- "%a, %d %b %Y %H:%M:%S %Z", tmp) == 0) {
- return false;
+ return 0;
}
- return true;
+ return strftime(timestr, sizeof(timestr),
+ "%a, %d %b %Y %H:%M:%S %Z", tmp);
}
void dump_time_header(struct req_state *s, const char *name, real_time t)
{
char timestr[TIME_BUF_SIZE];
- if (! dump_time_header_impl(timestr, t)) {
+ const std::size_t len = dump_time_header_impl(timestr, t);
+ if (len == 0) {
return;
}
- int r = STREAM_IO(s)->print("%s: %s\r\n", name, timestr);
- if (r < 0) {
- ldout(s->cct, 0) << "ERROR: s->cio->print() returned err=" << r << dendl;
- }
+ return dump_header(s, name, boost::string_ref(timestr, len));
}
std::string dump_time_to_str(const real_time& t)
void dump_epoch_header(struct req_state *s, const char *name, real_time t)
{
utime_t ut(t);
- char sec_buf[32], nsec_buf[32];
- snprintf(sec_buf, sizeof(sec_buf), "%lld", (long long)ut.sec());
- snprintf(nsec_buf, sizeof(nsec_buf), "%09lld", (long long)ut.nsec());
+ char buf[65];
+ const auto len = snprintf(buf, sizeof(buf), "%lld.%09lld",
+ (long long)ut.sec(),
+ (long long)ut.nsec());
- int r = STREAM_IO(s)->print("%s: %s.%s\r\n", name, sec_buf, nsec_buf);
- if (r < 0) {
- ldout(s->cct, 0) << "ERROR: s->cio->print() returned err=" << r << dendl;
- }
+ return dump_header(s, name, boost::string_ref(buf, len));
}
void dump_time(struct req_state *s, const char *name, real_time *t)
const char *hdr, const char *exp_hdr,
uint32_t max_age) {
if (origin && (origin[0] != '\0')) {
- STREAM_IO(s)->print("Access-Control-Allow-Origin: %s\r\n", origin);
+ dump_header(s, "Access-Control-Allow-Origin", origin);
/* If the server specifies an origin host rather than "*",
* then it must also include Origin in the Vary response header
* to indicate to clients that server responses will differ
* based on the value of the Origin request header.
*/
- if (strcmp(origin, "*") != 0)
- STREAM_IO(s)->print("Vary: Origin\r\n");
+ if (strcmp(origin, "*") != 0) {
+ dump_header(s, "Vary", "Origin");
+ }
- if (meth && (meth[0] != '\0'))
- STREAM_IO(s)->print("Access-Control-Allow-Methods: %s\r\n", meth);
- if (hdr && (hdr[0] != '\0'))
- STREAM_IO(s)->print("Access-Control-Allow-Headers: %s\r\n", hdr);
+ if (meth && (meth[0] != '\0')) {
+ dump_header(s, "Access-Control-Allow-Methods", meth);
+ }
+ if (hdr && (hdr[0] != '\0')) {
+ dump_header(s, "Access-Control-Allow-Headers", hdr);
+ }
if (exp_hdr && (exp_hdr[0] != '\0')) {
- STREAM_IO(s)->print("Access-Control-Expose-Headers: %s\r\n", exp_hdr);
+ dump_header(s, "Access-Control-Expose-Headers", exp_hdr);
}
if (max_age != CORS_MAX_AGE_INVALID) {
- STREAM_IO(s)->print("Access-Control-Max-Age: %d\r\n", max_age);
+ dump_header(s, "Access-Control-Max-Age", max_age);
}
}
}
void dump_trans_id(req_state *s)
{
if (s->prot_flags & RGW_REST_SWIFT) {
- STREAM_IO(s)->print("X-Trans-Id: %s\r\n", s->trans_id.c_str());
- }
- else if (s->trans_id.length()) {
- STREAM_IO(s)->print("x-amz-request-id: %s\r\n", s->trans_id.c_str());
+ dump_header(s, "X-Trans-Id", s->trans_id);
+ } else if (s->trans_id.length()) {
+ dump_header(s, "x-amz-request-id", s->trans_id);
}
}
if ((!s->err.is_err()) &&
(s->bucket_info.owner != s->user->user_id) &&
(s->bucket_info.requester_pays)) {
- STREAM_IO(s)->print("x-amz-request-charged: requester\r\n");
+ dump_header(s, "x-amz-request-charged", "requester");
}
if (op) {
}
}
- int r;
if (content_type) {
- r = STREAM_IO(s)->print("Content-Type: %s\r\n", content_type);
- if (r < 0) {
- ldout(s->cct, 0) << "ERROR: STREAM_IO(s)->print() returned err=" << r
- << dendl;
- }
+ dump_header(s, "Content-Type", content_type);
}
- r = STREAM_IO(s)->complete_header();
+ int r = STREAM_IO(s)->complete_header();
if (r < 0) {
ldout(s->cct, 0) << "ERROR: STREAM_IO(s)->complete_header() returned err="
<< r << dendl;
STREAM_IO(s)->send_100_continue();
}
-void dump_range(struct req_state *s, uint64_t ofs, uint64_t end,
- uint64_t total)
+void dump_range(struct req_state* const s,
+ const uint64_t ofs,
+ const uint64_t end,
+ const uint64_t total)
{
- char range_buf[128];
-
/* dumping range into temp buffer first, as libfcgi will fail to digest
* %lld */
+ char range_buf[128];
+ std::size_t len;
- if (!total) {
- snprintf(range_buf, sizeof(range_buf), "*/%lld", (long long)total);
+ if (! total) {
+ len = snprintf(range_buf, sizeof(range_buf), "bytes */%lld",
+ static_cast<long long>(total));
} else {
- snprintf(range_buf, sizeof(range_buf), "%lld-%lld/%lld", (long long)ofs,
- (long long)end, (long long)total);
- }
- int r = STREAM_IO(s)->print("Content-Range: bytes %s\r\n", range_buf);
- if (r < 0) {
- ldout(s->cct, 0) << "ERROR: s->cio->print() returned err=" << r << dendl;
+ len = snprintf(range_buf, sizeof(range_buf), "bytes %lld-%lld/%lld",
+ static_cast<long long>(ofs),
+ static_cast<long long>(end),
+ static_cast<long long>(total));
}
+
+ return dump_header(s, "Content-Range", boost::string_ref(range_buf, len));
}
int RGWGetObj_ObjStore::get_params()
#define TIME_BUF_SIZE 128
+#include <boost/utility/string_ref.hpp>
+
#include "common/ceph_json.h"
#include "include/assert.h" /* needed because of common/ceph_json.h */
#include "rgw_op.h"
extern void list_all_buckets_start(struct req_state *s);
extern void dump_owner(struct req_state *s, rgw_user& id, string& name,
const char *section = NULL);
-extern void dump_string_header(struct req_state *s, const char *name,
- const char *val);
+extern void dump_header(struct req_state* s,
+ const boost::string_ref& name,
+ const boost::string_ref& val);
+extern void dump_header(struct req_state* s,
+ const boost::string_ref& name,
+ ceph::buffer::list& bl);
+extern void dump_header(struct req_state* s,
+ const boost::string_ref& name,
+ long long val);
+extern void dump_header(struct req_state* s,
+ const boost::string_ref& name,
+ const utime_t& val);
+template <class... Args>
+static inline void dump_header_prefixed(struct req_state* s,
+ const boost::string_ref& name_prefix,
+ const boost::string_ref& name,
+ Args&&... args) {
+ char full_name_buf[name_prefix.size() + name.size() + 1];
+ const auto len = snprintf(full_name_buf, sizeof(full_name_buf), "%.*s%.*s",
+ name_prefix.length(), name_prefix.data(),
+ name.length(), name.data());
+ boost::string_ref full_name(full_name_buf, len);
+ return dump_header(s, std::move(full_name), std::forward<Args>(args)...);
+}
extern void dump_content_length(struct req_state *s, uint64_t len);
-extern void dump_etag(struct req_state *s, const char *etag);
+extern void dump_etag(struct req_state *s, const boost::string_ref& etag);
+extern void dump_etag(struct req_state *s, ceph::buffer::list& bl_etag);
extern void dump_epoch_header(struct req_state *s, const char *name, real_time t);
extern void dump_time_header(struct req_state *s, const char *name, real_time t);
extern void dump_last_modified(struct req_state *s, real_time t);
if (s->system_request &&
s->info.args.exists(RGW_SYS_PARAM_PREFIX "prepend-metadata")) {
- STREAM_IO(s)->print("Rgwx-Object-Size: %lld\r\n", (long long)total_len);
+ dump_header(s, "Rgwx-Object-Size", (long long)total_len);
if (rgwx_stat) {
/*
stringstream ss;
jf.flush(ss);
metadata_bl.append(ss.str());
- STREAM_IO(s)->print("Rgwx-Embedded-Metadata-Len: %lld\r\n",
- (long long)metadata_bl.length());
+ dump_header(s, "Rgwx-Embedded-Metadata-Len", metadata_bl.length());
total_len += metadata_bl.length();
}
if (r < 0) {
ldout(s->cct, 0) << "ERROR: failed to decode pg ver attr, ignoring" << dendl;
}
- STREAM_IO(s)->print("Rgwx-Obj-PG-Ver: %lld\r\n", (long long)pg_ver);
+ dump_header(s, "Rgwx-Obj-PG-Ver", pg_ver);
uint32_t source_zone_short_id = 0;
r = decode_attr_bl_single_value(attrs, RGW_ATTR_SOURCE_ZONE, &source_zone_short_id, (uint32_t)0);
ldout(s->cct, 0) << "ERROR: failed to decode pg ver attr, ignoring" << dendl;
}
if (source_zone_short_id != 0) {
- STREAM_IO(s)->print("Rgwx-Source-Zone-Short-Id: %lld\r\n", (long long)source_zone_short_id);
+ dump_header(s, "Rgwx-Source-Zone-Short-Id", source_zone_short_id);
}
}
* legit to perform GET on them through S3 API. In such situation,
* a client should receive the composited content with corresponding
* etag value. */
- dump_etag(s, lo_etag.c_str());
+ dump_etag(s, lo_etag);
} else {
auto iter = attrs.find(RGW_ATTR_ETAG);
if (iter != attrs.end()) {
- bufferlist& bl = iter->second;
- if (bl.length()) {
- const char * etag = bl.c_str();
- dump_etag(s, etag);
- }
+ dump_etag(s, iter->second);
}
}
sizeof(RGW_ATTR_META_PREFIX)-1) == 0) {
/* User custom metadata. */
name += sizeof(RGW_ATTR_PREFIX) - 1;
- STREAM_IO(s)->print("%s: %s\r\n", name, iter->second.c_str());
+ dump_header(s, name, iter->second);
}
}
}
done:
for (riter = response_attrs.begin(); riter != response_attrs.end();
++riter) {
- STREAM_IO(s)->print("%s: %s\r\n", riter->first.c_str(),
- riter->second.c_str());
+ dump_header(s, riter->first, riter->second);
}
if (op_ret == -ERR_NOT_MODIFIED) {
static void dump_bucket_metadata(struct req_state *s, RGWBucketEnt& bucket)
{
- char buf[32];
- snprintf(buf, sizeof(buf), "%lld", (long long)bucket.count);
- STREAM_IO(s)->print("X-RGW-Object-Count: %s\r\n", buf);
- snprintf(buf, sizeof(buf), "%lld", (long long)bucket.size);
- STREAM_IO(s)->print("X-RGW-Bytes-Used: %s\r\n", buf);
+ dump_header(s, "X-RGW-Object-Count", static_cast<long long>(bucket.count));
+ dump_header(s, "X-RGW-Bytes-Used", static_cast<long long>(bucket.size));
}
void RGWStatBucket_ObjStore_S3::send_response()
}
if (!copy_source) {
dump_errno(s);
- dump_etag(s, etag.c_str());
+ dump_etag(s, etag);
dump_content_length(s, 0);
} else {
dump_errno(s);
set_req_state_err(s, r);
dump_errno(s);
if (!version_id.empty()) {
- dump_string_header(s, "x-amz-version-id", version_id.c_str());
+ dump_header(s, "x-amz-version-id", version_id);
}
if (delete_marker) {
- dump_string_header(s, "x-amz-delete-marker", "true");
+ dump_header(s, "x-amz-delete-marker", "true");
}
end_header(s, this);
}
const RGWQuotaInfo& quota,
const RGWAccessControlPolicy_SWIFTAcct &policy)
{
- char buf[32];
- utime_t now = ceph_clock_now(g_ceph_context);
- snprintf(buf, sizeof(buf), "%0.5f", (double)now);
/* Adding X-Timestamp to keep align with Swift API */
- STREAM_IO(s)->print("X-Timestamp: %s\r\n", buf);
- snprintf(buf, sizeof(buf), "%lld", (long long)buckets_count);
- STREAM_IO(s)->print("X-Account-Container-Count: %s\r\n", buf);
- snprintf(buf, sizeof(buf), "%lld", (long long)buckets_object_count);
- STREAM_IO(s)->print("X-Account-Object-Count: %s\r\n", buf);
- snprintf(buf, sizeof(buf), "%lld", (long long)buckets_size);
- STREAM_IO(s)->print("X-Account-Bytes-Used: %s\r\n", buf);
- snprintf(buf, sizeof(buf), "%lld", (long long)buckets_size_rounded);
- STREAM_IO(s)->print("X-Account-Bytes-Used-Actual: %s\r\n", buf);
+ dump_header(s, "X-Timestamp", ceph_clock_now(g_ceph_context));
+
+ dump_header(s, "X-Account-Container-Count", buckets_count);
+ dump_header(s, "X-Account-Object-Count", buckets_object_count);
+ dump_header(s, "X-Account-Bytes-Used", buckets_size);
+ dump_header(s, "X-Account-Bytes-Used-Actual", buckets_size_rounded);
/* Dump TempURL-related stuff */
if (s->perm_mask == RGW_PERM_FULL_CONTROL) {
auto iter = s->user->temp_url_keys.find(0);
- if (iter != std::end(s->user->temp_url_keys) && !iter->second.empty()) {
- STREAM_IO(s)->print("X-Account-Meta-Temp-Url-Key: %s\r\n",
- iter->second.c_str());
+ if (iter != std::end(s->user->temp_url_keys) && ! iter->second.empty()) {
+ dump_header(s, "X-Account-Meta-Temp-Url-Key", iter->second);
}
iter = s->user->temp_url_keys.find(1);
- if (iter != std::end(s->user->temp_url_keys) && !iter->second.empty()) {
- STREAM_IO(s)->print("X-Account-Meta-Temp-Url-Key-2: %s\r\n",
- iter->second.c_str());
+ if (iter != std::end(s->user->temp_url_keys) && ! iter->second.empty()) {
+ dump_header(s, "X-Account-Meta-Temp-Url-Key-2", iter->second);
}
}
/* Dump quota headers. */
if (quota.enabled) {
if (quota.max_size >= 0) {
- STREAM_IO(s)->print("X-Account-Meta-Quota-Bytes: %lld\r\n",
- (long long)quota.max_size);
+ dump_header(s, "X-Account-Meta-Quota-Bytes", quota.max_size);
}
/* Limit on the number of objects in a given account is a RadosGW's
* extension. Swift's account quota WSGI filter doesn't support it. */
if (quota.max_objects >= 0) {
- STREAM_IO(s)->print("X-Account-Meta-Quota-Count: %lld\r\n",
- (long long)quota.max_objects);
+ dump_header(s, "X-Account-Meta-Quota-Count", quota.max_objects);
}
}
map<string, string>::const_iterator geniter = rgw_to_http_attrs.find(name);
if (geniter != rgw_to_http_attrs.end()) {
- STREAM_IO(s)->print("%s: %s\r\n", geniter->second.c_str(),
- iter->second.c_str());
+ dump_header(s, geniter->second, iter->second);
} else if (strncmp(name, RGW_ATTR_META_PREFIX, PREFIX_LEN) == 0) {
- STREAM_IO(s)->print("X-Account-Meta-%s: %s\r\n",
- camelcase_dash_http_attr(name + PREFIX_LEN).c_str(),
- iter->second.c_str());
+ dump_header_prefixed(s, "X-Account-Meta-",
+ camelcase_dash_http_attr(name + PREFIX_LEN),
+ iter->second);
}
}
string acct_acl;
policy.to_str(acct_acl);
if (acct_acl.size()) {
- STREAM_IO(s)->print("X-Account-Access-Control: %s\r\n", acct_acl.c_str());
+ dump_header(s, "X-Account-Access-Control", std::move(acct_acl));
}
}
const RGWQuotaInfo& quota,
const RGWBucketWebsiteConf& ws_conf)
{
- char buf[32];
/* Adding X-Timestamp to keep align with Swift API */
- utime_t ut(s->bucket_info.creation_time);
- snprintf(buf, sizeof(buf), "%lld.%05d",
- (long long)ut.sec(), (int)(ut.usec() / 10));
- STREAM_IO(s)->print("X-Timestamp: %s\r\n", buf);
- snprintf(buf, sizeof(buf), "%lld", (long long)bucket.count);
- STREAM_IO(s)->print("X-Container-Object-Count: %s\r\n", buf);
- snprintf(buf, sizeof(buf), "%lld", (long long)bucket.size);
- STREAM_IO(s)->print("X-Container-Bytes-Used: %s\r\n", buf);
- snprintf(buf, sizeof(buf), "%lld", (long long)bucket.size_rounded);
- STREAM_IO(s)->print("X-Container-Bytes-Used-Actual: %s\r\n", buf);
+ dump_header(s, "X-Timestamp", utime_t(s->bucket_info.creation_time));
+
+ dump_header(s, "X-Container-Object-Count", bucket.count);
+ dump_header(s, "X-Container-Bytes-Used", bucket.size);
+ dump_header(s, "X-Container-Bytes-Used-Actual", bucket.size_rounded);
if (s->object.empty()) {
- RGWAccessControlPolicy_SWIFT *swift_policy
- = static_cast<RGWAccessControlPolicy_SWIFT *>(s->bucket_acl);
- string read_acl, write_acl;
+ auto swift_policy = static_cast<RGWAccessControlPolicy_SWIFT*>(s->bucket_acl);
+ std::string read_acl, write_acl;
swift_policy->to_str(read_acl, write_acl);
+
if (read_acl.size()) {
- STREAM_IO(s)->print("X-Container-Read: %s\r\n", read_acl.c_str());
+ dump_header(s, "X-Container-Read", read_acl);
}
if (write_acl.size()) {
- STREAM_IO(s)->print("X-Container-Write: %s\r\n", write_acl.c_str());
+ dump_header(s, "X-Container-Write", write_acl);
}
if (!s->bucket_info.placement_rule.empty()) {
- STREAM_IO(s)->print("X-Storage-Policy: %s\r\n",
- s->bucket_info.placement_rule.c_str());
+ dump_header(s, "X-Storage-Policy", s->bucket_info.placement_rule);
}
/* Dump user-defined metadata items and generic attrs. */
map<string, string>::const_iterator geniter = rgw_to_http_attrs.find(name);
if (geniter != rgw_to_http_attrs.end()) {
- STREAM_IO(s)->print("%s: %s\r\n", geniter->second.c_str(),
- iter->second.c_str());
+ dump_header(s, geniter->second, iter->second);
} else if (strncmp(name, RGW_ATTR_META_PREFIX, PREFIX_LEN) == 0) {
- STREAM_IO(s)->print("X-Container-Meta-%s: %s\r\n",
- camelcase_dash_http_attr(name + PREFIX_LEN).c_str(),
- iter->second.c_str());
+ dump_header_prefixed(s, "X-Container-Meta-",
+ camelcase_dash_http_attr(name + PREFIX_LEN),
+ iter->second);
}
}
}
/* Dump container versioning info. */
- if (!s->bucket_info.swift_ver_location.empty()) {
- string encoded_loc;
- url_encode(s->bucket_info.swift_ver_location, encoded_loc);
- STREAM_IO(s)->print("X-Versions-Location: %s\r\n", encoded_loc.c_str());
+ if (! s->bucket_info.swift_ver_location.empty()) {
+ dump_header(s, "X-Versions-Location",
+ url_encode(s->bucket_info.swift_ver_location));
}
/* Dump quota headers. */
if (quota.enabled) {
if (quota.max_size >= 0) {
- STREAM_IO(s)->print("X-Container-Meta-Quota-Bytes: %lld\r\n",
- (long long)quota.max_size);
+ dump_header(s, "X-Container-Meta-Quota-Bytes", quota.max_size);
}
if (quota.max_objects >= 0) {
- STREAM_IO(s)->print("X-Container-Meta-Quota-Count: %lld\r\n",
- (long long)quota.max_objects);
+ dump_header(s, "X-Container-Meta-Quota-Count", quota.max_objects);
}
}
/* Dump Static Website headers. */
if (! ws_conf.index_doc_suffix.empty()) {
- STREAM_IO(s)->print("X-Container-Meta-Web-Index: %s\r\n",
- ws_conf.index_doc_suffix.c_str());
+ dump_header(s, "X-Container-Meta-Web-Index", ws_conf.index_doc_suffix);
}
if (! ws_conf.error_doc.empty()) {
- STREAM_IO(s)->print("X-Container-Meta-Web-Error: %s\r\n",
- ws_conf.error_doc.c_str());
+ dump_header(s, "X-Container-Meta-Web-Error", ws_conf.error_doc);
}
if (! ws_conf.subdir_marker.empty()) {
- STREAM_IO(s)->print("X-Container-Meta-Web-Directory-Type: %s\r\n",
- ws_conf.subdir_marker.c_str());
+ dump_header(s, "X-Container-Meta-Web-Directory-Type",
+ ws_conf.subdir_marker);
}
if (! ws_conf.listing_css_doc.empty()) {
- STREAM_IO(s)->print("X-Container-Meta-Web-Listings-CSS: %s\r\n",
- ws_conf.listing_css_doc.c_str());
+ dump_header(s, "X-Container-Meta-Web-Listings-CSS",
+ ws_conf.listing_css_doc);
}
if (ws_conf.listing_enabled) {
- STREAM_IO(s)->print("X-Container-Meta-Web-Listings: true\r\n");
+ dump_header(s, "X-Container-Meta-Web-Listings", "true");
}
}
* In response for PUT request we have to expose the second one.
* The first one may be obtained by GET with "multipart-manifest=get"
* in query string on a given SLO. */
- dump_etag(s, ("\"" + lo_etag + "\"").c_str());
+ dump_etag(s, ("\"" + lo_etag + "\""));
} else {
- dump_etag(s, etag.c_str());
+ dump_etag(s, etag);
}
dump_last_modified(s, mtime);
} else if (strncmp(name, RGW_ATTR_META_PREFIX,
sizeof(RGW_ATTR_META_PREFIX)-1) == 0) {
name += sizeof(RGW_ATTR_META_PREFIX) - 1;
- STREAM_IO(s)->print("X-Object-Meta-%s: %s\r\n",
- camelcase_dash_http_attr(name).c_str(),
- kv.second.c_str());
+ dump_header_prefixed(s, "X-Object-Meta-",
+ camelcase_dash_http_attr(name), kv.second);
}
}
}
for (const auto kv : response_attrs) {
- STREAM_IO(s)->print("%s: %s\r\n", kv.first.c_str(), kv.second.c_str());
+ dump_header(s, kv.first, kv.second);
}
const auto iter = attrs.find(RGW_ATTR_DELETE_AT);
utime_t delete_at;
try {
::decode(delete_at, iter->second);
- STREAM_IO(s)->print("X-Delete-At: %lu\r\n", delete_at.sec());
+ dump_header(s, "X-Delete-At", delete_at.sec());
} catch (buffer::error& err) {
ldout(s->cct, 0) << "ERROR: cannot decode object's " RGW_ATTR_DELETE_AT
" attr, ignoring"
void RGWCopyObj_ObjStore_SWIFT::dump_copy_info()
{
- /* Dump X-Copied-From */
- string objname, bucketname;
- url_encode(src_object.name, objname);
- url_encode(src_bucket.name, bucketname);
- STREAM_IO(s)->print("X-Copied-From: %s/%s\r\n", bucketname.c_str(),
- objname.c_str());
+ /* Dump X-Copied-From. */
+ dump_header(s, "X-Copied-From", url_encode(src_bucket.name) +
+ "/" + url_encode(src_object.name));
- /* Dump X-Copied-From-Account */
- string account_name;
- url_encode(s->user->user_id.id, account_name); // XXX tenant
- STREAM_IO(s)->print("X-Copied-From-Account: %s\r\n", account_name.c_str());
+ /* Dump X-Copied-From-Account. */
+ /* XXX tenant */
+ dump_header(s, "X-Copied-From-Account", url_encode(s->user->user_id.id));
/* Dump X-Copied-From-Last-Modified. */
dump_time_header(s, "X-Copied-From-Last-Modified", src_mtime);
op_ret = STATUS_CREATED;
set_req_state_err(s, op_ret);
dump_errno(s);
- dump_etag(s, etag.c_str());
+ dump_etag(s, etag);
dump_last_modified(s, mtime);
dump_copy_info();
get_contype_from_attrs(attrs, content_type);
dump_content_length(s, total_len);
dump_last_modified(s, lastmod);
- {
- utime_t ut(lastmod);
- STREAM_IO(s)->print("X-Timestamp: %lld.%05d\r\n", (long long)ut.sec(), (int)(ut.usec() / 10));
- }
+ dump_header(s, "X-Timestamp", utime_t(lastmod));
+
if (is_slo) {
- STREAM_IO(s)->print("X-Static-Large-Object: True\r\n");
+ dump_header(s, "X-Static-Large-Object", "True");
}
if (! op_ret) {
if (!lo_etag.empty()) {
- dump_etag(s, ("\"" + lo_etag + "\"").c_str());
+ dump_etag(s, ("\"" + lo_etag + "\""));
} else {
auto iter = attrs.find(RGW_ATTR_ETAG);
if (iter != attrs.end()) {
- bufferlist& bl = iter->second;
- if (bl.length()) {
- char *etag = bl.c_str();
- dump_etag(s, etag);
- }
+ dump_etag(s, iter->second);
}
}
tenant_path.append(info.user_id.to_str());
}
- STREAM_IO(s)->print("X-Storage-Url: %s%s/v1%s\r\n", swift_url.c_str(),
- swift_prefix.c_str(), tenant_path.c_str());
+ dump_header(s, "X-Storage-Url", swift_url + swift_prefix + "/v1" +
+ tenant_path);
if ((ret = encode_token(s->cct, swift_key->id, swift_key->key, bl)) < 0)
goto done;
{
- char buf[bl.length() * 2 + 1];
- buf_to_hex((const unsigned char *)bl.c_str(), bl.length(), buf);
+ static constexpr std::size_t PREFIX_LEN = strlen("AUTH_rgwtk");
+ char token_val[PREFIX_LEN + bl.length() * 2 + 1];
- STREAM_IO(s)->print("X-Storage-Token: AUTH_rgwtk%s\r\n", buf);
- STREAM_IO(s)->print("X-Auth-Token: AUTH_rgwtk%s\r\n", buf);
+ snprintf(token_val, PREFIX_LEN + 1, "AUTH_rgwtk");
+ buf_to_hex((const unsigned char *)bl.c_str(), bl.length(),
+ token_val + PREFIX_LEN);
+
+ dump_header(s, "X-Storage-Token", token_val);
+ dump_header(s, "X-Auth-Token", token_val);
}
ret = STATUS_NO_CONTENT;