From cf5e70d434f9a7cad31c4811ff4f2f1aa403de58 Mon Sep 17 00:00:00 2001 From: Yehuda Sadeh Date: Thu, 9 Jun 2011 16:40:58 -0700 Subject: [PATCH] rgw: skeleton for list multipart uploads --- src/rgw/rgw_op.cc | 38 +++++++++++++++++++++++++++++++ src/rgw/rgw_op.h | 33 +++++++++++++++++++++++++++ src/rgw/rgw_rest.h | 6 +++++ src/rgw/rgw_rest_s3.cc | 51 ++++++++++++++++++++++++++++++++++++++++++ src/rgw/rgw_rest_s3.h | 12 ++++++++++ 5 files changed, 140 insertions(+) diff --git a/src/rgw/rgw_op.cc b/src/rgw/rgw_op.cc index c0c614bdd07f7..e41634fa8c8b1 100644 --- a/src/rgw/rgw_op.cc +++ b/src/rgw/rgw_op.cc @@ -1098,6 +1098,9 @@ void RGWAbortMultipart::execute() // and also remove the metadata obj meta_obj.init(s->bucket_str, meta_oid, s->object_str, mp_ns); ret = rgwstore->delete_obj(s->user.user_id, meta_obj); + if (ret == -ENOENT) { + ret = -ERR_NO_SUCH_BUCKET; + } done: send_response(); @@ -1120,6 +1123,41 @@ done: send_response(); } +void RGWListBucketMultiparts::execute() +{ + if (!verify_permission(s, RGW_PERM_READ)) { + ret = -EACCES; + goto done; + } + + url_decode(s->args.get("prefix"), prefix); + marker = s->args.get("marker"); + max_keys = s->args.get(limit_opt_name); + if (!max_keys.empty()) { + max = atoi(max_keys.c_str()); + } else { + max = default_max; + } + url_decode(s->args.get("delimiter"), delimiter); + + if (s->prot_flags & RGW_REST_OPENSTACK) { + string path_args = s->args.get("path"); + if (!path_args.empty()) { + if (!delimiter.empty() || !prefix.empty()) { + ret = -EINVAL; + goto done; + } + url_decode(path_args, prefix); + delimiter="/"; + } + } + + ret = rgwstore->list_objects(s->user.user_id, s->bucket_str, max, prefix, delimiter, marker, objs, common_prefixes, + !!(s->prot_flags & RGW_REST_OPENSTACK), mp_ns); +done: + send_response(); +} + void RGWHandler::init_state(struct req_state *s, struct fcgx_state *fcgx) { /* Retrieve the loglevel from the CGI envirioment (if set) */ diff --git a/src/rgw/rgw_op.h b/src/rgw/rgw_op.h index 7b1c35185483f..7e7d2d0095747 100644 --- a/src/rgw/rgw_op.h +++ b/src/rgw/rgw_op.h @@ -416,6 +416,39 @@ public: virtual void send_response() = 0; }; +class RGWListBucketMultiparts : public RGWOp { +protected: + string prefix; + string marker; + string max_keys; + string delimiter; + int max; + int ret; + vector objs; + map common_prefixes; + + string limit_opt_name; + int default_max; + +public: + RGWListBucketMultiparts() {} + + virtual void init(struct req_state *s) { + RGWOp::init(s); + prefix.clear(); + marker.clear(); + max_keys.clear(); + delimiter.clear(); + max = 0; + ret = 0; + objs.clear(); + common_prefixes.clear(); + } + void execute(); + + virtual void send_response() = 0; +}; + class RGWHandler { protected: struct req_state *s; diff --git a/src/rgw/rgw_rest.h b/src/rgw/rgw_rest.h index 3b541d53a847f..a50ca9da64612 100644 --- a/src/rgw/rgw_rest.h +++ b/src/rgw/rgw_rest.h @@ -118,6 +118,12 @@ public: int get_params(); }; +class RGWListBucketMultiparts_REST : public RGWListBucketMultiparts { +public: + RGWListBucketMultiparts_REST() {} + ~RGWListBucketMultiparts_REST() {} +}; + class RGWHandler_REST : public RGWHandler { protected: bool is_acl_op(struct req_state *s) { diff --git a/src/rgw/rgw_rest_s3.cc b/src/rgw/rgw_rest_s3.cc index 0fe605549f088..ea5a7b3afd990 100644 --- a/src/rgw/rgw_rest_s3.cc +++ b/src/rgw/rgw_rest_s3.cc @@ -343,6 +343,54 @@ void RGWListMultipart_REST_S3::send_response() } } +void RGWListBucketMultiparts_REST_S3::send_response() +{ + if (ret < 0) + set_req_state_err(s, ret); + dump_errno(s); + + end_header(s, "application/xml"); + dump_start(s); + if (ret < 0) + return; + + s->formatter->open_obj_section("ListMultipartUploadsResult"); + s->formatter->dump_value_str("Bucket", s->bucket); + if (!prefix.empty()) + s->formatter->dump_value_str("Prefix", prefix.c_str()); + if (!marker.empty()) + s->formatter->dump_value_str("KeyMarker", marker.c_str()); + if (!max_keys.empty()) { + s->formatter->dump_value_str("MaxKeys", max_keys.c_str()); + } + if (!delimiter.empty()) + s->formatter->dump_value_str("Delimiter", delimiter.c_str()); + + if (ret >= 0) { + vector::iterator iter; + for (iter = objs.begin(); iter != objs.end(); ++iter) { + s->formatter->open_array_section("Upload"); + s->formatter->dump_value_str("Key", iter->name.c_str()); + dump_time(s, "LastModified", &iter->mtime); + s->formatter->dump_value_str("ETag", "\"%s\"", iter->etag); + s->formatter->dump_value_int("Size", "%lld", iter->size); + s->formatter->dump_value_str("StorageClass", "STANDARD"); + dump_owner(s, s->user.user_id, s->user.display_name); + s->formatter->close_section("Upload"); + } + if (common_prefixes.size() > 0) { + s->formatter->open_array_section("CommonPrefixes"); + map::iterator pref_iter; + for (pref_iter = common_prefixes.begin(); pref_iter != common_prefixes.end(); ++pref_iter) { + s->formatter->dump_value_str("Prefix", pref_iter->first.c_str()); + } + s->formatter->close_section("CommonPrefixes"); + } + } + s->formatter->close_section("ListBucketResult"); + s->formatter->flush(); +} + RGWOp *RGWHandler_REST_S3::get_retrieve_obj_op(struct req_state *s, bool get_data) { if (is_acl_op(s)) { @@ -355,6 +403,9 @@ RGWOp *RGWHandler_REST_S3::get_retrieve_obj_op(struct req_state *s, bool get_dat return NULL; } + if (s->args.exists("uploads")) + return &list_bucket_multiparts; + return &list_bucket_op; } diff --git a/src/rgw/rgw_rest_s3.h b/src/rgw/rgw_rest_s3.h index 18cf4ff749e81..12c53bf1f5325 100644 --- a/src/rgw/rgw_rest_s3.h +++ b/src/rgw/rgw_rest_s3.h @@ -121,6 +121,17 @@ public: void send_response(); }; +class RGWListBucketMultiparts_REST_S3 : public RGWListBucketMultiparts_REST { +public: + RGWListBucketMultiparts_REST_S3() { + limit_opt_name ="max-keys"; + default_max = 1000; + } + ~RGWListBucketMultiparts_REST_S3() {} + + void send_response(); +}; + class RGWHandler_REST_S3 : public RGWHandler_REST { RGWGetObj_REST_S3 get_obj_op; RGWListBuckets_REST_S3 list_buckets_op; @@ -136,6 +147,7 @@ class RGWHandler_REST_S3 : public RGWHandler_REST { RGWCompleteMultipart_REST_S3 complete_multipart; RGWCompleteMultipart_REST_S3 abort_multipart; RGWListMultipart_REST_S3 list_multipart; + RGWListBucketMultiparts_REST_S3 list_bucket_multiparts; protected: -- 2.39.5