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;
/* 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);
}
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
int ret;
RGWAccessControlPolicy policy;
string placement_rule;
+ utime_t delete_at;
public:
RGWPutMetadataObject()
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;
}
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()
~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 {