]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: add basic support for X-Delete-At header of Swift API.
authorRadoslaw Zarzynski <rzarzynski@mirantis.com>
Mon, 18 May 2015 14:54:34 +0000 (16:54 +0200)
committerYehuda Sadeh <yehuda@redhat.com>
Thu, 27 Aug 2015 18:36:48 +0000 (11:36 -0700)
Fixes: #4099
Signed-off-by: Radoslaw Zarzynski <rzarzynski@mirantis.com>
src/rgw/rgw_op.cc
src/rgw/rgw_op.h
src/rgw/rgw_rest_swift.cc
src/rgw/rgw_rest_swift.h

index c3827714d0f1e9e8f10722774b53de420a54f7a2..35a49b0e2b5094f1cd45a0bba1b9ea6283ad68db 100644 (file)
@@ -962,6 +962,19 @@ void RGWGetObj::execute()
     return;
   }
 
+  /* Check whether the object has expired. Swift API documentation
+   * stands that we should return 404 Not Found in such case. */
+  attr_iter = attrs.find(RGW_ATTR_DELETE_AT);
+  if (need_object_expiration() && attr_iter != attrs.end()) {
+    utime_t delete_at;
+    ::decode(delete_at, attr_iter->second);
+
+    if (delete_at <= ceph_clock_now(g_ceph_context)) {
+      ret = -ENOENT;
+      goto done_err;
+    }
+  }
+
   ofs = new_ofs;
   end = new_end;
 
@@ -2339,6 +2352,13 @@ void RGWPutMetadataObject::execute()
   /* Filter currently existing attributes. */
   prepare_add_del_attrs(orig_attrs, attrs, rmattrs);
   populate_with_generic_attrs(s, attrs);
+
+  if (!delete_at.is_zero()) {
+    bufferlist delatbl;
+    ::encode(delete_at, delatbl);
+    attrs[RGW_ATTR_DELETE_AT] = delatbl;
+  }
+
   ret = store->set_attrs(s->obj_ctx, obj, attrs, &rmattrs, NULL);
 }
 
index 32e8c80fe49742217b440a7e0125bc24911a5f8b..61d8c019fef5a21ec5ad20d5963118cb06a5225e 100644 (file)
@@ -180,6 +180,7 @@ public:
   virtual const string name() { return "get_obj"; }
   virtual RGWOpType get_type() { return RGW_OP_GET_OBJ; }
   virtual uint32_t op_mask() { return RGW_OP_TYPE_READ; }
+  virtual bool need_object_expiration() { return false; }
 };
 
 #define RGW_LIST_BUCKETS_LIMIT_MAX 10000
@@ -578,6 +579,7 @@ protected:
   int ret;
   RGWAccessControlPolicy policy;
   string placement_rule;
+  utime_t delete_at;
 
 public:
   RGWPutMetadataObject()
index 39dee7867d3290b7265016d7f72861b7dd276746..e3377d326678bee673e75310b93b401aadc271f1 100644 (file)
@@ -620,6 +620,26 @@ int RGWPutMetadataObject_ObjStore_SWIFT::get_params()
     return -EINVAL;
   }
 
+  /* Handle Swift object expiration. */
+  utime_t delat_proposal;
+  string x_delete = s->info.env->get("HTTP_X_DELETE_AT", "");
+
+  if (!x_delete.empty()) {
+    string err;
+    long ts = strict_strtoll(x_delete.c_str(), 10, &err);
+
+    if (!err.empty()) {
+      return -EINVAL;
+    }
+
+    delat_proposal += utime_t(ts, 0);
+    if (delat_proposal < ceph_clock_now(g_ceph_context)) {
+      return -EINVAL;
+    }
+
+    delete_at = delat_proposal;
+  }
+
   placement_rule = s->info.env->get("HTTP_X_STORAGE_POLICY", "");
   return 0;
 }
@@ -683,6 +703,13 @@ static void dump_object_metadata(struct req_state * const s,
   for (riter = response_attrs.begin(); riter != response_attrs.end(); ++riter) {
     s->cio->print("%s: %s\r\n", riter->first.c_str(), riter->second.c_str());
   }
+
+  iter = attrs.find(RGW_ATTR_DELETE_AT);
+  if (iter != attrs.end()) {
+    utime_t delete_at;
+    ::decode(delete_at, iter->second);
+    s->cio->print("X-Delete-At: %lu\r\n", delete_at.sec());
+  }
 }
 
 int RGWCopyObj_ObjStore_SWIFT::init_dest_policy()
index 22283e468a0d2426c46672949c2f4d7244994085..a2838c7847170bb9cc69d798bc1e8e6fa28de47f 100644 (file)
@@ -14,6 +14,7 @@ public:
   ~RGWGetObj_ObjStore_SWIFT() {}
 
   int send_response_data(bufferlist& bl, off_t ofs, off_t len);
+  bool need_object_expiration() { return true; }
 };
 
 class RGWListBuckets_ObjStore_SWIFT : public RGWListBuckets_ObjStore {