From fa71082ee43ecfef2342e0dd0db834e7da38d706 Mon Sep 17 00:00:00 2001 From: Radoslaw Zarzynski Date: Mon, 9 Nov 2015 19:12:49 +0100 Subject: [PATCH] rgw: make response for multipart delete on a SLO compliant with Swift. Signed-off-by: Radoslaw Zarzynski --- src/rgw/rgw_rest.cc | 7 +- src/rgw/rgw_rest_swift.cc | 142 ++++++++++++++++++++++++-------------- 2 files changed, 94 insertions(+), 55 deletions(-) diff --git a/src/rgw/rgw_rest.cc b/src/rgw/rgw_rest.cc index 2a761f720f61c..c557bc506f9ae 100644 --- a/src/rgw/rgw_rest.cc +++ b/src/rgw/rgw_rest.cc @@ -1177,16 +1177,19 @@ int RGWHandler_ObjStore::allocate_formatter(struct req_state *s, int default_typ } } + const string& mm = s->info.args.get("multipart-manifest"); + const bool multipart_delete = (mm.compare("delete") == 0); + switch (s->format) { case RGW_FORMAT_PLAIN: { - const bool use_kv_syntax = s->info.args.exists("bulk-delete"); + const bool use_kv_syntax = s->info.args.exists("bulk-delete") || multipart_delete; s->formatter = new RGWFormatter_Plain(use_kv_syntax); break; } case RGW_FORMAT_XML: { - const bool lowercase_underscore = s->info.args.exists("bulk-delete"); + const bool lowercase_underscore = s->info.args.exists("bulk-delete") || multipart_delete; s->formatter = new XMLFormatter(false, lowercase_underscore); break; } diff --git a/src/rgw/rgw_rest_swift.cc b/src/rgw/rgw_rest_swift.cc index 8f17c103b2302..21a0336022bb5 100644 --- a/src/rgw/rgw_rest_swift.cc +++ b/src/rgw/rgw_rest_swift.cc @@ -731,6 +731,61 @@ void RGWPutMetadataObject_ObjStore_SWIFT::send_response() rgw_flush_formatter_and_reset(s, s->formatter); } +static void bulkdelete_respond(const unsigned num_deleted, + const unsigned int num_unfound, + const std::list& failures, + const int prot_flags, /* in */ + ceph::Formatter& formatter) /* out */ +{ + formatter.open_object_section("delete"); + + string resp_status; + string resp_body; + + if (!failures.empty()) { + int reason = ERR_INVALID_REQUEST; + for (const auto fail_desc : failures) { + if (-ENOENT != fail_desc.err && -EACCES != fail_desc.err) { + reason = fail_desc.err; + } + } + + rgw_err err; + set_req_state_err(err, reason, prot_flags); + dump_errno(err, resp_status); + } else if (0 == num_deleted && 0 == num_unfound) { + /* 400 Bad Request */ + dump_errno(400, resp_status); + resp_body = "Invalid bulk delete."; + } else { + /* 200 OK */ + dump_errno(200, resp_status); + } + + formatter.dump_int("Number Deleted", num_deleted); + formatter.dump_int("Number Not Found", num_unfound); + formatter.dump_string("Response Body", resp_body); + formatter.dump_string("Response Status", resp_status); + formatter.open_array_section("Errors"); + for (const auto fail_desc : failures) { + formatter.open_array_section("object"); + + stringstream ss_name; + ss_name << fail_desc.path; + formatter.dump_string("Name", ss_name.str()); + + rgw_err err; + set_req_state_err(err, fail_desc.err, prot_flags); + string status; + dump_errno(err, status); + formatter.dump_string("Status", status); + formatter.close_section(); + } + formatter.close_section(); + + formatter.close_section(); +} + int RGWDeleteObj_ObjStore_SWIFT::get_params() { const string& mm = s->info.args.get("multipart-manifest"); @@ -742,13 +797,41 @@ int RGWDeleteObj_ObjStore_SWIFT::get_params() void RGWDeleteObj_ObjStore_SWIFT::send_response() { int r = ret; - if (!r) + + if (multipart_delete) { + r = 0; + } else if(!r) { r = STATUS_NO_CONTENT; + } set_req_state_err(s, r); dump_errno(s); end_header(s, this); + + if (multipart_delete) { + if (deleter) { + bulkdelete_respond(deleter->get_num_deleted(), + deleter->get_num_unfound(), + deleter->get_failures(), + s->prot_flags, + *s->formatter); + } else if (-ENOENT == ret) { + bulkdelete_respond(0, 1, {}, s->prot_flags, *s->formatter); + } else { + RGWBulkDelete::acct_path_t path; + path.bucket_name = s->bucket_name_str; + path.obj_key = s->object; + + RGWBulkDelete::fail_desc_t fail_desc; + fail_desc.err = ret; + fail_desc.path = path; + + bulkdelete_respond(0, 0, { fail_desc }, s->prot_flags, *s->formatter); + } + } + rgw_flush_formatter_and_reset(s, s->formatter); + } static void get_contype_from_attrs(map& attrs, @@ -1030,58 +1113,11 @@ void RGWBulkDelete_ObjStore_SWIFT::send_response() dump_errno(s); end_header(s, NULL); - s->formatter->open_object_section("delete"); - - const auto num_deleted = deleter->get_num_deleted(); - const auto num_unfound = deleter->get_num_unfound(); - const auto& failures = deleter->get_failures(); - - string resp_status; - string resp_body; - - if (!failures.empty()) { - int reason = ERR_INVALID_REQUEST; - for (const auto fail_desc : failures) { - if (-ENOENT != fail_desc.err && -EACCES != fail_desc.err) { - reason = fail_desc.err; - } - } - - rgw_err err; - set_req_state_err(err, reason, s->prot_flags); - dump_errno(err, resp_status); - } else if (0 == num_deleted && 0 == num_unfound) { - /* 400 Bad Request */ - dump_errno(400, resp_status); - resp_body = "Invalid bulk delete."; - } else { - /* 200 OK */ - dump_errno(200, resp_status); - } - - s->formatter->dump_int("Number Deleted", num_deleted); - s->formatter->dump_int("Number Not Found", num_unfound); - s->formatter->dump_string("Response Body", resp_body); - s->formatter->dump_string("Response Status", resp_status); - s->formatter->open_array_section("Errors"); - for (const auto fail_desc : failures) { - s->formatter->open_array_section("object"); - - stringstream ss_name; - ss_name << fail_desc.path; - s->formatter->dump_string("Name", ss_name.str()); - - rgw_err err; - set_req_state_err(err, fail_desc.err, s->prot_flags); - string status; - dump_errno(err, status); - s->formatter->dump_string("Status", status); - s->formatter->close_section(); - } - s->formatter->close_section(); - - s->formatter->close_section(); - + bulkdelete_respond(deleter->get_num_deleted(), + deleter->get_num_unfound(), + deleter->get_failures(), + s->prot_flags, + *s->formatter); rgw_flush_formatter_and_reset(s, s->formatter); } -- 2.39.5