summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYehuda Sadeh <yehuda@inktank.com>2013-06-07 22:16:17 -0700
committerYehuda Sadeh <yehuda@inktank.com>2013-06-10 14:28:03 -0700
commitcbf860fc030db5353411581a24e44d97e09329ee (patch)
tree8fa65ff36d04fc63ee7dff0169191de4991094d3
parentbe1d84db391e84abd60846555153f5acd4d1e880 (diff)
downloadceph-cbf860fc030db5353411581a24e44d97e09329ee.tar.gz
rgw: don't send redirect if copy object has a local source
Signed-off-by: Yehuda Sadeh <yehuda@inktank.com>
-rw-r--r--src/rgw/rgw_op.cc32
1 files changed, 31 insertions, 1 deletions
diff --git a/src/rgw/rgw_op.cc b/src/rgw/rgw_op.cc
index d540fd605be..f571de0f731 100644
--- a/src/rgw/rgw_op.cc
+++ b/src/rgw/rgw_op.cc
@@ -297,6 +297,29 @@ static int rgw_build_policies(RGWRados *store, struct req_state *s, bool only_bu
s->bucket_acl = new RGWAccessControlPolicy(s->cct);
RGWBucketInfo bucket_info;
+
+ bool source_in_domain = false;
+
+ if (s->copy_source) { /* check if copy source is within the current domain */
+ const char *src = s->copy_source;
+ if (*src == '/')
+ ++src;
+ string copy_source_str(src);
+
+ int pos = copy_source_str.find('/');
+ if (pos > 0)
+ copy_source_str = copy_source_str.substr(0, pos);
+
+ RGWBucketInfo source_info;
+
+ ret = store->get_bucket_info(s->obj_ctx, copy_source_str, source_info, NULL);
+ if (ret == 0) {
+ string& region = source_info.region;
+ source_in_domain = (region.empty() && store->region.is_master) ||
+ (region == store->region.name);
+ }
+ }
+
if (s->bucket_name_str.size()) {
bool exists = true;
ret = store->get_bucket_info(s->obj_ctx, s->bucket_name_str, bucket_info, &s->objv_tracker);
@@ -319,7 +342,14 @@ static int rgw_build_policies(RGWRados *store, struct req_state *s, bool only_bu
if (exists && ((region.empty() && !store->region.is_master) ||
(region != store->region.name))) {
ldout(s->cct, 0) << "NOTICE: request for data in a different region (" << region << " != " << store->region.name << ")" << dendl;
- return -ERR_PERMANENT_REDIRECT;
+ /* we now need to make sure that the operation actually requires copy source, that is
+ * it's a copy operation
+ */
+ if (!source_in_domain ||
+ (s->op != OP_PUT && s->op != OP_COPY) ||
+ s->object_str.empty()) {
+ return -ERR_PERMANENT_REDIRECT;
+ }
}
}