Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rgw: Swift API. Dump container's custom metadata. #3561

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion doc/radosgw/swift/auth.rst
Expand Up @@ -7,7 +7,7 @@ Swift API requests that require authentication must contain an
The token may be retrieved from RADOS Gateway, or from another authenticator.
To obtain a token from RADOS Gateway, you must create a user. For example::

sudo radosgw-admin user create --uid="{username}" --displayname="{Display Name}"
sudo radosgw-admin user create --uid="{username}" --display-name="{Display Name}"

For details on RADOS Gateway administration, see `radosgw-admin`_.

Expand Down
2 changes: 1 addition & 1 deletion src/rgw/rgw_common.h
Expand Up @@ -918,7 +918,7 @@ struct req_info {

req_info(CephContext *cct, RGWEnv *_env);
void rebuild_from(req_info& src);
void init_meta_info(bool *found_nad_meta);
void init_meta_info(bool *found_bad_meta);
};

struct rgw_obj_key {
Expand Down
17 changes: 15 additions & 2 deletions src/rgw/rgw_op.cc
Expand Up @@ -2050,11 +2050,24 @@ void RGWPutMetadata::execute()
}
}

/* only remove meta attrs */
for (iter = orig_attrs.begin(); iter != orig_attrs.end(); ++iter) {
const string& name = iter->first;
/* check if the attr is user-defined metadata item */
if (name.compare(0, meta_prefix_len, meta_prefix) == 0) {
rmattrs[name] = iter->second;
if (is_object_op) {
/* for the objects all existing meta attrs have to be removed */
rmattrs[name] = iter->second;
} else {
/* for the buckets all existing meta attrs are preserved,
except those that are listed in rmattr_names. */
if (rmattr_names.find(name) != rmattr_names.end()) {
map<string, bufferlist>::iterator aiter = attrs.find(name);
if (aiter != attrs.end()) {
attrs.erase(aiter);
}
rmattrs[name] = iter->second;
}
}
} else if (attrs.find(name) == attrs.end()) {
attrs[name] = iter->second;
}
Expand Down
3 changes: 2 additions & 1 deletion src/rgw/rgw_op.h
Expand Up @@ -14,6 +14,7 @@
#include <limits.h>

#include <string>
#include <set>
#include <map>

#include "rgw_common.h"
Expand Down Expand Up @@ -498,7 +499,7 @@ class RGWPostObj : public RGWOp {
class RGWPutMetadata : public RGWOp {
protected:
int ret;
map<string, bufferlist> attrs;
set<string> rmattr_names;
bool has_policy, has_cors;
RGWAccessControlPolicy policy;
RGWCORSConfiguration cors_config;
Expand Down
50 changes: 36 additions & 14 deletions src/rgw/rgw_rest.cc
Expand Up @@ -79,10 +79,10 @@ string lowercase_underscore_http_attr(const string& orig)
for (size_t i = 0; i < orig.size(); ++i, ++s) {
switch (*s) {
case '-':
buf[i] = '_';
break;
buf[i] = '_';
break;
default:
buf[i] = tolower(*s);
buf[i] = tolower(*s);
}
}
return string(buf);
Expand All @@ -101,10 +101,32 @@ string uppercase_underscore_http_attr(const string& orig)
for (size_t i = 0; i < orig.size(); ++i, ++s) {
switch (*s) {
case '-':
buf[i] = '_';
break;
buf[i] = '_';
break;
default:
buf[i] = toupper(*s);
buf[i] = toupper(*s);
}
}
return string(buf);
}

/*
* make attrs look-like-this
* converts underscores to dashes
*/
string lowercase_dash_http_attr(const string& orig)
{
const char *s = orig.c_str();
char buf[orig.size() + 1];
buf[orig.size()] = '\0';

for (size_t i = 0; i < orig.size(); ++i, ++s) {
switch (*s) {
case '_':
buf[i] = '-';
break;
default:
buf[i] = tolower(*s);
}
}
return string(buf);
Expand All @@ -125,15 +147,15 @@ string camelcase_dash_http_attr(const string& orig)
for (size_t i = 0; i < orig.size(); ++i, ++s) {
switch (*s) {
case '_':
buf[i] = '-';
last_sep = true;
break;
buf[i] = '-';
last_sep = true;
break;
default:
if (last_sep)
buf[i] = toupper(*s);
else
buf[i] = tolower(*s);
last_sep = false;
if (last_sep)
buf[i] = toupper(*s);
else
buf[i] = tolower(*s);
last_sep = false;
}
}
return string(buf);
Expand Down
2 changes: 2 additions & 0 deletions src/rgw/rgw_rest.h
Expand Up @@ -13,6 +13,8 @@

extern std::map<std::string, std::string> rgw_to_http_attrs;

extern string lowercase_dash_http_attr(const string& orig);

extern void rgw_rest_init(CephContext *cct, RGWRegion& region);

extern void rgw_flush_formatter_and_reset(struct req_state *s,
Expand Down
46 changes: 40 additions & 6 deletions src/rgw/rgw_rest_swift.cc
Expand Up @@ -245,6 +245,17 @@ static void dump_container_metadata(struct req_state *s, RGWBucketEnt& bucket)
if (!s->bucket_info.placement_rule.empty()) {
s->cio->print("X-Storage-Policy: %s\r\n", s->bucket_info.placement_rule.c_str());
}
// Dump user-defined metadata items
const size_t PREFIX_LEN = sizeof(RGW_ATTR_META_PREFIX) - 1;
map<string, bufferlist>::iterator iter;
for (iter = s->bucket_attrs.lower_bound(RGW_ATTR_META_PREFIX); iter != s->bucket_attrs.end(); ++iter) {
const char *name = iter->first.c_str();
if (strncmp(name, RGW_ATTR_META_PREFIX, PREFIX_LEN) == 0) {
s->cio->print("X-Container-Meta-%s: %s\r\n", name + PREFIX_LEN, iter->second.c_str());
} else {
break;
}
}
}
}

Expand Down Expand Up @@ -431,6 +442,11 @@ void RGWPutObj_ObjStore_SWIFT::send_response()
rgw_flush_formatter_and_reset(s, s->formatter);
}

#define REMOVE_ATTR_PREFIX "HTTP_X_REMOVE_CONTAINER_META_"
#define PUT_ATTR_PREFIX "HTTP_X_CONTAINER_META_"
#define REMOVE_ATTR_PREFIX_LEN sizeof(REMOVE_ATTR_PREFIX) - 1
#define PUT_ATTR_PREFIX_LEN sizeof(PUT_ATTR_PREFIX) - 1

int RGWPutMetadata_ObjStore_SWIFT::get_params()
{
if (s->has_bad_meta)
Expand All @@ -441,6 +457,24 @@ int RGWPutMetadata_ObjStore_SWIFT::get_params()
if (r < 0) {
return r;
}
map<string, string, ltstr_nocase>& m = s->info.env->get_map();
map<string, string, ltstr_nocase>::iterator iter;
for (iter = m.begin(); iter != m.end(); ++iter) {
size_t prefix_len = 0;
const char *p = iter->first.c_str();
if (strncasecmp(p, REMOVE_ATTR_PREFIX, REMOVE_ATTR_PREFIX_LEN) == 0) {
// Explicitly requested removal
prefix_len = REMOVE_ATTR_PREFIX_LEN;
} else if ((strncasecmp(p, PUT_ATTR_PREFIX, PUT_ATTR_PREFIX_LEN) == 0) && iter->second.empty()) {
// Removal requested by putting an empty value
prefix_len = PUT_ATTR_PREFIX_LEN;
}
if (prefix_len > 0) {
string name(RGW_ATTR_META_PREFIX);
name.append(lowercase_dash_http_attr(p + prefix_len));
rmattr_names.insert(name);
}
}
}
placement_rule = s->info.env->get("HTTP_X_STORAGE_POLICY", "");

Expand Down Expand Up @@ -592,15 +626,15 @@ int RGWGetObj_ObjStore_SWIFT::send_response_data(bufferlist& bl, off_t bl_ofs, o
const char *name = iter->first.c_str();
map<string, string>::iterator aiter = rgw_to_http_attrs.find(name);
if (aiter != rgw_to_http_attrs.end()) {
if (aiter->first.compare(RGW_ATTR_CONTENT_TYPE) == 0) { // special handling for content_type
content_type = iter->second.c_str();
continue;
if (aiter->first.compare(RGW_ATTR_CONTENT_TYPE) == 0) { // special handling for content_type
content_type = iter->second.c_str();
continue;
}
response_attrs[aiter->second] = iter->second.c_str();
} else {
if (strncmp(name, RGW_ATTR_META_PREFIX, sizeof(RGW_ATTR_META_PREFIX)-1) == 0) {
name += sizeof(RGW_ATTR_META_PREFIX) - 1;
s->cio->print("X-%s-Meta-%s: %s\r\n", (!s->object.empty() ? "Object" : "Container"), name, iter->second.c_str());
s->cio->print("X-Object-Meta-%s: %s\r\n", name, iter->second.c_str());
}
}
}
Expand Down Expand Up @@ -647,7 +681,7 @@ void RGWOptionsCORS_ObjStore_SWIFT::send_response()
}
get_response_params(hdrs, exp_hdrs, &max_age);
dump_errno(s);
dump_access_control(s, origin, req_meth, hdrs.c_str(), exp_hdrs.c_str(), max_age);
dump_access_control(s, origin, req_meth, hdrs.c_str(), exp_hdrs.c_str(), max_age);
end_header(s, NULL);
}

Expand Down Expand Up @@ -924,7 +958,7 @@ int RGWHandler_ObjStore_SWIFT::init_from_header(struct req_state *s)
return 0;

s->bucket_name_str = first;

s->info.effective_uri = "/" + s->bucket_name_str;

if (req.size()) {
Expand Down