From: Xinying Song Date: Wed, 15 Nov 2017 06:10:58 +0000 (+0800) Subject: rgw:send x-amz-version-id header when upload files X-Git-Tag: v12.2.13~246^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=65fe73a5456d70caa2003e53062108d9f11a748d;p=ceph.git rgw:send x-amz-version-id header when upload files To be compatible with aws s3, an x-amz-version-id header should be returned. For atomic upload, RGWPutObj::version_id will stores the version-id either generated by rgw randomly or read from user. For multipart upload, RGWCompleteMultipart::version_id will stores the version-id either generated by rgw randomly or read from user. Function send_respones() will send 'x-amz-version-id' header when version_id is not empty. Signed-off-by: Xinying Song (cherry picked from commit b4a937562a7ae909c2748980b5327189ccb8cdc0) --- diff --git a/src/rgw/rgw_common.h b/src/rgw/rgw_common.h index 3854d5b4a8f..cccf73f7eea 100644 --- a/src/rgw/rgw_common.h +++ b/src/rgw/rgw_common.h @@ -1534,6 +1534,10 @@ struct rgw_obj_key { instance = i; } + const string& get_instance() const { + return instance; + } + string get_index_key_name() const { if (ns.empty()) { if (name.size() < 1 || name[0] != '_') { diff --git a/src/rgw/rgw_op.cc b/src/rgw/rgw_op.cc index f9a1fc2ee59..abd327207f9 100644 --- a/src/rgw/rgw_op.cc +++ b/src/rgw/rgw_op.cc @@ -3657,6 +3657,10 @@ void RGWPutObj::execute() (delete_at ? *delete_at : real_time()), if_match, if_nomatch, (user_data.empty() ? nullptr : &user_data)); + // only atomic upload will upate version_id here + if (!multipart) + version_id = (static_cast(processor))->get_version_id(); + /* produce torrent */ if (s->cct->_conf->rgw_torrent_flag && (ofs == torrent.get_data_len())) { @@ -5390,7 +5394,6 @@ void RGWCompleteMultipart::execute() RGWMPObj mp; RGWObjManifest manifest; uint64_t olh_epoch = 0; - string version_id; op_ret = get_params(); if (op_ret < 0) @@ -5597,7 +5600,12 @@ void RGWCompleteMultipart::execute() target_obj.init(s->bucket, s->object.name); if (versioned_object) { - store->gen_rand_obj_instance_name(&target_obj); + if (!version_id.empty()) { + target_obj.key.set_instance(version_id); + } else { + store->gen_rand_obj_instance_name(&target_obj); + version_id = target_obj.key.get_instance(); + } } RGWObjectCtx& obj_ctx = *static_cast(s->obj_ctx); diff --git a/src/rgw/rgw_op.h b/src/rgw/rgw_op.h index 23d97994723..84516ede501 100644 --- a/src/rgw/rgw_op.h +++ b/src/rgw/rgw_op.h @@ -1601,6 +1601,7 @@ class RGWCompleteMultipart : public RGWOp { protected: string upload_id; string etag; + string version_id; char *data; int len; diff --git a/src/rgw/rgw_rados.cc b/src/rgw/rgw_rados.cc index 4fcd15c1544..b0c56877a76 100644 --- a/src/rgw/rgw_rados.cc +++ b/src/rgw/rgw_rados.cc @@ -2668,10 +2668,13 @@ int RGWPutObjProcessor_Atomic::prepare(RGWRados *store, string *oid_rand) return r; } - if (!version_id.empty()) { - head_obj.key.set_instance(version_id); - } else if (versioned_object) { - store->gen_rand_obj_instance_name(&head_obj); + if (versioned_object) { + if (!version_id.empty()) { + head_obj.key.set_instance(version_id); + } else { + store->gen_rand_obj_instance_name(&head_obj); + version_id = head_obj.key.get_instance(); + } } manifest.set_trivial_rule(max_chunk_size, store->ctx()->_conf->rgw_obj_stripe_size); diff --git a/src/rgw/rgw_rados.h b/src/rgw/rgw_rados.h index 79124e15d78..48081c6a73b 100644 --- a/src/rgw/rgw_rados.h +++ b/src/rgw/rgw_rados.h @@ -4060,6 +4060,10 @@ public: void set_version_id(const string& vid) { version_id = vid; } + + const string& get_version_id() const { + return version_id; + } }; /* RGWPutObjProcessor_Atomic */ #define MP_META_SUFFIX ".meta" diff --git a/src/rgw/rgw_rest_s3.cc b/src/rgw/rgw_rest_s3.cc index 0fba5b923bf..52ed736404a 100644 --- a/src/rgw/rgw_rest_s3.cc +++ b/src/rgw/rgw_rest_s3.cc @@ -1406,10 +1406,12 @@ void RGWPutObj_ObjStore_S3::send_response() dump_errno(s); dump_etag(s, etag); dump_content_length(s, 0); + dump_header_if_nonempty(s, "x-amz-version-id", version_id); for (auto &it : crypt_http_responses) dump_header(s, it.first, it.second); } else { dump_errno(s); + dump_header_if_nonempty(s, "x-amz-version-id", version_id); end_header(s, this, "application/xml"); dump_start(s); struct tm tmp; @@ -2563,6 +2565,7 @@ void RGWCompleteMultipart_ObjStore_S3::send_response() if (op_ret) set_req_state_err(s, op_ret); dump_errno(s); + dump_header_if_nonempty(s, "x-amz-version-id", version_id); end_header(s, this, "application/xml"); if (op_ret == 0) { dump_start(s);