]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: add support for putting Swift's X-Object-Manifest through POST.
authorRadoslaw Zarzynski <rzarzynski@mirantis.com>
Tue, 1 Sep 2015 16:20:42 +0000 (18:20 +0200)
committerRadoslaw Zarzynski <rzarzynski@mirantis.com>
Tue, 8 Dec 2015 16:57:21 +0000 (17:57 +0100)
Fixes: #12886
Signed-off-by: Radoslaw Zarzynski <rzarzynski@mirantis.com>
src/rgw/rgw_op.cc
src/rgw/rgw_op.h
src/rgw/rgw_rest_swift.cc

index 5025988038039efe00950572526ccd2208fe6d14..8abced98fa79149885e17d7b636c154443607054 100644 (file)
@@ -1829,6 +1829,22 @@ static void encode_delete_at_attr(time_t delete_at, map<string, bufferlist>& att
   attrs[RGW_ATTR_DELETE_AT] = delatbl;
 }
 
+static int encode_obj_manifest_attr(const char * const obj_manifest,
+                                    map<string, bufferlist>& 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);
 }
 
index 0252ff8a65d2f882586f5010d7f5f45a58e2ab21..29d679677c36d944e6d559516360dd3dd480f17c 100644 (file)
@@ -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) {
index 06817ad8a5376442c69eb260427be51a385e5ba6..500794f84672746524aa97f6451b4c160237bce5 100644 (file)
@@ -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;
 }