]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: Swift API. Support for X-Remove-Container-Meta-{key} header. 3929/head
authorDmytro Iurchenko <diurchenko@mirantis.com>
Tue, 3 Feb 2015 15:54:38 +0000 (17:54 +0200)
committerLoic Dachary <ldachary@redhat.com>
Tue, 10 Mar 2015 23:35:55 +0000 (00:35 +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
        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 432e82a39790c61faedd49a4b7437d1f35a20de3..975bb9dbc63dffb0e6c6b3c55e33ca8e1b007c3d 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 4cc12eabb3884ed4b19c8315baae0968b03df174..d436e3a67e06877a0d21e42a78e2a442976dfd48 100644 (file)
@@ -1895,11 +1895,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 bd6f96401d1ab040b0b47da63b6dba2214913c40..98922f767cc0eaa2c1e438b51bf8d2eb53abdeff 100644 (file)
@@ -14,6 +14,7 @@
 #include <limits.h>
 
 #include <string>
+#include <set>
 #include <map>
 
 #include "rgw_common.h"
@@ -402,7 +403,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 59026fbc3395dc5016afcdf86b3e262ddba817bc..a907decf063d5ed4a994a50d9d2a9ac369f5f9fa 100644 (file)
@@ -76,10 +76,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);
@@ -98,10 +98,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);
@@ -122,15 +144,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 d42ec8d1a02a3cc1ad3706057969a784dd87e6ba..a6108f4e75a7b33d925e4c748abc4e4348f25190 100644 (file)
@@ -12,6 +12,8 @@ extern std::map<std::string, std::string> rgw_to_http_attrs;
 
 extern void rgw_rest_init(CephContext *cct);
 
+extern string lowercase_dash_http_attr(const string& orig);
+
 extern void rgw_flush_formatter_and_reset(struct req_state *s,
                                         ceph::Formatter *formatter);
 
index 36544dbb5bfd406f04328e909fc630df9f2f06c2..ab3c142fda5c4b5bcd09777e6c1f1b5337ccb6d4 100644 (file)
@@ -424,6 +424,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)
@@ -434,6 +439,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;