From: Yehuda Sadeh Date: Wed, 25 Mar 2015 03:16:02 +0000 (-0700) Subject: rgw: add rgwx-copy-if-newer http header X-Git-Tag: v0.94.8~33^2~4 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=5e4de5ad66dc24b059ef19664d1eef22be6890f7;p=ceph.git rgw: add rgwx-copy-if-newer http header Similar to IF_MOD_SINCE, but does not take a time argument, and should protected against races (not there yet). Signed-off-by: Yehuda Sadeh (cherry picked from commit 8813a4401198636e0f4d3a220a0f726625a5c5d4) --- diff --git a/src/rgw/rgw_op.cc b/src/rgw/rgw_op.cc index cd8785f19de..2a73c0220bb 100644 --- a/src/rgw/rgw_op.cc +++ b/src/rgw/rgw_op.cc @@ -2433,6 +2433,7 @@ void RGWCopyObj::execute() if_match, if_nomatch, attrs_mod, + copy_if_newer, attrs, RGW_OBJ_CATEGORY_MAIN, olh_epoch, (version_id.empty() ? NULL : &version_id), diff --git a/src/rgw/rgw_op.h b/src/rgw/rgw_op.h index c4a64aec77b..fd83401f5a5 100644 --- a/src/rgw/rgw_op.h +++ b/src/rgw/rgw_op.h @@ -602,6 +602,7 @@ protected: string version_id; uint64_t olh_epoch; + bool copy_if_newer; int init_common(); @@ -624,6 +625,7 @@ public: attrs_mod = RGWRados::ATTRSMOD_NONE; last_ofs = 0; olh_epoch = 0; + copy_if_newer = false; } static bool parse_copy_location(const string& src, string& bucket_name, rgw_obj_key& object); diff --git a/src/rgw/rgw_rados.cc b/src/rgw/rgw_rados.cc index 05c41ef4c33..1cafe180d04 100644 --- a/src/rgw/rgw_rados.cc +++ b/src/rgw/rgw_rados.cc @@ -3777,6 +3777,7 @@ int RGWRados::fetch_remote_obj(RGWObjectCtx& obj_ctx, const char *if_match, const char *if_nomatch, AttrsMod attrs_mod, + bool copy_if_newer, map& attrs, RGWObjCategory category, uint64_t olh_epoch, @@ -3837,8 +3838,26 @@ int RGWRados::fetch_remote_obj(RGWObjectCtx& obj_ctx, string etag; map req_headers; time_t set_mtime; + + RGWObjState *dest_state = NULL; + + time_t dest_mtime; + const time_t *pmod = mod_ptr; + + if (copy_if_newer) { + /* need to get mtime for destination */ + ret = get_obj_state(&obj_ctx, dest_obj, &dest_state, NULL); + if (ret < 0) + return ret; + + if (dest_state->exists) { + dest_mtime = dest_state->mtime; + pmod = &dest_mtime; + } + } + - ret = conn->get_obj(user_id, info, src_obj, true, &cb, &in_stream_req); + ret = conn->get_obj(user_id, info, src_obj, pmod, unmod_ptr, true, &cb, &in_stream_req); if (ret < 0) { goto set_err_state; } @@ -3959,6 +3978,7 @@ int RGWRados::copy_obj(RGWObjectCtx& obj_ctx, const char *if_match, const char *if_nomatch, AttrsMod attrs_mod, + bool copy_if_newer, map& attrs, RGWObjCategory category, uint64_t olh_epoch, @@ -3993,7 +4013,7 @@ int RGWRados::copy_obj(RGWObjectCtx& obj_ctx, if (remote_src || !source_zone.empty()) { return fetch_remote_obj(obj_ctx, user_id, client_id, op_id, info, source_zone, dest_obj, src_obj, dest_bucket_info, src_bucket_info, src_mtime, mtime, mod_ptr, - unmod_ptr, if_match, if_nomatch, attrs_mod, attrs, category, + unmod_ptr, if_match, if_nomatch, attrs_mod, copy_if_newer, attrs, category, olh_epoch, version_id, ptag, petag, err, progress_cb, progress_data); } diff --git a/src/rgw/rgw_rados.h b/src/rgw/rgw_rados.h index 37c7e8a731d..b7977a51c6e 100644 --- a/src/rgw/rgw_rados.h +++ b/src/rgw/rgw_rados.h @@ -1767,6 +1767,7 @@ public: const char *if_match, const char *if_nomatch, AttrsMod attrs_mod, + bool copy_if_newer, map& attrs, RGWObjCategory category, uint64_t olh_epoch, @@ -1814,6 +1815,7 @@ public: const char *if_match, const char *if_nomatch, AttrsMod attrs_mod, + bool copy_if_newer, map& attrs, RGWObjCategory category, uint64_t olh_epoch, diff --git a/src/rgw/rgw_rest_conn.cc b/src/rgw/rgw_rest_conn.cc index cbffad0b674..0e31a0f8a35 100644 --- a/src/rgw/rgw_rest_conn.cc +++ b/src/rgw/rgw_rest_conn.cc @@ -78,8 +78,21 @@ int RGWRESTConn::complete_request(RGWRESTStreamWriteRequest *req, string& etag, return ret; } -int RGWRESTConn::get_obj(const string& uid, req_info *info /* optional */, rgw_obj& obj, bool prepend_metadata, - RGWGetDataCB *cb, RGWRESTStreamReadRequest **req) +static void set_date_header(const time_t *t, map& headers, const string& header_name) +{ + if (!t) { + return; + } + stringstream s; + utime_t tm = utime_t(*t, 0); + tm.asctime(s); + headers["HTTP_IF_MODIFIED_SINCE"] = s.str(); +} + + +int RGWRESTConn::get_obj(const string& uid, req_info *info /* optional */, rgw_obj& obj, + const time_t *mod_ptr, const time_t *unmod_ptr, + bool prepend_metadata, RGWGetDataCB *cb, RGWRESTStreamReadRequest **req) { string url; int ret = get_url(url); @@ -108,6 +121,10 @@ int RGWRESTConn::get_obj(const string& uid, req_info *info /* optional */, rgw_o extra_headers[iter->first] = iter->second; } } + + set_date_header(mod_ptr, extra_headers, "HTTP_IF_MODIFIED_SINCE"); + set_date_header(unmod_ptr, extra_headers, "HTTP_IF_UNMODIFIED_SINCE"); + return (*req)->get_obj(key, extra_headers, obj); } diff --git a/src/rgw/rgw_rest_conn.h b/src/rgw/rgw_rest_conn.h index 209ddcf9892..b39e570d7f2 100644 --- a/src/rgw/rgw_rest_conn.h +++ b/src/rgw/rgw_rest_conn.h @@ -30,7 +30,9 @@ public: map& attrs, RGWRESTStreamWriteRequest **req); int complete_request(RGWRESTStreamWriteRequest *req, string& etag, time_t *mtime); - int get_obj(const string& uid, req_info *info /* optional */, rgw_obj& obj, bool prepend_metadata, RGWGetDataCB *cb, RGWRESTStreamReadRequest **req); + int get_obj(const string& uid, req_info *info /* optional */, rgw_obj& obj, + const time_t *mod_ptr, const time_t *unmod_ptr, + bool prepend_metadata, RGWGetDataCB *cb, RGWRESTStreamReadRequest **req); int complete_request(RGWRESTStreamReadRequest *req, string& etag, time_t *mtime, map& attrs); }; diff --git a/src/rgw/rgw_rest_s3.cc b/src/rgw/rgw_rest_s3.cc index 0cc7793ac9a..23d0c9d5ff2 100644 --- a/src/rgw/rgw_rest_s3.cc +++ b/src/rgw/rgw_rest_s3.cc @@ -1463,6 +1463,7 @@ int RGWCopyObj_ObjStore_S3::get_params() if (s->system_request) { source_zone = s->info.args.get(RGW_SYS_PARAM_PREFIX "source-zone"); + s->info.args.get_bool(RGW_SYS_PARAM_PREFIX "copy-if-newer", ©_if_newer, false); if (!source_zone.empty()) { client_id = s->info.args.get(RGW_SYS_PARAM_PREFIX "client-id"); op_id = s->info.args.get(RGW_SYS_PARAM_PREFIX "op-id");