diff options
author | Yehuda Sadeh <yehuda@inktank.com> | 2013-06-07 22:16:17 -0700 |
---|---|---|
committer | Yehuda Sadeh <yehuda@inktank.com> | 2013-06-10 14:28:03 -0700 |
commit | cbf860fc030db5353411581a24e44d97e09329ee (patch) | |
tree | 8fa65ff36d04fc63ee7dff0169191de4991094d3 | |
parent | be1d84db391e84abd60846555153f5acd4d1e880 (diff) | |
download | ceph-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.cc | 32 |
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; + } } } |