mirror of
https://github.com/ceph/ceph
synced 2024-12-14 23:46:28 +00:00
rgw: turn swift COPY into PUT
Fixes: #6606 The swift COPY operation is unique in a sense that it's a write operation that has its destination not set by the URI target, but by a different HTTP header. This is problematic as there are some hidden assumptions in the code that the specified bucket/object in the URI is the operation target. E.g., certain initialization functions, quota, etc. Instead of creating a specialized code everywhere for this case just turn it into a regular copy operation, that is, a PUT with a specified copy source. Signed-off-by: Yehuda Sadeh <yehuda@inktank.com>
This commit is contained in:
parent
1376d2379a
commit
cbf8f9a517
@ -825,6 +825,8 @@ struct req_state {
|
||||
rgw_bucket bucket;
|
||||
string bucket_name_str;
|
||||
string object_str;
|
||||
string src_bucket_name;
|
||||
string src_object;
|
||||
ACLOwner bucket_owner;
|
||||
ACLOwner owner;
|
||||
|
||||
|
@ -339,7 +339,7 @@ static int rgw_build_policies(RGWRados *store, struct req_state *s, bool only_bu
|
||||
s->local_source = store->region.equals(region);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (s->bucket_name_str.size()) {
|
||||
s->bucket_exists = true;
|
||||
if (s->bucket_instance_id.empty()) {
|
||||
@ -1706,8 +1706,6 @@ bool RGWCopyObj::parse_copy_location(const char *src, string& bucket_name, strin
|
||||
url_decode(url_src, dec_src);
|
||||
src = dec_src.c_str();
|
||||
|
||||
ldout(s->cct, 15) << "decoded obj=" << src << dendl;
|
||||
|
||||
if (*src == '/') ++src;
|
||||
|
||||
string str(src);
|
||||
|
@ -460,9 +460,6 @@ protected:
|
||||
|
||||
int init_common();
|
||||
|
||||
protected:
|
||||
bool parse_copy_location(const char *src, string& bucket_name, string& object);
|
||||
|
||||
public:
|
||||
RGWCopyObj() {
|
||||
if_mod = NULL;
|
||||
@ -482,6 +479,8 @@ public:
|
||||
last_ofs = 0;
|
||||
}
|
||||
|
||||
static bool parse_copy_location(const char *src, string& bucket_name, string& object);
|
||||
|
||||
virtual void init(RGWRados *store, struct req_state *s, RGWHandler *h) {
|
||||
RGWOp::init(store, s, h);
|
||||
dest_policy.set_ctx(s->cct);
|
||||
|
@ -1060,6 +1060,7 @@ int RGWHandler_ObjStore::read_permissions(RGWOp *op_obj)
|
||||
break;
|
||||
case OP_PUT:
|
||||
case OP_POST:
|
||||
case OP_COPY:
|
||||
/* is it a 'multi-object delete' request? */
|
||||
if (s->info.request_params == "delete") {
|
||||
only_bucket = true;
|
||||
@ -1077,8 +1078,6 @@ int RGWHandler_ObjStore::read_permissions(RGWOp *op_obj)
|
||||
case OP_DELETE:
|
||||
only_bucket = true;
|
||||
break;
|
||||
case OP_COPY: // op itself will read and verify the permissions
|
||||
return 0;
|
||||
case OP_OPTIONS:
|
||||
only_bucket = true;
|
||||
break;
|
||||
|
@ -451,28 +451,10 @@ int RGWCopyObj_ObjStore_SWIFT::get_params()
|
||||
if_match = s->info.env->get("HTTP_COPY_IF_MATCH");
|
||||
if_nomatch = s->info.env->get("HTTP_COPY_IF_NONE_MATCH");
|
||||
|
||||
if (s->op == OP_COPY) {
|
||||
const char *req_dest = s->info.env->get("HTTP_DESTINATION");
|
||||
if (!req_dest)
|
||||
return -ERR_BAD_URL;
|
||||
|
||||
ret = parse_copy_location(req_dest, dest_bucket_name, dest_object);
|
||||
if (!ret)
|
||||
return -ERR_BAD_URL;
|
||||
src_bucket_name = s->bucket_name;
|
||||
src_object = s->object_str;
|
||||
} else {
|
||||
const char *req_src = s->copy_source;
|
||||
if (!req_src)
|
||||
return -ERR_BAD_URL;
|
||||
|
||||
ret = parse_copy_location(req_src, src_bucket_name, src_object);
|
||||
if (!ret)
|
||||
return -ERR_BAD_URL;
|
||||
|
||||
dest_bucket_name = s->bucket_name;
|
||||
dest_object = s->object_str;
|
||||
}
|
||||
src_bucket_name = s->src_bucket_name;
|
||||
src_object = s->src_object;
|
||||
dest_bucket_name = s->bucket_name;
|
||||
dest_object = s->object_str;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -701,7 +683,7 @@ RGWOp *RGWHandler_ObjStore_Obj_SWIFT::op_put()
|
||||
if (is_acl_op()) {
|
||||
return new RGWPutACLs_ObjStore_SWIFT;
|
||||
}
|
||||
if (!s->copy_source)
|
||||
if (s->src_bucket_name.empty())
|
||||
return new RGWPutObj_ObjStore_SWIFT;
|
||||
else
|
||||
return new RGWCopyObj_ObjStore_SWIFT;
|
||||
@ -883,9 +865,41 @@ int RGWHandler_ObjStore_SWIFT::init(RGWRados *store, struct req_state *s, RGWCli
|
||||
return ret;
|
||||
|
||||
s->copy_source = s->info.env->get("HTTP_X_COPY_FROM");
|
||||
if (s->copy_source) {
|
||||
ret = RGWCopyObj::parse_copy_location(s->copy_source, s->src_bucket_name, s->src_object);
|
||||
if (!ret)
|
||||
return -ERR_BAD_URL;
|
||||
}
|
||||
|
||||
s->dialect = "swift";
|
||||
|
||||
if (s->op == OP_COPY) {
|
||||
const char *req_dest = s->info.env->get("HTTP_DESTINATION");
|
||||
if (!req_dest)
|
||||
return -ERR_BAD_URL;
|
||||
|
||||
string dest_bucket_name;
|
||||
string dest_object;
|
||||
ret = RGWCopyObj::parse_copy_location(req_dest, dest_bucket_name, dest_object);
|
||||
if (!ret)
|
||||
return -ERR_BAD_URL;
|
||||
|
||||
if (dest_bucket_name != s->bucket_name_str) {
|
||||
ret = validate_bucket_name(dest_bucket_name.c_str());
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* convert COPY operation into PUT */
|
||||
s->src_bucket_name = s->bucket_name_str;
|
||||
s->src_object = s->object_str;
|
||||
s->bucket_name_str = dest_bucket_name;
|
||||
free(s->bucket_name);
|
||||
s->bucket_name = strdup(s->bucket_name_str.c_str());
|
||||
s->object_str = dest_object;
|
||||
s->op = OP_PUT;
|
||||
}
|
||||
|
||||
return RGWHandler_ObjStore::init(store, s, cio);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user