From 37fd3b58329278bf144cad4a4d8351675efe5341 Mon Sep 17 00:00:00 2001 From: Yehuda Sadeh Date: Tue, 7 Jun 2011 14:13:59 -0700 Subject: [PATCH] rgw: calc etag for multipart upload --- src/rgw/rgw_common.h | 36 ++++++++++++++++++++++++++++++++++++ src/rgw/rgw_op.cc | 27 +++++++++++++++++++++++++-- src/rgw/rgw_os_auth.cc | 35 ----------------------------------- 3 files changed, 61 insertions(+), 37 deletions(-) diff --git a/src/rgw/rgw_common.h b/src/rgw/rgw_common.h index 757128f9b4d89..ecd64a2079513 100644 --- a/src/rgw/rgw_common.h +++ b/src/rgw/rgw_common.h @@ -19,6 +19,7 @@ #include "common/debug.h" #include "fcgiapp.h" +#include #include #include #include @@ -456,6 +457,41 @@ static inline void buf_to_hex(const unsigned char *buf, int len, char *str) } } +static inline int hexdigit(char c) +{ + if (c >= '0' && c <= '9') + return (c - '0'); + c = toupper(c); + if (c >= 'A' && c <= 'F') + return c - 'A' + 0xa; + return -EINVAL; +} + +static inline int hex_to_buf(const char *hex, char *buf, int len) +{ + int i = 0; + const char *p = hex; + while (*p) { + if (i >= len) + return -EINVAL; + buf[i] = 0; + int d = hexdigit(*p); + if (d < 0) + return d; + buf[i] = d << 4; + p++; + if (!*p) + return -EINVAL; + d = hexdigit(*p); + if (d < 0) + return -d; + buf[i] += d; + i++; + p++; + } + return i; +} + static inline int rgw_str_to_bool(const char *s, int def_val) { if (!s) diff --git a/src/rgw/rgw_op.cc b/src/rgw/rgw_op.cc index 754762f30e707..ea16cb4df1f34 100644 --- a/src/rgw/rgw_op.cc +++ b/src/rgw/rgw_op.cc @@ -922,6 +922,12 @@ void RGWCompleteMultipart::execute() map attrs; off_t ofs = 0; string prefix; + MD5 hash; + char final_etag[CEPH_CRYPTO_MD5_DIGESTSIZE]; + char final_etag_str[CEPH_CRYPTO_MD5_DIGESTSIZE * 2 + 16]; + bufferlist etag_bl; + + ret = get_params(); if (ret < 0) @@ -956,12 +962,15 @@ void RGWCompleteMultipart::execute() ret = get_multiparts_info(s, obj, obj_parts, policy, attrs); if (ret == -ENOENT) ret = -ERR_NO_SUCH_UPLOAD; + if (parts->parts.size() != obj_parts.size()) + ret = -ERR_INVALID_PART; if (ret < 0) goto done; for (iter = parts->parts.begin(), obj_iter = obj_parts.begin(); - iter != parts->parts.end(); + iter != parts->parts.end() && obj_iter != obj_parts.end(); ++iter, ++obj_iter) { + char etag[CEPH_CRYPTO_MD5_DIGESTSIZE]; if (iter->first != (int)obj_iter->first) { RGW_LOG(0) << "parts num mismatch: next requested: " << iter->first << " next uploaded: " << obj_iter->first << dendl; ret = -ERR_INVALID_PART; @@ -972,7 +981,20 @@ void RGWCompleteMultipart::execute() ret = -ERR_INVALID_PART; goto done; } + + hex_to_buf(obj_iter->second.etag.c_str(), etag, CEPH_CRYPTO_MD5_DIGESTSIZE); + hash.Update((const byte *)etag, sizeof(etag)); } + hash.Final((byte *)final_etag); + + buf_to_hex((unsigned char *)final_etag, sizeof(final_etag), final_etag_str); + snprintf(&final_etag_str[CEPH_CRYPTO_MD5_DIGESTSIZE * 2], sizeof(final_etag_str) - CEPH_CRYPTO_MD5_DIGESTSIZE * 2, + "-%lld", (long long)parts->parts.size()); + RGW_LOG(0) << "calculated etag: " << final_etag_str << dendl; + + etag_bl.append(final_etag_str, strlen(final_etag_str) + 1); + + attrs[RGW_ATTR_ETAG] = etag_bl; ret = rgwstore->put_obj_meta(s->user.user_id, s->bucket_str, s->object_str, s->object_str, NULL, attrs, false); if (ret < 0) @@ -981,10 +1003,11 @@ void RGWCompleteMultipart::execute() for (obj_iter = obj_parts.begin(); obj_iter != obj_parts.end(); ++obj_iter) { obj = prefix; char buf[16]; - snprintf(buf, 16, "%d", obj_iter->second.num); + snprintf(buf, sizeof(buf), "%d", obj_iter->second.num); obj.append(buf); rgwstore->clone_range(s->bucket_str, s->object_str, ofs, obj, 0, obj_iter->second.size, s->object_str); ofs += obj_iter->second.size; + } done: diff --git a/src/rgw/rgw_os_auth.cc b/src/rgw/rgw_os_auth.cc index 46d0a76bcb74d..8e051045d6087 100644 --- a/src/rgw/rgw_os_auth.cc +++ b/src/rgw/rgw_os_auth.cc @@ -52,41 +52,6 @@ static int encode_token(string& os_user, string& key, bufferlist& bl) return ret; } -int hexdigit(char c) -{ - if (c >= '0' && c <= '9') - return (c - '0'); - c = toupper(c); - if (c >= 'A' && c <= 'F') - return c - 'A' + 0xa; - return -EINVAL; -} - -int hex_to_buf(const char *hex, char *buf, int len) -{ - int i = 0; - const char *p = hex; - while (*p) { - if (i >= len) - return -EINVAL; - buf[i] = 0; - int d = hexdigit(*p); - if (d < 0) - return d; - buf[i] = d << 4; - p++; - if (!*p) - return -EINVAL; - d = hexdigit(*p); - if (d < 0) - return -d; - buf[i] += d; - i++; - p++; - } - return i; -} - int rgw_os_verify_signed_token(const char *token, RGWUserInfo& info) { if (strncmp(token, "AUTH_rgwtk", 10) != 0) -- 2.39.5