return string::npos;
}
+static inline string rgw_bl_str(ceph::buffer::list& raw)
+{
+ size_t len = raw.length();
+ string s(raw.c_str(), len);
+ while (len && !s[len - 1]) {
+ --len;
+ s.resize(len);
+ }
+ return s;
+}
+
#endif
op.setxattr(name.c_str(), bl);
if (name.compare(RGW_ATTR_ETAG) == 0) {
- etag = bl.to_str();
+ etag = rgw_bl_str(bl);
} else if (name.compare(RGW_ATTR_CONTENT_TYPE) == 0) {
- content_type = bl.to_str();
+ content_type = rgw_bl_str(bl);
} else if (name.compare(RGW_ATTR_ACL) == 0) {
acl_bl = bl;
}
bufferlist acl_bl = attrs[RGW_ATTR_ACL];
bufferlist etag_bl = attrs[RGW_ATTR_ETAG];
bufferlist content_type_bl = attrs[RGW_ATTR_CONTENT_TYPE];
- string etag(etag_bl.c_str(), etag_bl.length());
- string content_type(content_type_bl.c_str(), content_type_bl.length());
+ string etag = rgw_bl_str(etag_bl);
+ string content_type = rgw_bl_str(content_type_bl);
string storage_class;
auto iter = attrs.find(RGW_ATTR_STORAGE_CLASS);
if (iter != attrs.end()) {
- storage_class = iter->second.to_str();
+ storage_class = rgw_bl_str(iter->second);
}
uint64_t epoch = ref.ioctx.get_last_version();
int64_t poolid = ref.ioctx.get_id();
map<string, bufferlist>::iterator iter = astate->attrset.find(RGW_ATTR_ETAG);
if (iter != astate->attrset.end()) {
- etag = iter->second.to_str();
+ etag = rgw_bl_str(iter->second);
}
iter = astate->attrset.find(RGW_ATTR_CONTENT_TYPE);
if (iter != astate->attrset.end()) {
- content_type = iter->second.to_str();
+ content_type = rgw_bl_str(iter->second);
}
iter = astate->attrset.find(RGW_ATTR_ACL);
if (iter != astate->attrset.end()) {
}
}
-static inline boost::string_ref get_sanitized_hdrval(ceph::buffer::list& raw)
-{
- /* std::string and thus boost::string_ref ARE OBLIGED to carry multiple
- * 0x00 and count them to the length of a string. We need to take that
- * into consideration and sanitize the size of a ceph::buffer::list used
- * to store metadata values (x-amz-meta-*, X-Container-Meta-*, etags).
- * Otherwise we might send 0x00 to clients. */
- const char* const data = raw.c_str();
- size_t len = raw.length();
-
- if (len && data[len - 1] == '\0') {
- /* That's the case - the null byte has been included at the last position
- * of the bufferlist. We need to restore the proper string length we'll
- * pass to string_ref. */
- len--;
- }
-
- return boost::string_ref(data, len);
-}
-
void dump_header(struct req_state* const s,
const boost::string_ref& name,
ceph::buffer::list& bl)
{
- return dump_header(s, name, get_sanitized_hdrval(bl));
+ return dump_header(s, name, rgw_sanitized_hdrval(bl));
}
void dump_header(struct req_state* const s,
const uint64_t max_len,
const bool allow_chunked=true);
+static inline boost::string_ref rgw_sanitized_hdrval(ceph::buffer::list& raw)
+{
+ /* std::string and thus boost::string_ref ARE OBLIGED to carry multiple
+ * 0x00 and count them to the length of a string. We need to take that
+ * into consideration and sanitize the size of a ceph::buffer::list used
+ * to store metadata values (x-amz-meta-*, X-Container-Meta-*, etags).
+ * Otherwise we might send 0x00 to clients. */
+ const char* const data = raw.c_str();
+ size_t len = raw.length();
+
+ if (len && data[len - 1] == '\0') {
+ /* That's the case - the null byte has been included at the last position
+ * of the bufferlist. We need to restore the proper string length we'll
+ * pass to string_ref. */
+ len--;
+ }
+
+ return boost::string_ref(data, len);
+}
+
template <class T>
int rgw_rest_get_json_input(CephContext *cct, req_state *s, T& out,
uint64_t max_len, bool *empty)
if (response_attrs.count(aiter->second) == 0) {
/* Was not already overridden by a response param. */
- /* clean up attribute, we have cases where we kept extra null character
- * at the end of the buffer, so bufferlist.to_str() won't work because
- * it'll generate a string with that extra character
- */
- auto& buf = iter->second;
- const char *val = buf.c_str();
- size_t len = buf.length();
- while (len > 0 && !val[len - 1]) {
+ size_t len = iter->second.length();
+ string s(iter->second.c_str(), len);
+ while (len && !s[len - 1]) {
--len;
+ s.resize(len);
}
- response_attrs[aiter->second] = string(val, len);
+ response_attrs[aiter->second] = s;
}
} else if (iter->first.compare(RGW_ATTR_CONTENT_TYPE) == 0) {
/* Special handling for content_type. */
if (!content_type) {
- content_type = iter->second.c_str();
+ content_type_str = rgw_bl_str(iter->second);
+ content_type = content_type_str.c_str();
}
} else if (strcmp(name, RGW_ATTR_SLO_UINDICATOR) == 0) {
// this attr has an extra length prefix from encode() in prior versions
{
map<string, bufferlist>::iterator iter = attrs.find(RGW_ATTR_CONTENT_TYPE);
if (iter != attrs.end()) {
- content_type = iter->second.c_str();
+ content_type = rgw_bl_str(iter->second);
}
}
static void dump_object_metadata(struct req_state * const s,
- map<string, bufferlist> attrs)
+ const map<string, bufferlist>& attrs)
{
map<string, string> response_attrs;
const auto aiter = rgw_to_http_attrs.find(name);
if (aiter != std::end(rgw_to_http_attrs)) {
- response_attrs[aiter->second] = kv.second.c_str();
+ response_attrs[aiter->second] = rgw_bl_str(kv.second);
} else if (strcmp(name, RGW_ATTR_SLO_UINDICATOR) == 0) {
// this attr has an extra length prefix from encode() in prior versions
dump_header(s, "X-Object-Meta-Static-Large-Object", "True");