if_match,
if_nomatch,
attrs_mod,
+ copy_if_newer,
attrs, RGW_OBJ_CATEGORY_MAIN,
olh_epoch,
(version_id.empty() ? NULL : &version_id),
string version_id;
uint64_t olh_epoch;
+ bool copy_if_newer;
int init_common();
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);
const char *if_match,
const char *if_nomatch,
AttrsMod attrs_mod,
+ bool copy_if_newer,
map<string, bufferlist>& attrs,
RGWObjCategory category,
uint64_t olh_epoch,
string etag;
map<string, string> 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;
}
const char *if_match,
const char *if_nomatch,
AttrsMod attrs_mod,
+ bool copy_if_newer,
map<string, bufferlist>& attrs,
RGWObjCategory category,
uint64_t olh_epoch,
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);
}
const char *if_match,
const char *if_nomatch,
AttrsMod attrs_mod,
+ bool copy_if_newer,
map<string, bufferlist>& attrs,
RGWObjCategory category,
uint64_t olh_epoch,
const char *if_match,
const char *if_nomatch,
AttrsMod attrs_mod,
+ bool copy_if_newer,
map<std::string, bufferlist>& attrs,
RGWObjCategory category,
uint64_t olh_epoch,
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<string, string>& 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);
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);
}
map<string, bufferlist>& 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<string, string>& attrs);
};
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");