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);
};
/** Store all the state necessary to complete and respond to an HTTP request*/
orig_attrs = s->bucket_attrs;
}
- /* 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 (!(s->object == NULL)) {
+ /* 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;
}
#include <limits.h>
#include <string>
+#include <set>
#include <map>
#include "rgw_common.h"
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;
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);
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);
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);
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);
extern void rgw_flush_formatter_and_reset(struct req_state *s,
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)
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);
+ }
+ }
}
return 0;