From 4f9a84310e847f10b6c3d0fc573e6dd06bc095c6 Mon Sep 17 00:00:00 2001 From: Radoslaw Zarzynski Date: Mon, 18 May 2015 16:54:34 +0200 Subject: [PATCH] rgw: add basic support for X-Delete-At header of Swift API. Fixes: #4099 Signed-off-by: Radoslaw Zarzynski --- src/rgw/rgw_op.cc | 20 ++++++++++++++++++++ src/rgw/rgw_op.h | 2 ++ src/rgw/rgw_rest_swift.cc | 27 +++++++++++++++++++++++++++ src/rgw/rgw_rest_swift.h | 1 + 4 files changed, 50 insertions(+) diff --git a/src/rgw/rgw_op.cc b/src/rgw/rgw_op.cc index c3827714d0f1e..35a49b0e2b509 100644 --- a/src/rgw/rgw_op.cc +++ b/src/rgw/rgw_op.cc @@ -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); } diff --git a/src/rgw/rgw_op.h b/src/rgw/rgw_op.h index 32e8c80fe4974..61d8c019fef5a 100644 --- a/src/rgw/rgw_op.h +++ b/src/rgw/rgw_op.h @@ -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() diff --git a/src/rgw/rgw_rest_swift.cc b/src/rgw/rgw_rest_swift.cc index 39dee7867d329..e3377d326678b 100644 --- a/src/rgw/rgw_rest_swift.cc +++ b/src/rgw/rgw_rest_swift.cc @@ -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() diff --git a/src/rgw/rgw_rest_swift.h b/src/rgw/rgw_rest_swift.h index 22283e468a0d2..a2838c7847170 100644 --- a/src/rgw/rgw_rest_swift.h +++ b/src/rgw/rgw_rest_swift.h @@ -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 { -- 2.39.5