]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: add rgwx-copy-if-newer http header
authorYehuda Sadeh <yehuda@redhat.com>
Wed, 25 Mar 2015 03:16:02 +0000 (20:16 -0700)
committerCasey Bodley <cbodley@redhat.com>
Fri, 10 Jun 2016 12:59:50 +0000 (08:59 -0400)
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 <yehuda@redhat.com>
(cherry picked from commit 8813a4401198636e0f4d3a220a0f726625a5c5d4)

src/rgw/rgw_op.cc
src/rgw/rgw_op.h
src/rgw/rgw_rados.cc
src/rgw/rgw_rados.h
src/rgw/rgw_rest_conn.cc
src/rgw/rgw_rest_conn.h
src/rgw/rgw_rest_s3.cc

index cd8785f19dea8b8591d1e2b859cc9c63229f0fcd..2a73c0220bbaa367ada42dbb6cb8ca8b155e01a9 100644 (file)
@@ -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),
index c4a64aec77bd5d3de3c89b0f79a25e84c80aa713..fd83401f5a52a9bec6dcb7087cd26894d91427ac 100644 (file)
@@ -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);
index 05c41ef4c33db9174f6f02d0b50b55848a3abb31..1cafe180d043e6bc839659c00e095582a32f8d6a 100644 (file)
@@ -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<string, bufferlist>& attrs,
                RGWObjCategory category,
                uint64_t olh_epoch,
@@ -3837,8 +3838,26 @@ int RGWRados::fetch_remote_obj(RGWObjectCtx& obj_ctx,
   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;
   }
@@ -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<string, bufferlist>& 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);
   }
 
index 37c7e8a731d3bea79c6cb418353172333d0cdca2..b7977a51c6e0ff8af91563cb62936fc705e9f435 100644 (file)
@@ -1767,6 +1767,7 @@ public:
                        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,
@@ -1814,6 +1815,7 @@ public:
                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,
index cbffad0b6741dcaccb6a499e08259fb941047937..0e31a0f8a35b6cb049ad301de677ccc0b3cc5f2d 100644 (file)
@@ -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<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);
@@ -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);
 }
 
index 209ddcf9892ead6c97e0486e58dffa6fa44e6c7e..b39e570d7f2f39d809b9718538a6948d95d761a7 100644 (file)
@@ -30,7 +30,9 @@ public:
                    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);
 };
 
index 0cc7793ac9ad0109fa7392b2b88b4a58c383f154..23d0c9d5ff2cd95b9deed9f09883453104cecdcf 100644 (file)
@@ -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", &copy_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");