From 5dd0e12225d16aa45b5fe4f7da3bfaab0473adf5 Mon Sep 17 00:00:00 2001 From: Yehuda Sadeh Date: Tue, 31 May 2011 16:05:45 -0700 Subject: [PATCH] rgw: handle multipart completion still wip --- src/rgw/rgw_multi.cc | 4 ++-- src/rgw/rgw_multi.h | 4 ++-- src/rgw/rgw_op.cc | 36 ++++++++++++++++++++++++++++++++++++ src/rgw/rgw_op.h | 25 +++++++++++++++++++++++++ src/rgw/rgw_rest.cc | 27 ++++++++++++++++++++++++++- src/rgw/rgw_rest.h | 8 ++++++++ src/rgw/rgw_rest_s3.cc | 29 ++++++++++++++++++++++++----- src/rgw/rgw_rest_s3.h | 9 +++++++++ 8 files changed, 132 insertions(+), 10 deletions(-) diff --git a/src/rgw/rgw_multi.cc b/src/rgw/rgw_multi.cc index 74693feab62fa..c34cac8380721 100644 --- a/src/rgw/rgw_multi.cc +++ b/src/rgw/rgw_multi.cc @@ -43,8 +43,8 @@ bool RGWMultiCompleteUpload::xml_end(const char *el) { } -XMLObj *RGWXMLParser::alloc_obj(const char *el) { - XMLObj * obj; +XMLObj *RGWMultiXMLParser::alloc_obj(const char *el) { + XMLObj *obj = NULL; if (strcmp(el, "CompleteMultipartUpload") == 0) { obj = new RGWMultiCompleteUpload(); } else if (strcmp(el, "Part") == 0) { diff --git a/src/rgw/rgw_multi.h b/src/rgw/rgw_multi.h index f7dc482b411fe..f24f71d989675 100644 --- a/src/rgw/rgw_multi.h +++ b/src/rgw/rgw_multi.h @@ -6,13 +6,12 @@ class RGWMultiCompleteUpload : public XMLObj { - std::map parts; public: RGWMultiCompleteUpload() {} ~RGWMultiCompleteUpload() {} bool xml_end(const char *el); - std::map& get_parts() { return parts; } + std::map parts; }; class RGWMultiPart : public XMLObj @@ -47,6 +46,7 @@ class RGWMultiXMLParser : public RGWXMLParser XMLObj *alloc_obj(const char *el); public: RGWMultiXMLParser() {} + ~RGWMultiXMLParser() {} }; #endif diff --git a/src/rgw/rgw_op.cc b/src/rgw/rgw_op.cc index 704e5f8127089..e05d418813225 100644 --- a/src/rgw/rgw_op.cc +++ b/src/rgw/rgw_op.cc @@ -13,6 +13,7 @@ #include "rgw_acl.h" #include "rgw_user.h" #include "rgw_log.h" +#include "rgw_multi.h" using namespace std; using ceph::crypto::MD5; @@ -840,6 +841,41 @@ done: send_response(); } +void RGWCompleteMultipart::execute() +{ + RGWMultiCompleteUpload *parts; + map::iterator iter; + RGWMultiXMLParser parser; + + if (!data) { + ret = -EINVAL; + goto done; + } + + if (!parser.init()) { + ret = -EINVAL; + goto done; + } + + if (!parser.parse(data, len, 1)) { + ret = -EINVAL; + goto done; + } + + parts = (RGWMultiCompleteUpload *)parser.find_first("CompleteMultipartUpload"); + if (!parts) { + ret = -EINVAL; + goto done; + } + + for (iter = parts->parts.begin(); iter != parts->parts.end(); ++iter) { + RGW_LOG(0) << "part: " << iter->first << " etag: " << iter->second << dendl; + } + +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 c3abfd61a3964..e69840afe0255 100644 --- a/src/rgw/rgw_op.h +++ b/src/rgw/rgw_op.h @@ -346,6 +346,31 @@ public: virtual void send_response() = 0; }; +class RGWCompleteMultipart : public RGWOp { +protected: + int ret; + string upload_id; + string etag; + char *data; + int len; + +public: + RGWCompleteMultipart() {} + + virtual void init(struct req_state *s) { + RGWOp::init(s); + ret = 0; + upload_id = ""; + etag=""; + data = NULL; + len = 0; + } + void execute(); + + virtual int get_params() = 0; + virtual void send_response() = 0; +}; + class RGWHandler { protected: struct req_state *s; diff --git a/src/rgw/rgw_rest.cc b/src/rgw/rgw_rest.cc index 3b4defb0629f6..5c81f1d794193 100644 --- a/src/rgw/rgw_rest.cc +++ b/src/rgw/rgw_rest.cc @@ -285,6 +285,32 @@ int RGWInitMultipart_REST::get_params() return ret; } +int RGWCompleteMultipart_REST::get_params() +{ + if (!s->args.exists("uploadId")) { + ret = -ENOTSUP; + return ret; + } + + size_t cl = 0; + + if (s->length) + cl = atoll(s->length); + if (cl) { + data = (char *)malloc(cl + 1); + if (!data) { + ret = -ENOMEM; + return ret; + } + CGI_GetStr(s, data, cl, len); + data[len] = '\0'; + } else { + len = 0; + } + + return ret; +} + static void next_tok(string& str, string& tok, char delim) { if (str.size() == 0) { @@ -712,7 +738,6 @@ RGWOp *RGWHandler_REST::get_op() op = get_retrieve_op(s, false); break; case OP_POST: -RGW_LOG(0) << __FILE__ << ":" << __LINE__ << dendl; op = get_post_op(s); break; default: diff --git a/src/rgw/rgw_rest.h b/src/rgw/rgw_rest.h index 8b528fc166906..541124eb3e122 100644 --- a/src/rgw/rgw_rest.h +++ b/src/rgw/rgw_rest.h @@ -96,6 +96,14 @@ public: int get_params(); }; +class RGWCompleteMultipart_REST : public RGWCompleteMultipart { +public: + RGWCompleteMultipart_REST() {} + ~RGWCompleteMultipart_REST() {} + + int get_params(); +}; + 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 5a26a0e238e0a..c5379cd788a35 100644 --- a/src/rgw/rgw_rest_s3.cc +++ b/src/rgw/rgw_rest_s3.cc @@ -246,7 +246,6 @@ void RGWPutACLs_REST_S3::send_response() void RGWInitMultipart_REST_S3::send_response() { -RGW_LOG(0) << __FILE__ << ":" << __LINE__ << dendl; if (ret) set_req_state_err(s, ret); dump_errno(s); @@ -262,6 +261,24 @@ RGW_LOG(0) << __FILE__ << ":" << __LINE__ << dendl; } } +void RGWCompleteMultipart_REST_S3::send_response() +{ + if (ret) + set_req_state_err(s, ret); + dump_errno(s); + end_header(s, "application/xml"); + if (ret == 0) { + dump_start(s); + s->formatter->open_obj_section("CompleteMultipartUploadResult xmlns=\"http://s3.amazonaws.com/doc/2006-03-01/\""); + // s->formatter->dump_value_str("Location" ... + s->formatter->dump_value_str("Bucket", s->bucket); + s->formatter->dump_value_str("Key", s->object); + s->formatter->dump_value_str("ETag", upload_id.c_str()); + s->formatter->close_section("CompleteMultipartUploadResult"); + s->formatter->flush(); + } +} + RGWOp *RGWHandler_REST_S3::get_retrieve_obj_op(struct req_state *s, bool get_data) { if (is_acl_op(s)) { @@ -318,10 +335,12 @@ RGWOp *RGWHandler_REST_S3::get_delete_op(struct req_state *s) RGWOp *RGWHandler_REST_S3::get_post_op(struct req_state *s) { -RGW_LOG(0) << __FILE__ << ":" << __LINE__ << dendl; - if (s->object) - return &init_multipart; -RGW_LOG(0) << __FILE__ << ":" << __LINE__ << dendl; + if (s->object) { + if (s->args.exists("uploadId")) + return &complete_multipart; + else + return &init_multipart; + } return NULL; } diff --git a/src/rgw/rgw_rest_s3.h b/src/rgw/rgw_rest_s3.h index dff4f4646b5a6..5c912cf4383e1 100644 --- a/src/rgw/rgw_rest_s3.h +++ b/src/rgw/rgw_rest_s3.h @@ -97,6 +97,14 @@ public: void send_response(); }; +class RGWCompleteMultipart_REST_S3 : public RGWCompleteMultipart_REST { +public: + RGWCompleteMultipart_REST_S3() {} + ~RGWCompleteMultipart_REST_S3() {} + + void send_response(); +}; + class RGWHandler_REST_S3 : public RGWHandler_REST { RGWGetObj_REST_S3 get_obj_op; RGWListBuckets_REST_S3 list_buckets_op; @@ -109,6 +117,7 @@ class RGWHandler_REST_S3 : public RGWHandler_REST { RGWGetACLs_REST_S3 get_acls_op; RGWPutACLs_REST_S3 put_acls_op; RGWInitMultipart_REST_S3 init_multipart; + RGWCompleteMultipart_REST_S3 complete_multipart; protected: -- 2.39.5