}
-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) {
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
XMLObj *alloc_obj(const char *el);
public:
RGWMultiXMLParser() {}
+ ~RGWMultiXMLParser() {}
};
#endif
#include "rgw_acl.h"
#include "rgw_user.h"
#include "rgw_log.h"
+#include "rgw_multi.h"
using namespace std;
using ceph::crypto::MD5;
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) */
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;
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) {
op = get_retrieve_op(s, false);
break;
case OP_POST:
-RGW_LOG(0) << __FILE__ << ":" << __LINE__ << dendl;
op = get_post_op(s);
break;
default:
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) {
void RGWInitMultipart_REST_S3::send_response()
{
-RGW_LOG(0) << __FILE__ << ":" << __LINE__ << dendl;
if (ret)
set_req_state_err(s, ret);
dump_errno(s);
}
}
+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)) {
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;
}
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;
RGWGetACLs_REST_S3 get_acls_op;
RGWPutACLs_REST_S3 put_acls_op;
RGWInitMultipart_REST_S3 init_multipart;
+ RGWCompleteMultipart_REST_S3 complete_multipart;
protected: