]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: calc etag for multipart upload
authorYehuda Sadeh <yehuda@hq.newdream.net>
Tue, 7 Jun 2011 21:13:59 +0000 (14:13 -0700)
committerYehuda Sadeh <yehuda@hq.newdream.net>
Tue, 7 Jun 2011 21:13:59 +0000 (14:13 -0700)
src/rgw/rgw_common.h
src/rgw/rgw_op.cc
src/rgw/rgw_os_auth.cc

index 757128f9b4d89615a6cba24eddeb9339f328ad24..ecd64a207951398e10f01c3d4111f536cf182041 100644 (file)
@@ -19,6 +19,7 @@
 #include "common/debug.h"
 #include "fcgiapp.h"
 
+#include <errno.h>
 #include <string.h>
 #include <string>
 #include <map>
@@ -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)
index 754762f30e707bbce6d2464106fab17b05b5b6e8..ea16cb4df1f341c2343fcf9f0153b7343c07a839 100644 (file)
@@ -922,6 +922,12 @@ void RGWCompleteMultipart::execute()
   map<string, bufferlist> 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:
index 46d0a76bcb74d6f49c38d80576564a483030bb64..8e051045d6087a60473977ccd18400820cc0a48f 100644 (file)
@@ -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)