From 2945bef8eb6a51878e0eb76e324f1102d999d85b Mon Sep 17 00:00:00 2001 From: Radoslaw Zarzynski Date: Tue, 1 Sep 2015 18:20:42 +0200 Subject: [PATCH] rgw: add support for putting Swift's X-Object-Manifest through POST. Fixes: #12886 Signed-off-by: Radoslaw Zarzynski --- src/rgw/rgw_op.cc | 67 +++++++++++++++++++++------------------ src/rgw/rgw_op.h | 8 ++--- src/rgw/rgw_rest_swift.cc | 2 ++ 3 files changed, 42 insertions(+), 35 deletions(-) diff --git a/src/rgw/rgw_op.cc b/src/rgw/rgw_op.cc index 5025988038039..8abced98fa791 100644 --- a/src/rgw/rgw_op.cc +++ b/src/rgw/rgw_op.cc @@ -1829,6 +1829,22 @@ static void encode_delete_at_attr(time_t delete_at, map& att attrs[RGW_ATTR_DELETE_AT] = delatbl; } +static int encode_obj_manifest_attr(const char * const obj_manifest, + map& attrs) +{ + string om = obj_manifest; + + if (om.find('/') == string::npos) { + return -EINVAL; + } + + bufferlist manifest_bl; + manifest_bl.append(obj_manifest, strlen(obj_manifest) + 1); + attrs[RGW_ATTR_USER_MANIFEST] = manifest_bl; + + return 0; +} + void RGWPutObj::execute() { RGWPutObjProcessor *processor = NULL; @@ -1978,48 +1994,29 @@ void RGWPutObj::execute() if (need_calc_md5) { processor->complete_hash(&hash); - hash.Final(m); + } + hash.Final(m); - buf_to_hex(m, CEPH_CRYPTO_MD5_DIGESTSIZE, calc_md5); - etag = calc_md5; + buf_to_hex(m, CEPH_CRYPTO_MD5_DIGESTSIZE, calc_md5); + etag = calc_md5; - if (supplied_md5_b64 && strcmp(calc_md5, supplied_md5)) { - ret = -ERR_BAD_DIGEST; - goto done; - } + if (supplied_md5_b64 && strcmp(calc_md5, supplied_md5)) { + ret = -ERR_BAD_DIGEST; + goto done; } policy.encode(aclbl); attrs[RGW_ATTR_ACL] = aclbl; + if (obj_manifest) { - bufferlist manifest_bl; - string manifest_obj_prefix; - string manifest_bucket; - - char etag_buf[CEPH_CRYPTO_MD5_DIGESTSIZE]; - char etag_buf_str[CEPH_CRYPTO_MD5_DIGESTSIZE * 2 + 16]; - - manifest_bl.append(obj_manifest, strlen(obj_manifest) + 1); - attrs[RGW_ATTR_USER_MANIFEST] = manifest_bl; - user_manifest_parts_hash = &hash; - string prefix_str = obj_manifest; - int pos = prefix_str.find('/'); - if (pos < 0) { - ldout(s->cct, 0) << "bad user manifest, missing slash separator: " << obj_manifest << dendl; + ret = encode_obj_manifest_attr(obj_manifest, attrs); + if (ret < 0) { + ldout(s->cct, 0) << "bad user manifest: " << obj_manifest << dendl; goto done; } - - manifest_bucket = prefix_str.substr(0, pos); - manifest_obj_prefix = prefix_str.substr(pos + 1); - - hash.Final((byte *)etag_buf); - buf_to_hex((const unsigned char *)etag_buf, CEPH_CRYPTO_MD5_DIGESTSIZE, etag_buf_str); - - ldout(s->cct, 0) << __func__ << ": calculated md5 for user manifest: " << etag_buf_str << dendl; - - etag = etag_buf_str; } + if (supplied_etag && etag.compare(supplied_etag) != 0) { ret = -ERR_UNPROCESSABLE_ENTITY; goto done; @@ -2423,6 +2420,14 @@ void RGWPutMetadataObject::execute() populate_with_generic_attrs(s, attrs); encode_delete_at_attr(delete_at, attrs); + if (obj_manifest) { + ret = encode_obj_manifest_attr(obj_manifest, attrs); + if (ret < 0) { + ldout(s->cct, 0) << "bad user manifest: " << obj_manifest << dendl; + return; + } + } + ret = store->set_attrs(s->obj_ctx, obj, attrs, &rmattrs, NULL); } diff --git a/src/rgw/rgw_op.h b/src/rgw/rgw_op.h index 0252ff8a65d2f..29d679677c36d 100644 --- a/src/rgw/rgw_op.h +++ b/src/rgw/rgw_op.h @@ -436,8 +436,6 @@ protected: const char *obj_manifest; time_t mtime; - MD5 *user_manifest_parts_hash; - uint64_t olh_epoch; string version_id; @@ -454,7 +452,6 @@ public: chunked_upload = false; obj_manifest = NULL; mtime = 0; - user_manifest_parts_hash = NULL; olh_epoch = 0; delete_at = 0; } @@ -589,10 +586,13 @@ protected: RGWAccessControlPolicy policy; string placement_rule; time_t delete_at; + const char *obj_manifest; public: RGWPutMetadataObject() - : ret(0), delete_at(0) + : ret(0), + delete_at(0), + obj_manifest(NULL) {} virtual void init(RGWRados *store, struct req_state *s, RGWHandler *h) { diff --git a/src/rgw/rgw_rest_swift.cc b/src/rgw/rgw_rest_swift.cc index 06817ad8a5376..500794f846727 100644 --- a/src/rgw/rgw_rest_swift.cc +++ b/src/rgw/rgw_rest_swift.cc @@ -679,6 +679,8 @@ int RGWPutMetadataObject_ObjStore_SWIFT::get_params() } placement_rule = s->info.env->get("HTTP_X_STORAGE_POLICY", ""); + obj_manifest = s->info.env->get("HTTP_X_OBJECT_MANIFEST"); + return 0; } -- 2.39.5