]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: handle multipart completion
authorYehuda Sadeh <yehuda@hq.newdream.net>
Tue, 31 May 2011 23:05:45 +0000 (16:05 -0700)
committerYehuda Sadeh <yehuda@hq.newdream.net>
Tue, 31 May 2011 23:05:45 +0000 (16:05 -0700)
still wip

src/rgw/rgw_multi.cc
src/rgw/rgw_multi.h
src/rgw/rgw_op.cc
src/rgw/rgw_op.h
src/rgw/rgw_rest.cc
src/rgw/rgw_rest.h
src/rgw/rgw_rest_s3.cc
src/rgw/rgw_rest_s3.h

index 74693feab62fa6e1d26e664810fb3eb360e3cff6..c34cac838072128cee75f55c9787064fa77d15bf 100644 (file)
@@ -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) {
index f7dc482b411fe14af0a7eb6b45eca0758740e4cf..f24f71d989675f4be10a2e9c90f55c1ae9c841cb 100644 (file)
@@ -6,13 +6,12 @@
 
 class RGWMultiCompleteUpload : public XMLObj
 {
-  std::map<int, string> parts;
 public:
   RGWMultiCompleteUpload() {}
   ~RGWMultiCompleteUpload() {}
   bool xml_end(const char *el);
 
-  std::map<int, string>& get_parts() { return parts; }
+  std::map<int, string> parts;
 };
 
 class RGWMultiPart : public XMLObj
@@ -47,6 +46,7 @@ class RGWMultiXMLParser : public RGWXMLParser
   XMLObj *alloc_obj(const char *el);
 public:
   RGWMultiXMLParser() {}
+  ~RGWMultiXMLParser() {}
 };
 
 #endif
index 704e5f8127089769f30a5826ccba6544b2180c82..e05d4188132257e354f30472598574b6799d4792 100644 (file)
@@ -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<int, string>::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) */
index c3abfd61a39644323a1efffffb8f42035230322a..e69840afe0255fcae5043ca04ae9aee60950c9f9 100644 (file)
@@ -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;
index 3b4defb0629f619578a692235d76b6eb9f81c89a..5c81f1d7941936408c12e02cd055a445b9f34668 100644 (file)
@@ -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:
index 8b528fc16690679e66f220e443a624908dad7bd1..541124eb3e12282bce7343d00cbc4b0c78288635 100644 (file)
@@ -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) {
index 5a26a0e238e0aa7c62fc4e5a773c5991c9d03c96..c5379cd788a355204fdbc3f0ad8a5f8c633ccccf 100644 (file)
@@ -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;
 }
index dff4f4646b5a6478b602869db461236a76b9c6d6..5c912cf4383e1117561bddd8029e5f8f414d8cae 100644 (file)
@@ -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: