]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: Swift API. Support for X-Remove-Container-Meta-{key} header. 4034/head
authorDmytro Iurchenko <diurchenko@mirantis.com>
Tue, 3 Feb 2015 15:54:38 +0000 (17:54 +0200)
committerLoic Dachary <ldachary@redhat.com>
Thu, 19 Mar 2015 13:26:26 +0000 (14:26 +0100)
Fixes: #10475
Backport: hammer, firefly
Reported-by: Josh Durgin <jdurgin@redhat.com>
Signed-off-by: Dmytro Iurchenko <diurchenko@mirantis.com>
(cherry picked from commit f67bfa24fd6f69c2fcc0987eba8b6b426dd78320)

Conflicts:
src/rgw/rgw_rest.h
        trivial merge: prototype of an unrelated function changed
        src/rgw/rgw_op.cc
        s/is_object_op/!(s->object == NULL)/

src/rgw/rgw_common.h
src/rgw/rgw_op.cc
src/rgw/rgw_op.h
src/rgw/rgw_rest.cc
src/rgw/rgw_rest.h
src/rgw/rgw_rest_swift.cc

index c87169ab337edfcc7512bd669d49ac9284d9a9c9..52a7c4618338303bccefc0b485422a4dd992fe83 100644 (file)
@@ -849,7 +849,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);
 };
 
 /** Store all the state necessary to complete and respond to an HTTP request*/
index 492ebab59eea7f61fcd0cdfb766c4294080812b5..472902c97a1710d174970a10fc00541f717e7c4e 100644 (file)
@@ -1904,11 +1904,24 @@ void RGWPutMetadata::execute()
     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;
     }
index d3b227e3ebaa1f3bd3f663fbec4ec6edd10c8431..97dad7c8936238393322bd7fcf3f35d4f396d660 100644 (file)
@@ -14,6 +14,7 @@
 #include <limits.h>
 
 #include <string>
+#include <set>
 #include <map>
 
 #include "rgw_common.h"
@@ -415,7 +416,7 @@ public:
 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;
index 0c2701441a709d3fd73435d0c07d200744d9820a..6165d10215bfa2267de8b43ed1cffcdd3d196d5b 100644 (file)
@@ -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);
@@ -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);
@@ -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);
index 36dc7ce42ddecc7dffab39a04adf8f884b23f618..1035bfef7bf8d6308d9d433d209c148fd692a842 100644 (file)
@@ -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);
 
 extern void rgw_flush_formatter_and_reset(struct req_state *s,
index 1083a371a8b19564f35bd823fbb43490f4e2a28c..bf6db2adb2b180842fcc434c5ab22c4421d30dc9 100644 (file)
@@ -426,6 +426,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)
@@ -436,6 +441,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);
+      }
+    }
   }
 
   return 0;