diff options
author | Yehuda Sadeh <yehuda@inktank.com> | 2013-09-04 16:18:38 -0700 |
---|---|---|
committer | Yehuda Sadeh <yehuda@inktank.com> | 2013-09-04 16:18:38 -0700 |
commit | ea412c05f61e54c7a6749ca0b699e5fcbafa6191 (patch) | |
tree | 267416d002f8eb94b8b13e5d3d2d1b414789c2c1 | |
parent | d9187a73c3e1f21f0be894e983feb4a7d495b729 (diff) | |
parent | 6af5a5377f9730aeee3fc1432445becea47794dd (diff) | |
download | ceph-ea412c05f61e54c7a6749ca0b699e5fcbafa6191.tar.gz |
Merge branch 'wip-6078' into next
Reviewed-by: Josh Durgin <josh.durgin@inktank.com>
-rw-r--r-- | src/rgw/rgw_common.cc | 5 | ||||
-rw-r--r-- | src/rgw/rgw_common.h | 1 | ||||
-rw-r--r-- | src/rgw/rgw_cors.cc | 3 | ||||
-rw-r--r-- | src/rgw/rgw_cors.h | 12 | ||||
-rw-r--r-- | src/rgw/rgw_cors_s3.cc | 4 | ||||
-rw-r--r-- | src/rgw/rgw_main.cc | 16 | ||||
-rw-r--r-- | src/rgw/rgw_op.cc | 204 | ||||
-rw-r--r-- | src/rgw/rgw_op.h | 9 | ||||
-rw-r--r-- | src/rgw/rgw_rest.cc | 30 | ||||
-rw-r--r-- | src/rgw/rgw_rest.h | 15 | ||||
-rw-r--r-- | src/rgw/rgw_rest_s3.cc | 53 | ||||
-rw-r--r-- | src/rgw/rgw_rest_swift.cc | 28 |
12 files changed, 231 insertions, 149 deletions
diff --git a/src/rgw/rgw_common.cc b/src/rgw/rgw_common.cc index ef0a2604d51..c872314fe4e 100644 --- a/src/rgw/rgw_common.cc +++ b/src/rgw/rgw_common.cc @@ -123,8 +123,8 @@ void req_info::rebuild_from(req_info& src) req_state::req_state(CephContext *_cct, class RGWEnv *e) : cct(_cct), cio(NULL), op(OP_UNKNOWN), - bucket_cors(NULL), has_acl_header(false), - os_auth_token(NULL), info(_cct, e) + has_acl_header(false), + os_auth_token(NULL), info(_cct, e) { enable_ops_log = e->conf->enable_ops_log; enable_usage_log = e->conf->enable_usage_log; @@ -162,7 +162,6 @@ req_state::req_state(CephContext *_cct, class RGWEnv *e) : cct(_cct), cio(NULL), req_state::~req_state() { delete formatter; delete bucket_acl; - delete bucket_cors; delete object_acl; free((void *)object); free((void *)bucket_name); diff --git a/src/rgw/rgw_common.h b/src/rgw/rgw_common.h index 405c3d9b3ba..2c7c0c716be 100644 --- a/src/rgw/rgw_common.h +++ b/src/rgw/rgw_common.h @@ -821,7 +821,6 @@ struct req_state { RGWUserInfo user; RGWAccessControlPolicy *bucket_acl; RGWAccessControlPolicy *object_acl; - RGWCORSConfiguration *bucket_cors; bool system_request; diff --git a/src/rgw/rgw_cors.cc b/src/rgw/rgw_cors.cc index 033bfa2f215..4be83605b50 100644 --- a/src/rgw/rgw_cors.cc +++ b/src/rgw/rgw_cors.cc @@ -79,7 +79,10 @@ static bool is_string_in_set(set<string>& s, string h) { << ", at offset not less than " << flen << dendl; if (h.compare((h.size() - sl.size()), sl.size(), sl) != 0) continue; + ssplit.pop_front(); } + if (!ssplit.empty()) + continue; return true; } } diff --git a/src/rgw/rgw_cors.h b/src/rgw/rgw_cors.h index 415f3f0b869..1e0ec3bc7ec 100644 --- a/src/rgw/rgw_cors.h +++ b/src/rgw/rgw_cors.h @@ -25,11 +25,13 @@ #define RGW_CORS_HEAD 0x4 #define RGW_CORS_POST 0x8 #define RGW_CORS_DELETE 0x10 -#define RGW_CORS_ALL (RGW_CORS_GET | \ - RGW_CORS_PUT | \ - RGW_CORS_HEAD | \ - RGW_CORS_POST | \ - RGW_CORS_DELETE) +#define RGW_CORS_COPY 0x20 +#define RGW_CORS_ALL (RGW_CORS_GET | \ + RGW_CORS_PUT | \ + RGW_CORS_HEAD | \ + RGW_CORS_POST | \ + RGW_CORS_DELETE | \ + RGW_CORS_COPY) #define CORS_MAX_AGE_INVALID ((uint32_t)-1) diff --git a/src/rgw/rgw_cors_s3.cc b/src/rgw/rgw_cors_s3.cc index c1448f26b23..01150a9e65b 100644 --- a/src/rgw/rgw_cors_s3.cc +++ b/src/rgw/rgw_cors_s3.cc @@ -44,6 +44,8 @@ void RGWCORSRule_S3::to_xml(XMLFormatter& f) { f.dump_string("AllowedMethod", "HEAD"); if (allowed_methods & RGW_CORS_POST) f.dump_string("AllowedMethod", "POST"); + if (allowed_methods & RGW_CORS_COPY) + f.dump_string("AllowedMethod", "COPY"); /*AllowedOrigins*/ for(set<string>::iterator it = allowed_origins.begin(); it != allowed_origins.end(); @@ -87,6 +89,8 @@ bool RGWCORSRule_S3::xml_end(const char *el) { allowed_methods |= RGW_CORS_HEAD; } else if (strcasecmp(s, "PUT") == 0) { allowed_methods |= RGW_CORS_PUT; + } else if (strcasecmp(s, "COPY") == 0) { + allowed_methods |= RGW_CORS_COPY; } else { return false; } diff --git a/src/rgw/rgw_main.cc b/src/rgw/rgw_main.cc index 12301ba9c5f..54db609521c 100644 --- a/src/rgw/rgw_main.cc +++ b/src/rgw/rgw_main.cc @@ -323,7 +323,7 @@ void RGWProcess::handle_request(RGWRequest *req) RGWRESTMgr *mgr; RGWHandler *handler = rest->get_handler(store, s, &client_io, &mgr, &init_error); if (init_error != 0) { - abort_early(s, init_error); + abort_early(s, NULL, init_error); goto done; } @@ -332,7 +332,7 @@ void RGWProcess::handle_request(RGWRequest *req) req->log(s, "getting op"); op = handler->get_op(store); if (!op) { - abort_early(s, -ERR_METHOD_NOT_ALLOWED); + abort_early(s, NULL, -ERR_METHOD_NOT_ALLOWED); goto done; } req->op = op; @@ -341,26 +341,26 @@ void RGWProcess::handle_request(RGWRequest *req) ret = handler->authorize(); if (ret < 0) { dout(10) << "failed to authorize request" << dendl; - abort_early(s, ret); + abort_early(s, op, ret); goto done; } if (s->user.suspended) { dout(10) << "user is suspended, uid=" << s->user.user_id << dendl; - abort_early(s, -ERR_USER_SUSPENDED); + abort_early(s, op, -ERR_USER_SUSPENDED); goto done; } req->log(s, "reading permissions"); ret = handler->read_permissions(op); if (ret < 0) { - abort_early(s, ret); + abort_early(s, op, ret); goto done; } req->log(s, "verifying op mask"); ret = op->verify_op_mask(); if (ret < 0) { - abort_early(s, ret); + abort_early(s, op, ret); goto done; } @@ -370,7 +370,7 @@ void RGWProcess::handle_request(RGWRequest *req) if (s->system_request) { dout(2) << "overriding permissions due to system operation" << dendl; } else { - abort_early(s, ret); + abort_early(s, op, ret); goto done; } } @@ -378,7 +378,7 @@ void RGWProcess::handle_request(RGWRequest *req) req->log(s, "verifying op params"); ret = op->verify_params(); if (ret < 0) { - abort_early(s, ret); + abort_early(s, op, ret); goto done; } diff --git a/src/rgw/rgw_op.cc b/src/rgw/rgw_op.cc index d34e18bc4ba..15e51712ca3 100644 --- a/src/rgw/rgw_op.cc +++ b/src/rgw/rgw_op.cc @@ -421,6 +421,111 @@ int RGWOp::verify_op_mask() return 0; } +static bool validate_cors_rule_method(RGWCORSRule *rule, const char *req_meth) { + uint8_t flags = 0; + if (strcmp(req_meth, "GET") == 0) flags = RGW_CORS_GET; + else if (strcmp(req_meth, "POST") == 0) flags = RGW_CORS_POST; + else if (strcmp(req_meth, "PUT") == 0) flags = RGW_CORS_PUT; + else if (strcmp(req_meth, "DELETE") == 0) flags = RGW_CORS_DELETE; + else if (strcmp(req_meth, "HEAD") == 0) flags = RGW_CORS_HEAD; + + if ((rule->get_allowed_methods() & flags) == flags) { + dout(10) << "Method " << req_meth << " is supported" << dendl; + } else { + dout(5) << "Method " << req_meth << " is not supported" << dendl; + return false; + } + + return true; +} + +int RGWOp::read_bucket_cors() +{ + bufferlist bl; + + map<string, bufferlist>::iterator aiter = s->bucket_attrs.find(RGW_ATTR_CORS); + if (aiter == s->bucket_attrs.end()) { + ldout(s->cct, 20) << "no CORS configuration attr found" << dendl; + cors_exist = false; + return 0; /* no CORS configuration found */ + } + + cors_exist = true; + + bl = aiter->second; + + bufferlist::iterator iter = bl.begin(); + try { + bucket_cors.decode(iter); + } catch (buffer::error& err) { + ldout(s->cct, 0) << "ERROR: could not decode policy, caught buffer::error" << dendl; + return -EIO; + } + if (s->cct->_conf->subsys.should_gather(ceph_subsys_rgw, 15)) { + RGWCORSConfiguration_S3 *s3cors = static_cast<RGWCORSConfiguration_S3 *>(&bucket_cors); + ldout(s->cct, 15) << "Read RGWCORSConfiguration"; + s3cors->to_xml(*_dout); + *_dout << dendl; + } + return 0; +} + +static void get_cors_response_headers(RGWCORSRule *rule, const char *req_hdrs, string& hdrs, string& exp_hdrs, unsigned *max_age) { + if (req_hdrs) { + list<string> hl; + get_str_list(req_hdrs, hl); + for(list<string>::iterator it = hl.begin(); it != hl.end(); ++it) { + if (!rule->is_header_allowed((*it).c_str(), (*it).length())) { + dout(5) << "Header " << (*it) << " is not registered in this rule" << dendl; + } else { + if (hdrs.length() > 0) hdrs.append(","); + hdrs.append((*it)); + } + } + } + rule->format_exp_headers(exp_hdrs); + *max_age = rule->get_max_age(); +} + +bool RGWOp::generate_cors_headers(string& origin, string& method, string& headers, string& exp_headers, unsigned *max_age) +{ + const char *orig = s->info.env->get("HTTP_ORIGIN"); + if (!orig) { + return false; + } + origin = orig; + int ret = read_bucket_cors(); + if (ret < 0) { + return false; + } + + if (!cors_exist) { + dout(2) << "No CORS configuration set yet for this bucket" << dendl; + return false; + } + + RGWCORSRule *rule = bucket_cors.host_name_rule(orig); + if (!rule) + return false; + + const char *req_meth = s->info.env->get("HTTP_ACCESS_CONTROL_REQUEST_METHOD"); + if (!req_meth) { + req_meth = s->info.method; + } + + if (req_meth) + method = req_meth; + + if (!validate_cors_rule_method(rule, req_meth)) { + return false; + } + + const char *req_hdrs = s->info.env->get("HTTP_ACCESS_CONTROL_ALLOW_HEADERS"); + + get_cors_response_headers(rule, req_hdrs, headers, exp_headers, max_age); + + return true; +} int RGWGetObj::read_user_manifest_part(rgw_bucket& bucket, RGWObjEnt& ent, RGWAccessControlPolicy *bucket_policy, off_t start_ofs, off_t end_ofs) { @@ -1835,37 +1940,6 @@ void RGWPutACLs::execute() } } -static int read_bucket_cors(RGWRados *store, struct req_state *s, RGWCORSConfiguration *bucket_cors, bool *exist) -{ - bufferlist bl; - - map<string, bufferlist>::iterator aiter = s->bucket_attrs.find(RGW_ATTR_CORS); - if (aiter == s->bucket_attrs.end()) { - ldout(s->cct, 20) << "no CORS configuration attr found" << dendl; - *exist = false; - return 0; /* no CORS configuration found */ - } - - *exist = true; - - bl = aiter->second; - - bufferlist::iterator iter = bl.begin(); - try { - bucket_cors->decode(iter); - } catch (buffer::error& err) { - ldout(s->cct, 0) << "ERROR: could not decode policy, caught buffer::error" << dendl; - return -EIO; - } - if (s->cct->_conf->subsys.should_gather(ceph_subsys_rgw, 15)) { - RGWCORSConfiguration_S3 *s3cors = static_cast<RGWCORSConfiguration_S3 *>(bucket_cors); - ldout(s->cct, 15) << "Read RGWCORSConfiguration"; - s3cors->to_xml(*_dout); - *_dout << dendl; - } - return 0; -} - int RGWGetCORS::verify_permission() { if (s->user.user_id.compare(s->bucket_owner.get_id()) != 0) @@ -1876,9 +1950,7 @@ int RGWGetCORS::verify_permission() void RGWGetCORS::execute() { - bool cors_exist; - - ret = read_bucket_cors(store, s, &bucket_cors, &cors_exist); + ret = read_bucket_cors(); if (ret < 0) return ; @@ -1922,9 +1994,8 @@ int RGWDeleteCORS::verify_permission() void RGWDeleteCORS::execute() { - bool cors_exist; RGWCORSConfiguration bucket_cors; - ret = read_bucket_cors(store, s, &bucket_cors, &cors_exist); + ret = read_bucket_cors(); if (ret < 0) return; @@ -1961,52 +2032,34 @@ void RGWDeleteCORS::execute() } void RGWOptionsCORS::get_response_params(string& hdrs, string& exp_hdrs, unsigned *max_age) { - if (req_hdrs) { - list<string> hl; - get_str_list(req_hdrs, hl); - for(list<string>::iterator it = hl.begin(); it != hl.end(); ++it) { - if (!rule->is_header_allowed((*it).c_str(), (*it).length())) { - dout(5) << "Header " << (*it) << " is not registered in this rule" << dendl; - } else { - if (hdrs.length() > 0)hdrs.append(","); - hdrs.append((*it)); - } - } - } - rule->format_exp_headers(exp_hdrs); - *max_age = rule->get_max_age(); + get_cors_response_headers(rule, req_hdrs, hdrs, exp_hdrs, max_age); } -int RGWOptionsCORS::validate_cors_request() { - RGWCORSConfiguration *cc = s->bucket_cors; +int RGWOptionsCORS::validate_cors_request(RGWCORSConfiguration *cc) { rule = cc->host_name_rule(origin); if (!rule) { - dout(10) << "There is no corsrule present for " << origin << dendl; + dout(10) << "There is no cors rule present for " << origin << dendl; return -ENOENT; } - uint8_t flags = 0; - if (strcmp(req_meth, "GET") == 0) flags = RGW_CORS_GET; - else if (strcmp(req_meth, "POST") == 0) flags = RGW_CORS_POST; - else if (strcmp(req_meth, "PUT") == 0) flags = RGW_CORS_PUT; - else if (strcmp(req_meth, "DELETE") == 0) flags = RGW_CORS_DELETE; - else if (strcmp(req_meth, "HEAD") == 0) flags = RGW_CORS_HEAD; - - if ((rule->get_allowed_methods() & flags) == flags) { - dout(10) << "Method " << req_meth << " is supported" << dendl; - } else { - dout(5) << "Method " << req_meth << " is not supported" << dendl; - req_meth = NULL; - return -ENOTSUP; + if (!validate_cors_rule_method(rule, req_meth)) { + return -ENOENT; } return 0; } void RGWOptionsCORS::execute() { - if (!s->bucket_cors) { - dout(2) << "No CORS configuration set yet for this bucket" << dendl; - ret = -EACCES; + ret = read_bucket_cors(); + if (ret < 0) + return; + + origin = s->info.env->get("HTTP_ORIGIN"); + if (!origin) { + dout(0) << + "Preflight request without mandatory Origin header" + << dendl; + ret = -EINVAL; return; } req_meth = s->info.env->get("HTTP_ACCESS_CONTROL_REQUEST_METHOD"); @@ -2014,19 +2067,16 @@ void RGWOptionsCORS::execute() dout(0) << "Preflight request without mandatory Access-control-request-method header" << dendl; - ret = -EACCES; + ret = -EINVAL; return; } - origin = s->info.env->get("HTTP_ORIGIN"); - if (!origin) { - dout(0) << - "Preflight request without mandatory Origin header" - << dendl; - ret = -EACCES; + if (!cors_exist) { + dout(2) << "No CORS configuration set yet for this bucket" << dendl; + ret = -ENOENT; return; } req_hdrs = s->info.env->get("HTTP_ACCESS_CONTROL_ALLOW_HEADERS"); - ret = validate_cors_request(); + ret = validate_cors_request(&bucket_cors); if (!rule) { origin = req_meth = NULL; return; diff --git a/src/rgw/rgw_op.h b/src/rgw/rgw_op.h index d158f831cc7..241584bac68 100644 --- a/src/rgw/rgw_op.h +++ b/src/rgw/rgw_op.h @@ -34,8 +34,10 @@ protected: struct req_state *s; RGWHandler *dialect_handler; RGWRados *store; + RGWCORSConfiguration bucket_cors; + bool cors_exist; public: - RGWOp() : s(NULL), dialect_handler(NULL), store(NULL) {} + RGWOp() : s(NULL), dialect_handler(NULL), store(NULL), cors_exist(false) {} virtual ~RGWOp() {} virtual void init(RGWRados *store, struct req_state *s, RGWHandler *dialect_handler) { @@ -43,6 +45,9 @@ public: this->s = s; this->dialect_handler = dialect_handler; } + int read_bucket_cors(); + bool generate_cors_headers(string& origin, string& method, string& headers, string& exp_headers, unsigned *max_age); + virtual int verify_params() { return 0; } virtual bool prefetch_data() { return false; } virtual int verify_permission() = 0; @@ -586,7 +591,7 @@ public: } int verify_permission() {return 0;} - int validate_cors_request(); + int validate_cors_request(RGWCORSConfiguration *cc); void execute(); void get_response_params(string& allowed_hdrs, string& exp_hdrs, unsigned *max_age); virtual void send_response() = 0; diff --git a/src/rgw/rgw_rest.cc b/src/rgw/rgw_rest.cc index 571e4869642..196bd29e99b 100644 --- a/src/rgw/rgw_rest.cc +++ b/src/rgw/rgw_rest.cc @@ -377,6 +377,20 @@ void dump_access_control(struct req_state *s, const char *origin, const char *me } } +void dump_access_control(req_state *s, RGWOp *op) +{ + string origin; + string method; + string header; + string exp_header; + unsigned max_age = CORS_MAX_AGE_INVALID; + + if (!op->generate_cors_headers(origin, method, header, exp_header, &max_age)) + return; + + dump_access_control(s, origin.c_str(), method.c_str(), header.c_str(), exp_header.c_str(), max_age); +} + void dump_start(struct req_state *s) { if (!s->content_started) { @@ -386,10 +400,14 @@ void dump_start(struct req_state *s) } } -void end_header(struct req_state *s, const char *content_type) +void end_header(struct req_state *s, RGWOp *op, const char *content_type) { string ctype; + if (op) { + dump_access_control(s, op); + } + if (!content_type || s->err.is_err()) { switch (s->format) { case RGW_FORMAT_XML: @@ -424,7 +442,7 @@ void end_header(struct req_state *s, const char *content_type) rgw_flush_formatter_and_reset(s, s->formatter); } -void abort_early(struct req_state *s, int err_no) +void abort_early(struct req_state *s, RGWOp *op, int err_no) { if (!s->formatter) { s->formatter = new JSONFormatter; @@ -432,7 +450,7 @@ void abort_early(struct req_state *s, int err_no) } set_req_state_err(s, err_no); dump_errno(s); - end_header(s); + end_header(s, op); rgw_flush_formatter_and_reset(s, s->formatter); perfcounter->inc(l_rgw_failed_req); } @@ -644,7 +662,7 @@ void RGWRESTFlusher::do_start(int ret) set_req_state_err(s, ret); /* no going back from here */ dump_errno(s); dump_start(s); - end_header(s); + end_header(s, op); rgw_flush_formatter_and_reset(s, s->formatter); } @@ -927,7 +945,7 @@ void RGWRESTOp::send_response() if (!flusher.did_start()) { set_req_state_err(s, http_ret); dump_errno(s); - end_header(s); + end_header(s, this); } flusher.flush(); } @@ -1062,7 +1080,7 @@ int RGWHandler_ObjStore::read_permissions(RGWOp *op_obj) case OP_COPY: // op itself will read and verify the permissions return 0; case OP_OPTIONS: - only_bucket = false; + only_bucket = true; break; default: return -EINVAL; diff --git a/src/rgw/rgw_rest.h b/src/rgw/rgw_rest.h index b65efb3de3e..15ac863aa52 100644 --- a/src/rgw/rgw_rest.h +++ b/src/rgw/rgw_rest.h @@ -33,15 +33,17 @@ public: class RGWRESTFlusher : public RGWFormatterFlusher { struct req_state *s; + RGWOp *op; protected: virtual void do_flush(); virtual void do_start(int ret); public: - RGWRESTFlusher(struct req_state *_s) : RGWFormatterFlusher(_s->formatter), s(_s) {} - RGWRESTFlusher() : RGWFormatterFlusher(NULL), s(NULL) {} + RGWRESTFlusher(struct req_state *_s, RGWOp *_op) : RGWFormatterFlusher(_s->formatter), s(_s), op(_op) {} + RGWRESTFlusher() : RGWFormatterFlusher(NULL), s(NULL), op(NULL) {} - void init(struct req_state *_s) { + void init(struct req_state *_s, RGWOp *_op) { s = _s; + op = _op; set_formatter(s->formatter); } }; @@ -228,7 +230,7 @@ public: RGWRESTOp() : http_ret(0) {} virtual void init(RGWRados *store, struct req_state *s, RGWHandler *dialect_handler) { RGWOp::init(store, s, dialect_handler); - flusher.init(s); + flusher.init(s, this); } virtual void send_response(); virtual int check_caps(RGWUserCaps& caps) { return -EPERM; } /* should to be implemented! */ @@ -310,7 +312,7 @@ public: extern void set_req_state_err(struct req_state *s, int err_no); extern void dump_errno(struct req_state *s); extern void dump_errno(struct req_state *s, int ret); -extern void end_header(struct req_state *s, const char *content_type = NULL); +extern void end_header(struct req_state *s, RGWOp *op = NULL, const char *content_type = NULL); extern void dump_start(struct req_state *s); extern void list_all_buckets_start(struct req_state *s); extern void dump_owner(struct req_state *s, string& id, string& name, const char *section = NULL); @@ -318,7 +320,7 @@ extern void dump_content_length(struct req_state *s, uint64_t len); extern void dump_etag(struct req_state *s, const char *etag); extern void dump_epoch_header(struct req_state *s, const char *name, time_t t); extern void dump_last_modified(struct req_state *s, time_t t); -extern void abort_early(struct req_state *s, int err); +extern void abort_early(struct req_state *s, RGWOp *op, int err); extern void dump_range(struct req_state *s, uint64_t ofs, uint64_t end, uint64_t total_size); extern void dump_continue(struct req_state *s); extern void list_all_buckets_end(struct req_state *s); @@ -331,6 +333,7 @@ extern void dump_pair(struct req_state *s, const char *key, const char *value); extern bool is_valid_url(const char *url); extern void dump_access_control(struct req_state *s, const char *origin, const char *meth, const char *hdr, const char *exp_hdr, uint32_t max_age); +extern void dump_access_control(req_state *s, RGWOp *op); #endif diff --git a/src/rgw/rgw_rest_s3.cc b/src/rgw/rgw_rest_s3.cc index 71bb418c53c..a9a391fc348 100644 --- a/src/rgw/rgw_rest_s3.cc +++ b/src/rgw/rgw_rest_s3.cc @@ -166,7 +166,8 @@ done: if (!content_type) content_type = "binary/octet-stream"; - end_header(s, content_type); + + end_header(s, this, content_type); if (metadata_bl.length()) { s->cio->write(metadata_bl.c_str(), metadata_bl.length()); @@ -189,7 +190,7 @@ void RGWListBuckets_ObjStore_S3::send_response_begin(bool has_buckets) set_req_state_err(s, ret); dump_errno(s); dump_start(s); - end_header(s, "application/xml"); + end_header(s, NULL, "application/xml"); if (!ret) { list_all_buckets_start(s); @@ -242,7 +243,7 @@ void RGWListBucket_ObjStore_S3::send_response() set_req_state_err(s, ret); dump_errno(s); - end_header(s, "application/xml"); + end_header(s, this, "application/xml"); dump_start(s); if (ret < 0) return; @@ -288,7 +289,7 @@ void RGWListBucket_ObjStore_S3::send_response() void RGWGetBucketLogging_ObjStore_S3::send_response() { dump_errno(s); - end_header(s, "application/xml"); + end_header(s, this, "application/xml"); dump_start(s); s->formatter->open_object_section_in_ns("BucketLoggingStatus", @@ -315,7 +316,7 @@ void RGWStatBucket_ObjStore_S3::send_response() set_req_state_err(s, ret); dump_errno(s); - end_header(s); + end_header(s, this); dump_start(s); } @@ -467,7 +468,7 @@ void RGWDeleteBucket_ObjStore_S3::send_response() set_req_state_err(s, r); dump_errno(s); - end_header(s); + end_header(s, this); if (s->system_request) { JSONFormatter f; /* use json formatter for system requests output */ @@ -521,7 +522,7 @@ void RGWPutObj_ObjStore_S3::send_response() dump_epoch_header(s, "Rgwx-Mtime", mtime); } dump_errno(s); - end_header(s); + end_header(s, this); } /* @@ -1206,7 +1207,7 @@ done: set_req_state_err(s, ret); dump_errno(s); dump_content_length(s, s->formatter->get_len()); - end_header(s); + end_header(s, this); if (ret != STATUS_CREATED) return; @@ -1224,7 +1225,7 @@ void RGWDeleteObj_ObjStore_S3::send_response() set_req_state_err(s, r); dump_errno(s); - end_header(s); + end_header(s, this); } int RGWCopyObj_ObjStore_S3::init_dest_policy() @@ -1308,7 +1309,7 @@ void RGWCopyObj_ObjStore_S3::send_partial_response(off_t ofs) set_req_state_err(s, ret); dump_errno(s); - end_header(s, "binary/octet-stream"); + end_header(s, this, "binary/octet-stream"); if (ret == 0) { s->formatter->open_object_section("CopyObjectResult"); } @@ -1347,7 +1348,7 @@ void RGWGetACLs_ObjStore_S3::send_response() if (ret) set_req_state_err(s, ret); dump_errno(s); - end_header(s, "application/xml"); + end_header(s, this, "application/xml"); dump_start(s); s->cio->write(acls.c_str(), acls.size()); } @@ -1376,7 +1377,7 @@ void RGWPutACLs_ObjStore_S3::send_response() if (ret) set_req_state_err(s, ret); dump_errno(s); - end_header(s, "application/xml"); + end_header(s, this, "application/xml"); dump_start(s); } @@ -1389,7 +1390,7 @@ void RGWGetCORS_ObjStore_S3::send_response() set_req_state_err(s, ret); } dump_errno(s); - end_header(s, "application/xml"); + end_header(s, NULL, "application/xml"); dump_start(s); if (!ret) { string cors; @@ -1464,7 +1465,7 @@ void RGWPutCORS_ObjStore_S3::send_response() if (ret) set_req_state_err(s, ret); dump_errno(s); - end_header(s, "application/xml"); + end_header(s, NULL, "application/xml"); dump_start(s); } @@ -1476,7 +1477,7 @@ void RGWDeleteCORS_ObjStore_S3::send_response() set_req_state_err(s, r); dump_errno(s); - end_header(s); + end_header(s, NULL); } void RGWOptionsCORS_ObjStore_S3::send_response() @@ -1485,22 +1486,20 @@ void RGWOptionsCORS_ObjStore_S3::send_response() uint32_t max_age = CORS_MAX_AGE_INVALID; /*EACCES means, there is no CORS registered yet for the bucket *ENOENT means, there is no match of the Origin in the list of CORSRule - *ENOTSUPP means, the HTTP_METHOD is not supported */ if (ret == -ENOENT) ret = -EACCES; - if (ret != -EACCES) { - get_response_params(hdrs, exp_hdrs, &max_age); - } else { + if (ret < 0) { set_req_state_err(s, ret); dump_errno(s); - end_header(s); + end_header(s, NULL); return; } + get_response_params(hdrs, exp_hdrs, &max_age); dump_errno(s); dump_access_control(s, origin, req_meth, hdrs.c_str(), exp_hdrs.c_str(), max_age); - end_header(s); + end_header(s, NULL); } int RGWInitMultipart_ObjStore_S3::get_params() @@ -1520,7 +1519,7 @@ void RGWInitMultipart_ObjStore_S3::send_response() if (ret) set_req_state_err(s, ret); dump_errno(s); - end_header(s, "application/xml"); + end_header(s, this, "application/xml"); if (ret == 0) { dump_start(s); s->formatter->open_object_section_in_ns("InitiateMultipartUploadResult", @@ -1538,7 +1537,7 @@ void RGWCompleteMultipart_ObjStore_S3::send_response() if (ret) set_req_state_err(s, ret); dump_errno(s); - end_header(s, "application/xml"); + end_header(s, this, "application/xml"); if (ret == 0) { dump_start(s); s->formatter->open_object_section_in_ns("CompleteMultipartUploadResult", @@ -1561,7 +1560,7 @@ void RGWAbortMultipart_ObjStore_S3::send_response() set_req_state_err(s, r); dump_errno(s); - end_header(s); + end_header(s, this); } void RGWListMultipart_ObjStore_S3::send_response() @@ -1569,7 +1568,7 @@ void RGWListMultipart_ObjStore_S3::send_response() if (ret) set_req_state_err(s, ret); dump_errno(s); - end_header(s, "application/xml"); + end_header(s, this, "application/xml"); if (ret == 0) { dump_start(s); @@ -1624,7 +1623,7 @@ void RGWListBucketMultiparts_ObjStore_S3::send_response() set_req_state_err(s, ret); dump_errno(s); - end_header(s, "application/xml"); + end_header(s, this, "application/xml"); dump_start(s); if (ret < 0) return; @@ -1695,7 +1694,7 @@ void RGWDeleteMultiObj_ObjStore_S3::begin_response() } dump_start(s); - end_header(s, "application/xml"); + end_header(s, this, "application/xml"); s->formatter->open_object_section_in_ns("DeleteResult", "http://s3.amazonaws.com/doc/2006-03-01/"); diff --git a/src/rgw/rgw_rest_swift.cc b/src/rgw/rgw_rest_swift.cc index b4f830830f9..651c4635d37 100644 --- a/src/rgw/rgw_rest_swift.cc +++ b/src/rgw/rgw_rest_swift.cc @@ -52,7 +52,7 @@ void RGWListBuckets_ObjStore_SWIFT::send_response_begin(bool has_buckets) set_req_state_err(s, ret); } dump_errno(s); - end_header(s); + end_header(s, NULL); if (!ret) { dump_start(s); @@ -211,7 +211,7 @@ next: set_req_state_err(s, ret); dump_errno(s); - end_header(s); + end_header(s, this); if (ret < 0) { return; } @@ -266,7 +266,7 @@ void RGWStatAccount_ObjStore_SWIFT::send_response() set_req_state_err(s, ret); dump_errno(s); - end_header(s); + end_header(s, NULL); dump_start(s); } @@ -280,7 +280,7 @@ void RGWStatBucket_ObjStore_SWIFT::send_response() set_req_state_err(s, ret); dump_errno(s); - end_header(s); + end_header(s, this); dump_start(s); } @@ -301,7 +301,7 @@ void RGWCreateBucket_ObjStore_SWIFT::send_response() ret = STATUS_ACCEPTED; set_req_state_err(s, ret); dump_errno(s); - end_header(s); + end_header(s, NULL); rgw_flush_formatter_and_reset(s, s->formatter); } @@ -313,7 +313,7 @@ void RGWDeleteBucket_ObjStore_SWIFT::send_response() set_req_state_err(s, r); dump_errno(s); - end_header(s); + end_header(s, this); rgw_flush_formatter_and_reset(s, s->formatter); } @@ -361,7 +361,7 @@ void RGWPutObj_ObjStore_SWIFT::send_response() dump_etag(s, etag.c_str()); set_req_state_err(s, ret); dump_errno(s); - end_header(s); + end_header(s, this); rgw_flush_formatter_and_reset(s, s->formatter); } @@ -421,7 +421,7 @@ void RGWPutMetadata_ObjStore_SWIFT::send_response() ret = STATUS_ACCEPTED; set_req_state_err(s, ret); dump_errno(s); - end_header(s); + end_header(s, this); rgw_flush_formatter_and_reset(s, s->formatter); } @@ -433,7 +433,7 @@ void RGWDeleteObj_ObjStore_SWIFT::send_response() set_req_state_err(s, r); dump_errno(s); - end_header(s); + end_header(s, this); rgw_flush_formatter_and_reset(s, s->formatter); } @@ -484,7 +484,7 @@ void RGWCopyObj_ObjStore_SWIFT::send_partial_response(off_t ofs) ret = STATUS_CREATED; set_req_state_err(s, ret); dump_errno(s); - end_header(s); + end_header(s, this); /* Send progress information. Note that this diverge from the original swift * spec. We do this in order to keep connection alive. @@ -506,7 +506,7 @@ void RGWCopyObj_ObjStore_SWIFT::send_response() ret = STATUS_CREATED; set_req_state_err(s, ret); dump_errno(s); - end_header(s); + end_header(s, this); } else { s->formatter->close_section(); rgw_flush_formatter(s, s->formatter); @@ -570,7 +570,7 @@ int RGWGetObj_ObjStore_SWIFT::send_response_data(bufferlist& bl, off_t bl_ofs, o if (!content_type) content_type = "binary/octet-stream"; - end_header(s, content_type); + end_header(s, this, content_type); sent_header = true; @@ -600,12 +600,12 @@ void RGWOptionsCORS_ObjStore_SWIFT::send_response() } else { set_req_state_err(s, ret); dump_errno(s); - end_header(s); + end_header(s, NULL); return; } dump_errno(s); dump_access_control(s, origin, req_meth, hdrs.c_str(), exp_hdrs.c_str(), max_age); - end_header(s); + end_header(s, NULL); } RGWOp *RGWHandler_ObjStore_Service_SWIFT::op_get() |