From: Yehuda Sadeh Date: Thu, 20 Sep 2012 22:32:24 +0000 (-0700) Subject: rgw: refactor protocol stacking X-Git-Tag: v0.54~85^2~13 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=cea28f8cfb0f7642d53068d40e0daec0d02ae0e6;p=ceph.git rgw: refactor protocol stacking New RESTMgr* classes to handle a specific uri entry point. Actions are handled by RGWHandler*. Changing init order, newly instantiated RGWHandler for every op. Signed-off-by: Yehuda Sadeh --- diff --git a/src/rgw/rgw_main.cc b/src/rgw/rgw_main.cc index b4d2623c6b63..8e86afff4d81 100644 --- a/src/rgw/rgw_main.cc +++ b/src/rgw/rgw_main.cc @@ -126,6 +126,7 @@ class RGWProcess { deque m_req_queue; ThreadPool m_tp; Throttle req_throttle; + RGWREST rest; struct RGWWQ : public ThreadPool::WorkQueue { RGWProcess *process; @@ -247,7 +248,6 @@ static int call_log_intent(void *ctx, rgw_obj& obj, RGWIntentEvent intent) void RGWProcess::handle_request(RGWRequest *req) { FCGX_Request *fcgx = &req->fcgx; - RGWRESTMgr rest; int ret; RGWEnv rgw_env; RGWFCGX client_io(fcgx); @@ -330,6 +330,7 @@ done: if (handler) handler->put_op(op); + rest.put_handler(handler); rgwstore->destroy_context(s->obj_ctx); FCGX_Finish_r(fcgx); diff --git a/src/rgw/rgw_op.h b/src/rgw/rgw_op.h index a9433643c30e..86e3e67baa37 100644 --- a/src/rgw/rgw_op.h +++ b/src/rgw/rgw_op.h @@ -659,8 +659,6 @@ protected: struct req_state *s; int do_read_permissions(RGWOp *op, bool only_bucket); - virtual int validate_bucket_name(const string& bucket) = 0; - virtual int validate_object_name(const string& object) = 0; virtual RGWOp *op_get() { return NULL; } virtual RGWOp *op_put() { return NULL; } @@ -672,7 +670,6 @@ public: RGWHandler() {} virtual ~RGWHandler(); virtual int init(struct req_state *_s, RGWClientIO *cio); - virtual bool filter_request(struct req_state *s) = 0; virtual RGWOp *get_op(); virtual void put_op(RGWOp *op); diff --git a/src/rgw/rgw_rest.cc b/src/rgw/rgw_rest.cc index 45c4583d6fe4..cfe4017d5d58 100644 --- a/src/rgw/rgw_rest.cc +++ b/src/rgw/rgw_rest.cc @@ -641,39 +641,6 @@ static http_op op_from_method(const char *method) return OP_UNKNOWN; } -int RGWHandler_ObjStore::preprocess(struct req_state *s, RGWClientIO *cio) -{ - s->cio = cio; - s->request_uri = s->env->get("REQUEST_URI"); - int pos = s->request_uri.find('?'); - if (pos >= 0) { - s->request_params = s->request_uri.substr(pos + 1); - s->request_uri = s->request_uri.substr(0, pos); - } - url_decode(s->request_uri, s->decoded_uri); - s->method = s->env->get("REQUEST_METHOD"); - s->host = s->env->get("HTTP_HOST"); - s->length = s->env->get("CONTENT_LENGTH"); - if (s->length) { - if (*s->length == '\0') - return -EINVAL; - s->content_length = atoll(s->length); - } - - s->content_type = s->env->get("CONTENT_TYPE"); - s->http_auth = s->env->get("HTTP_AUTHORIZATION"); - - if (g_conf->rgw_print_continue) { - const char *expect = s->env->get("HTTP_EXPECT"); - s->expect_cont = (expect && !strcasecmp(expect, "100-continue")); - } - s->op = op_from_method(s->method); - - init_meta_info(s); - - return 0; -} - int RGWHandler_ObjStore::read_permissions(RGWOp *op_obj) { bool only_bucket; @@ -709,41 +676,100 @@ int RGWHandler_ObjStore::read_permissions(RGWOp *op_obj) return do_read_permissions(op_obj, only_bucket); } +void RGWRESTMgr::register_resource(string resource, RGWRESTMgr *mgr) +{ + if (resource[resource.size() - 1] != '/') + resource.append("/"); -RGWRESTMgr::RGWRESTMgr() + resource_mgrs[resource] = mgr; + resources_by_size[resource.size()] = resource; +} + +void RGWRESTMgr::register_default_mgr(RGWRESTMgr *mgr) { - // order is important! - protocol_handlers.push_back(new RGWHandler_ObjStore_SWIFT); - protocol_handlers.push_back(new RGWHandler_SWIFT_Auth); - protocol_handlers.push_back(new RGWHandler_ObjStore_S3); + delete default_mgr; + default_mgr = mgr; +} + +RGWRESTMgr *RGWRESTMgr::get_resource_mgr(struct req_state *s, const string& uri) +{ + if (resources_by_size.empty()) + return NULL; + + map::reverse_iterator iter; + + for (iter = resources_by_size.rbegin(); iter != resources_by_size.rend(); ++iter) { + string& resource = iter->second; + if (uri.compare(0, iter->first, resource) == 0) { + string suffix = resource.substr(resource.size() + 1); + return resource_mgrs[resource]->get_resource_mgr(s, suffix); + } + } + + if (default_mgr) + return default_mgr; + + return this; } RGWRESTMgr::~RGWRESTMgr() { - vector::iterator iter; - for (iter = protocol_handlers.begin(); iter != protocol_handlers.end(); ++iter) { - delete *iter; + map::iterator iter; + for (iter = resource_mgrs.begin(); iter != resource_mgrs.end(); ++iter) { + delete iter->second; + } + delete default_mgr; +} + +int RGWREST::preprocess(struct req_state *s, RGWClientIO *cio) +{ + s->cio = cio; + s->request_uri = s->env->get("REQUEST_URI"); + int pos = s->request_uri.find('?'); + if (pos >= 0) { + s->request_params = s->request_uri.substr(pos + 1); + s->request_uri = s->request_uri.substr(0, pos); + } + url_decode(s->request_uri, s->decoded_uri); + s->method = s->env->get("REQUEST_METHOD"); + s->host = s->env->get("HTTP_HOST"); + s->length = s->env->get("CONTENT_LENGTH"); + if (s->length) { + if (*s->length == '\0') + return -EINVAL; + s->content_length = atoll(s->length); + } + + s->content_type = s->env->get("CONTENT_TYPE"); + s->http_auth = s->env->get("HTTP_AUTHORIZATION"); + + if (g_conf->rgw_print_continue) { + const char *expect = s->env->get("HTTP_EXPECT"); + s->expect_cont = (expect && !strcasecmp(expect, "100-continue")); } + s->op = op_from_method(s->method); + + init_meta_info(s); + + return 0; } -RGWHandler *RGWRESTMgr::get_handler(struct req_state *s, RGWClientIO *cio, - int *init_error) +RGWHandler *RGWREST::get_handler(struct req_state *s, RGWClientIO *cio, + int *init_error) { RGWHandler *handler; - *init_error = RGWHandler_ObjStore::preprocess(s, cio); + *init_error = preprocess(s, cio); if (*init_error < 0) return NULL; - vector::iterator iter; - for (iter = protocol_handlers.begin(); iter != protocol_handlers.end(); ++iter) { - handler = *iter; - if (handler->filter_request(s)) - break; - } - if (iter == protocol_handlers.end()) + RGWRESTMgr *m = mgr.get_resource_mgr(s, s->decoded_uri); + if (!m) { + *init_error = -ERR_METHOD_NOT_ALLOWED; return NULL; + } + handler = m->get_handler(s); *init_error = handler->init(s, cio); if (*init_error < 0) return NULL; @@ -751,3 +777,8 @@ RGWHandler *RGWRESTMgr::get_handler(struct req_state *s, RGWClientIO *cio, return handler; } +RGWREST::RGWREST() { + mgr.register_default_mgr(new RGWRESTMgr_S3); + mgr.register_resource("/swift", new RGWRESTMgr_SWIFT); + mgr.register_resource("/auth", new RGWRESTMgr_SWIFT_Auth); +} diff --git a/src/rgw/rgw_rest.h b/src/rgw/rgw_rest.h index 053fe5257e43..16f53c780209 100644 --- a/src/rgw/rgw_rest.h +++ b/src/rgw/rgw_rest.h @@ -155,15 +155,13 @@ public: class RGWHandler_ObjStore : public RGWHandler { protected: - virtual bool is_acl_op() = 0; - virtual bool is_obj_update_op() = 0; - - virtual RGWOp *op_get() = 0; - virtual RGWOp *op_put() = 0; - virtual RGWOp *op_delete() = 0; - virtual RGWOp *op_head() = 0; - virtual RGWOp *op_post() = 0; - virtual RGWOp *op_copy() = 0; + virtual bool is_obj_update_op() { return false; } + virtual RGWOp *op_get() { return NULL; } + virtual RGWOp *op_put() { return NULL; } + virtual RGWOp *op_delete() { return NULL; } + virtual RGWOp *op_head() { return NULL; } + virtual RGWOp *op_post() { return NULL; } + virtual RGWOp *op_copy() { return NULL; } virtual int validate_bucket_name(const string& bucket); virtual int validate_object_name(const string& object); @@ -172,8 +170,6 @@ public: virtual ~RGWHandler_ObjStore() {} int read_permissions(RGWOp *op); - static int preprocess(struct req_state *s, RGWClientIO *cio); - virtual bool filter_request(struct req_state *s) = 0; virtual int authorize() = 0; }; @@ -182,13 +178,34 @@ class RGWHandler_SWIFT_Auth; class RGWHandler_ObjStore_S3; class RGWRESTMgr { - vector protocol_handlers; +protected: + map resource_mgrs; + map resources_by_size; + RGWRESTMgr *default_mgr; public: - RGWRESTMgr(); - ~RGWRESTMgr(); + RGWRESTMgr() : default_mgr(NULL) {} + virtual ~RGWRESTMgr(); + + void register_resource(string resource, RGWRESTMgr *mgr); + void register_default_mgr(RGWRESTMgr *mgr); + + virtual RGWRESTMgr *get_resource_mgr(struct req_state *s, const string& uri); + virtual RGWHandler *get_handler(struct req_state *s) { return NULL; } + virtual void put_handler(RGWHandler *handler) { delete handler; } +}; + +class RGWREST { + RGWRESTMgr mgr; + + static int preprocess(struct req_state *s, RGWClientIO *cio); +public: + RGWREST(); RGWHandler *get_handler(struct req_state *s, RGWClientIO *cio, int *init_error); + void put_handler(RGWHandler *handler) { + mgr.put_handler(handler); + } }; extern void set_req_state_err(struct req_state *s, int err_no); diff --git a/src/rgw/rgw_rest_s3.cc b/src/rgw/rgw_rest_s3.cc index c4ad0a734664..4d0614d86a7a 100644 --- a/src/rgw/rgw_rest_s3.cc +++ b/src/rgw/rgw_rest_s3.cc @@ -647,100 +647,123 @@ void RGWDeleteMultiObj_ObjStore_S3::end_response() rgw_flush_formatter_and_reset(s, s->formatter); } -RGWOp *RGWHandler_ObjStore_S3::get_obj_op(bool get_data) +RGWOp *RGWHandler_ObjStore_Service_S3::op_get() { - if (is_acl_op()) { - return new RGWGetACLs_ObjStore_S3; - } - if (s->object) { - RGWGetObj_ObjStore_S3 *get_obj_op = new RGWGetObj_ObjStore_S3; - get_obj_op->set_get_data(get_data); - return get_obj_op; - } else if (!s->bucket_name) { - return NULL; - } + return new RGWListBuckets_ObjStore_S3; +} - if (s->args.exists("uploads")) - return new RGWListBucketMultiparts_ObjStore_S3; +RGWOp *RGWHandler_ObjStore_Service_S3::op_head() +{ + return new RGWListBuckets_ObjStore_S3; +} +RGWOp *RGWHandler_ObjStore_Bucket_S3::get_obj_op(bool get_data) +{ if (get_data) return new RGWListBucket_ObjStore_S3; else return new RGWStatBucket_ObjStore_S3; } -RGWOp *RGWHandler_ObjStore_S3::op_get() +RGWOp *RGWHandler_ObjStore_Bucket_S3::op_get() { - if (s->bucket_name) { - if (is_acl_op()) { - return new RGWGetACLs_ObjStore_S3; - } else if (s->args.exists("uploadId")) { - return new RGWListMultipart_ObjStore_S3; - } - return get_obj_op(true); + if (is_acl_op()) { + return new RGWGetACLs_ObjStore_S3; + } else if (s->args.exists("uploadId")) { + return new RGWListMultipart_ObjStore_S3; } - - return new RGWListBuckets_ObjStore_S3; + return get_obj_op(true); } -RGWOp *RGWHandler_ObjStore_S3::op_head() +RGWOp *RGWHandler_ObjStore_Bucket_S3::op_head() { - if (s->bucket_name) { - if (is_acl_op()) { - return new RGWGetACLs_ObjStore_S3; - } else if (s->args.exists("uploadId")) { - return new RGWListMultipart_ObjStore_S3; - } - return get_obj_op(false); + if (is_acl_op()) { + return new RGWGetACLs_ObjStore_S3; + } else if (s->args.exists("uploadId")) { + return new RGWListMultipart_ObjStore_S3; } - - return new RGWListBuckets_ObjStore_S3; + return get_obj_op(false); } -RGWOp *RGWHandler_ObjStore_S3::op_put() +RGWOp *RGWHandler_ObjStore_Bucket_S3::op_put() { if (is_acl_op()) { return new RGWPutACLs_ObjStore_S3; - } else if (s->object) { - if (!s->copy_source) - return new RGWPutObj_ObjStore_S3; - else - return new RGWCopyObj_ObjStore_S3; - } else if (s->bucket_name) { - return new RGWCreateBucket_ObjStore_S3; } - - return NULL; + return new RGWCreateBucket_ObjStore_S3; } -RGWOp *RGWHandler_ObjStore_S3::op_delete() +RGWOp *RGWHandler_ObjStore_Bucket_S3::op_delete() { - string upload_id = s->args.get("uploadId"); + return new RGWDeleteBucket_ObjStore_S3; +} - if (s->object) { - if (upload_id.empty()) - return new RGWDeleteObj_ObjStore_S3; - else - return new RGWAbortMultipart_ObjStore_S3; - } else if (s->bucket_name) - return new RGWDeleteBucket_ObjStore_S3; +RGWOp *RGWHandler_ObjStore_Bucket_S3::op_post() +{ + if ( s->request_params == "delete" ) { + return new RGWDeleteMultiObj_ObjStore_S3; + } return NULL; } -RGWOp *RGWHandler_ObjStore_S3::op_post() +RGWOp *RGWHandler_ObjStore_Obj_S3::get_obj_op(bool get_data) { - if (s->object) { - if (s->args.exists("uploadId")) - return new RGWCompleteMultipart_ObjStore_S3; - else - return new RGWInitMultipart_ObjStore_S3; + if (is_acl_op()) { + return new RGWGetACLs_ObjStore_S3; } - else if ( s->request_params == "delete" ) { - return new RGWDeleteMultiObj_ObjStore_S3; + RGWGetObj_ObjStore_S3 *get_obj_op = new RGWGetObj_ObjStore_S3; + get_obj_op->set_get_data(get_data); + return get_obj_op; +} + +RGWOp *RGWHandler_ObjStore_Obj_S3::op_get() +{ + if (is_acl_op()) { + return new RGWGetACLs_ObjStore_S3; + } else if (s->args.exists("uploadId")) { + return new RGWListMultipart_ObjStore_S3; } + return get_obj_op(true); +} - return NULL; +RGWOp *RGWHandler_ObjStore_Obj_S3::op_head() +{ + if (is_acl_op()) { + return new RGWGetACLs_ObjStore_S3; + } else if (s->args.exists("uploadId")) { + return new RGWListMultipart_ObjStore_S3; + } + return get_obj_op(false); +} + +RGWOp *RGWHandler_ObjStore_Obj_S3::op_put() +{ + if (is_acl_op()) { + return new RGWPutACLs_ObjStore_S3; + } + if (!s->copy_source) + return new RGWPutObj_ObjStore_S3; + else + return new RGWCopyObj_ObjStore_S3; +} + +RGWOp *RGWHandler_ObjStore_Obj_S3::op_delete() +{ + string upload_id = s->args.get("uploadId"); + + if (upload_id.empty()) + return new RGWDeleteObj_ObjStore_S3; + else + return new RGWAbortMultipart_ObjStore_S3; +} + +RGWOp *RGWHandler_ObjStore_Obj_S3::op_post() +{ + if (s->args.exists("uploadId")) + return new RGWCompleteMultipart_ObjStore_S3; + else + return new RGWInitMultipart_ObjStore_S3; } int RGWHandler_ObjStore_S3::init_from_header(struct req_state *s) @@ -875,13 +898,9 @@ int RGWHandler_ObjStore_S3::validate_bucket_name(const string& bucket) int RGWHandler_ObjStore_S3::init(struct req_state *s, RGWClientIO *cio) { - int ret = init_from_header(s); - if (ret < 0) - return ret; - dout(10) << "s->object=" << (s->object ? s->object : "") << " s->bucket=" << (s->bucket_name ? s->bucket_name : "") << dendl; - ret = validate_bucket_name(s->bucket_name_str); + int ret = validate_bucket_name(s->bucket_name_str); if (ret) return ret; ret = validate_object_name(s->object_str); @@ -1125,4 +1144,17 @@ int RGWHandler_ObjStore_S3::authorize() return 0; } +RGWHandler *RGWRESTMgr_S3::get_handler(struct req_state *s) +{ + int ret = RGWHandler_ObjStore_S3::init_from_header(s); + if (ret < 0) + return NULL; + + if (!s->bucket_name) + return new RGWHandler_ObjStore_Service_S3; + if (!s->object) + return new RGWHandler_ObjStore_Bucket_S3; + + return new RGWHandler_ObjStore_Obj_S3; +} diff --git a/src/rgw/rgw_rest_s3.h b/src/rgw/rgw_rest_s3.h index 12af134823e8..86d3352f310f 100644 --- a/src/rgw/rgw_rest_s3.h +++ b/src/rgw/rgw_rest_s3.h @@ -163,8 +163,30 @@ public: void end_response(); }; - class RGWHandler_ObjStore_S3 : public RGWHandler_ObjStore { + friend class RGWRESTMgr_S3; +protected: + static int init_from_header(struct req_state *s); +public: + RGWHandler_ObjStore_S3() : RGWHandler_ObjStore() {} + virtual ~RGWHandler_ObjStore_S3() {} + + int validate_bucket_name(const string& bucket); + + virtual int init(struct req_state *state, RGWClientIO *cio); + int authorize(); +}; + +class RGWHandler_ObjStore_Service_S3 : public RGWHandler_ObjStore_S3 { +protected: + RGWOp *op_get(); + RGWOp *op_head(); +public: + RGWHandler_ObjStore_Service_S3() {} + virtual ~RGWHandler_ObjStore_Service_S3() {} +}; + +class RGWHandler_ObjStore_Bucket_S3 : public RGWHandler_ObjStore_S3 { protected: bool is_acl_op() { return s->args.exists("acl"); @@ -179,18 +201,41 @@ protected: RGWOp *op_put(); RGWOp *op_delete(); RGWOp *op_post(); - RGWOp *op_copy() { return NULL; } +public: + RGWHandler_ObjStore_Bucket_S3() {} + virtual ~RGWHandler_ObjStore_Bucket_S3() {} +}; - int init_from_header(struct req_state *s); +class RGWHandler_ObjStore_Obj_S3 : public RGWHandler_ObjStore_S3 { +protected: + bool is_acl_op() { + return s->args.exists("acl"); + } + bool is_obj_update_op() { + return is_acl_op(); + } + RGWOp *get_obj_op(bool get_data); + + RGWOp *op_get(); + RGWOp *op_head(); + RGWOp *op_put(); + RGWOp *op_delete(); + RGWOp *op_post(); public: - RGWHandler_ObjStore_S3() : RGWHandler_ObjStore() {} - virtual ~RGWHandler_ObjStore_S3() {} + RGWHandler_ObjStore_Obj_S3() {} + virtual ~RGWHandler_ObjStore_Obj_S3() {} +}; - bool filter_request(struct req_state *state) { return true; } - int validate_bucket_name(const string& bucket); +class RGWRESTMgr_S3 : public RGWRESTMgr { +public: + RGWRESTMgr_S3() {} + virtual ~RGWRESTMgr_S3() {} - virtual int init(struct req_state *state, RGWClientIO *cio); - int authorize(); + virtual RGWRESTMgr *get_resource_mgr(struct req_state *s, const string& uri) { + return this; + } + virtual RGWHandler *get_handler(struct req_state *s); }; + #endif diff --git a/src/rgw/rgw_rest_swift.cc b/src/rgw/rgw_rest_swift.cc index 3b59c7ab6c6e..fc7595f38c36 100644 --- a/src/rgw/rgw_rest_swift.cc +++ b/src/rgw/rgw_rest_swift.cc @@ -485,121 +485,124 @@ send_data: return 0; } -RGWOp *RGWHandler_ObjStore_SWIFT::get_obj_op(bool get_data) +RGWOp *RGWHandler_ObjStore_Service_SWIFT::op_get() +{ + return new RGWListBuckets_ObjStore_SWIFT; +} + +RGWOp *RGWHandler_ObjStore_Service_SWIFT::op_head() +{ + return new RGWStatAccount_ObjStore_SWIFT; +} + +RGWOp *RGWHandler_ObjStore_Bucket_SWIFT::get_obj_op(bool get_data) { if (is_acl_op()) { return new RGWGetACLs_ObjStore_SWIFT; } - if (s->object) { - RGWGetObj_ObjStore_SWIFT *get_obj_op = new RGWGetObj_ObjStore_SWIFT; - get_obj_op->set_get_data(get_data); - return get_obj_op; - } else if (!s->bucket_name) { - return NULL; - } - if (get_data) return new RGWListBucket_ObjStore_SWIFT; else return new RGWStatBucket_ObjStore_SWIFT; } -RGWOp *RGWHandler_ObjStore_SWIFT::op_get() +RGWOp *RGWHandler_ObjStore_Bucket_SWIFT::op_get() { - if (s->bucket_name) { - if (is_acl_op()) { - return new RGWGetACLs_ObjStore_SWIFT; - } - return get_obj_op(true); + if (is_acl_op()) { + return new RGWGetACLs_ObjStore_SWIFT; } - - return new RGWListBuckets_ObjStore_SWIFT; + return get_obj_op(true); } -RGWOp *RGWHandler_ObjStore_SWIFT::op_head() +RGWOp *RGWHandler_ObjStore_Bucket_SWIFT::op_head() { - if (s->bucket_name) { - if (is_acl_op()) { - return new RGWGetACLs_ObjStore_SWIFT; - } - return get_obj_op(false); + if (is_acl_op()) { + return new RGWGetACLs_ObjStore_SWIFT; } - - return new RGWStatAccount_ObjStore_SWIFT; + return get_obj_op(false); } -RGWOp *RGWHandler_ObjStore_SWIFT::op_put() +RGWOp *RGWHandler_ObjStore_Bucket_SWIFT::op_put() { if (is_acl_op()) { return new RGWPutACLs_ObjStore_SWIFT; - } else if (s->object) { - if (!s->copy_source) - return new RGWPutObj_ObjStore_SWIFT; - else - return new RGWCopyObj_ObjStore_SWIFT; - } else if (s->bucket_name) { - return new RGWCreateBucket_ObjStore_SWIFT; } - - return NULL; + return new RGWCreateBucket_ObjStore_SWIFT; } -RGWOp *RGWHandler_ObjStore_SWIFT::op_delete() +RGWOp *RGWHandler_ObjStore_Bucket_SWIFT::op_delete() { - if (s->object) - return new RGWDeleteObj_ObjStore_SWIFT; - else if (s->bucket_name) - return new RGWDeleteBucket_ObjStore_SWIFT; - - return NULL; + return new RGWDeleteBucket_ObjStore_SWIFT; } -RGWOp *RGWHandler_ObjStore_SWIFT::op_post() +RGWOp *RGWHandler_ObjStore_Bucket_SWIFT::op_post() { return new RGWPutMetadata_ObjStore_SWIFT; } -RGWOp *RGWHandler_ObjStore_SWIFT::op_copy() +RGWOp *RGWHandler_ObjStore_Obj_SWIFT::get_obj_op(bool get_data) { - if (s->object) - return new RGWCopyObj_ObjStore_SWIFT; + if (is_acl_op()) { + return new RGWGetACLs_ObjStore_SWIFT; + } - return NULL; + RGWGetObj_ObjStore_SWIFT *get_obj_op = new RGWGetObj_ObjStore_SWIFT; + get_obj_op->set_get_data(get_data); + return get_obj_op; } -int RGWHandler_ObjStore_SWIFT::authorize() +RGWOp *RGWHandler_ObjStore_Obj_SWIFT::op_get() { - bool authorized = rgw_verify_os_token(s); - if (!authorized) - return -EPERM; - - s->perm_mask = RGW_PERM_FULL_CONTROL; + if (is_acl_op()) { + return new RGWGetACLs_ObjStore_SWIFT; + } + return get_obj_op(true); +} - return 0; +RGWOp *RGWHandler_ObjStore_Obj_SWIFT::op_head() +{ + if (is_acl_op()) { + return new RGWGetACLs_ObjStore_SWIFT; + } + return get_obj_op(false); } -bool RGWHandler_ObjStore_SWIFT::filter_request(struct req_state *s) +RGWOp *RGWHandler_ObjStore_Obj_SWIFT::op_put() { - string& uri = s->decoded_uri; - size_t len = g_conf->rgw_swift_url_prefix.size(); + if (is_acl_op()) { + return new RGWPutACLs_ObjStore_SWIFT; + } + if (!s->copy_source) + return new RGWPutObj_ObjStore_SWIFT; + else + return new RGWCopyObj_ObjStore_SWIFT; +} - if (uri.size() < len + 1) - return false; +RGWOp *RGWHandler_ObjStore_Obj_SWIFT::op_delete() +{ + return new RGWDeleteObj_ObjStore_SWIFT; +} - if (uri[0] != '/') - return false; +RGWOp *RGWHandler_ObjStore_Obj_SWIFT::op_post() +{ + return new RGWPutMetadata_ObjStore_SWIFT; +} - if (uri.substr(1, len) != g_conf->rgw_swift_url_prefix) - return false; +RGWOp *RGWHandler_ObjStore_Obj_SWIFT::op_copy() +{ + return new RGWCopyObj_ObjStore_SWIFT; +} - if (uri.size() == len + 1) - return true; +int RGWHandler_ObjStore_SWIFT::authorize() +{ + bool authorized = rgw_verify_os_token(s); + if (!authorized) + return -EPERM; - if (uri[len] != '/') - return false; + s->perm_mask = RGW_PERM_FULL_CONTROL; - return true; + return 0; } int RGWHandler_ObjStore_SWIFT::validate_bucket_name(const string& bucket) @@ -752,13 +755,9 @@ int RGWHandler_ObjStore_SWIFT::init_from_header(struct req_state *s) int RGWHandler_ObjStore_SWIFT::init(struct req_state *s, RGWClientIO *cio) { - int ret = init_from_header(s); - if (ret < 0) - return ret; - dout(10) << "s->object=" << (s->object ? s->object : "") << " s->bucket=" << (s->bucket_name ? s->bucket_name : "") << dendl; - ret = validate_bucket_name(s->bucket_name_str.c_str()); + int ret = validate_bucket_name(s->bucket_name_str.c_str()); if (ret) return ret; ret = validate_object_name(s->object_str.c_str()); @@ -771,3 +770,18 @@ int RGWHandler_ObjStore_SWIFT::init(struct req_state *s, RGWClientIO *cio) return RGWHandler_ObjStore::init(s, cio); } + + +RGWHandler *RGWRESTMgr_SWIFT::get_handler(struct req_state *s) +{ + int ret = RGWHandler_ObjStore_SWIFT::init_from_header(s); + if (ret < 0) + return NULL; + + if (!s->bucket_name) + return new RGWHandler_ObjStore_Service_SWIFT; + if (!s->object) + return new RGWHandler_ObjStore_Bucket_SWIFT; + + return new RGWHandler_ObjStore_Obj_SWIFT; +} diff --git a/src/rgw/rgw_rest_swift.h b/src/rgw/rgw_rest_swift.h index fff875d6cc16..4b33fda57069 100644 --- a/src/rgw/rgw_rest_swift.h +++ b/src/rgw/rgw_rest_swift.h @@ -126,12 +126,38 @@ public: void send_response() {} }; - class RGWHandler_ObjStore_SWIFT : public RGWHandler_ObjStore { + friend class RGWRESTMgr_SWIFT; protected: - bool is_acl_op() { - return false; // for now + virtual bool is_acl_op() { + return false; } + + static int init_from_header(struct req_state *s); +public: + RGWHandler_ObjStore_SWIFT() {} + virtual ~RGWHandler_ObjStore_SWIFT() {} + + int validate_bucket_name(const string& bucket); + + int init(struct req_state *state, RGWClientIO *cio); + int authorize(); + + RGWAccessControlPolicy *alloc_policy() { return NULL; /* return new RGWAccessControlPolicy_SWIFT; */ } + void free_policy(RGWAccessControlPolicy *policy) { delete policy; } +}; + +class RGWHandler_ObjStore_Service_SWIFT : public RGWHandler_ObjStore_SWIFT { +protected: + RGWOp *op_get(); + RGWOp *op_head(); +public: + RGWHandler_ObjStore_Service_SWIFT() {} + virtual ~RGWHandler_ObjStore_Service_SWIFT() {} +}; + +class RGWHandler_ObjStore_Bucket_SWIFT : public RGWHandler_ObjStore_SWIFT { +protected: bool is_obj_update_op() { return s->op == OP_POST; } @@ -142,21 +168,38 @@ protected: RGWOp *op_put(); RGWOp *op_delete(); RGWOp *op_post(); - RGWOp *op_copy(); - - int init_from_header(struct req_state *s); public: - RGWHandler_ObjStore_SWIFT() : RGWHandler_ObjStore() {} - virtual ~RGWHandler_ObjStore_SWIFT() {} + RGWHandler_ObjStore_Bucket_SWIFT() {} + virtual ~RGWHandler_ObjStore_Bucket_SWIFT() {} +}; - bool filter_request(struct req_state *s); - int validate_bucket_name(const string& bucket); +class RGWHandler_ObjStore_Obj_SWIFT : public RGWHandler_ObjStore_SWIFT { +protected: + bool is_obj_update_op() { + return s->op == OP_POST; + } - int init(struct req_state *state, RGWClientIO *cio); - int authorize(); + RGWOp *get_obj_op(bool get_data); + RGWOp *op_get(); + RGWOp *op_head(); + RGWOp *op_put(); + RGWOp *op_delete(); + RGWOp *op_post(); + RGWOp *op_copy(); +public: + RGWHandler_ObjStore_Obj_SWIFT() {} + virtual ~RGWHandler_ObjStore_Obj_SWIFT() {} +}; - RGWAccessControlPolicy *alloc_policy() { return NULL; /* return new RGWAccessControlPolicy_SWIFT; */ } - void free_policy(RGWAccessControlPolicy *policy) { delete policy; } +class RGWRESTMgr_SWIFT : public RGWRESTMgr { +public: + RGWRESTMgr_SWIFT() {} + virtual ~RGWRESTMgr_SWIFT() {} + + virtual RGWRESTMgr *get_resource_mgr(struct req_state *s, const string& uri) { + return this; + } + virtual RGWHandler *get_handler(struct req_state *s); }; #endif diff --git a/src/rgw/rgw_swift_auth.cc b/src/rgw/rgw_swift_auth.cc index 7b9df146a596..656a3314351f 100644 --- a/src/rgw/rgw_swift_auth.cc +++ b/src/rgw/rgw_swift_auth.cc @@ -218,48 +218,6 @@ done: end_header(s); } -bool RGWHandler_SWIFT_Auth::filter_request(struct req_state *s) -{ - const string& auth_bucket = g_conf->rgw_swift_auth_entry; - string bucket; - - if (auth_bucket.empty()) - return false; - - int pos; - if (g_conf->rgw_dns_name.length() && s->host) { - string h(s->host); - - dout(10) << "host=" << s->host << " rgw_dns_name=" << g_conf->rgw_dns_name << dendl; - pos = h.find(g_conf->rgw_dns_name); - - if (pos > 0 && h[pos - 1] == '.') { - bucket = h.substr(0, pos-1); - return (bucket.compare(auth_bucket) == 0); - } - } - - const char *req_name = s->decoded_uri.c_str(); - - if (*req_name != '/') - return false; - - req_name++; - if (!*req_name) - return 0; - - string req = req_name; - pos = req.find('/'); - if (pos >= 0) { - bucket = req.substr(0, pos); - } else { - bucket = req; - } - - bucket = req.substr(0, pos); - return (bucket.compare(auth_bucket) == 0); -} - int RGWHandler_SWIFT_Auth::init(struct req_state *state, RGWClientIO *cio) { state->dialect = "swift-auth"; diff --git a/src/rgw/rgw_swift_auth.h b/src/rgw/rgw_swift_auth.h index 03b6b8177681..0747a40ab2d6 100644 --- a/src/rgw/rgw_swift_auth.h +++ b/src/rgw/rgw_swift_auth.h @@ -2,6 +2,7 @@ #define CEPH_RGW_SWIFT_AUTH_H #include "rgw_op.h" +#include "rgw_rest.h" #define RGW_SWIFT_TOKEN_EXPIRATION (15 * 60) @@ -23,10 +24,6 @@ public: ~RGWHandler_SWIFT_Auth() {} RGWOp *op_get(); - bool filter_request(struct req_state *s); - - int validate_bucket_name(const string& bucket) { return 0; } - int validate_object_name(const string& object) { return 0; } int init(struct req_state *state, RGWClientIO *cio); int authorize(); int read_permissions(RGWOp *op) { return 0; } @@ -35,4 +32,18 @@ public: virtual void free_policy(RGWAccessControlPolicy *policy) {} }; +class RGWRESTMgr_SWIFT_Auth : public RGWRESTMgr { +public: + RGWRESTMgr_SWIFT_Auth() {} + virtual ~RGWRESTMgr_SWIFT_Auth() {} + + virtual RGWRESTMgr *get_resource_mgr(struct req_state *s, const string& uri) { + return this; + } + virtual RGWHandler *get_handler(struct req_state *s) { + return new RGWHandler_SWIFT_Auth; + } +}; + + #endif