diff options
author | Yehuda Sadeh <yehuda@inktank.com> | 2013-08-22 13:38:55 -0700 |
---|---|---|
committer | Yehuda Sadeh <yehuda@inktank.com> | 2013-09-04 16:03:22 -0700 |
commit | 27f39178d37cc796d88021a4933cf6d5dc28f1ac (patch) | |
tree | 4d0bd183e4b9d4f67c6b616d8f985afaed5874f8 | |
parent | 86181f3d38de6f1bfd920e504b8344922ddea116 (diff) | |
download | ceph-27f39178d37cc796d88021a4933cf6d5dc28f1ac.tar.gz |
rgw: tie CORS header response to all relevant operations
Have the CORS responses on all relevant operations. Also add headers
on failure cases.
Signed-off-by: Yehuda Sadeh <yehuda@inktank.com>
-rw-r--r-- | src/rgw/rgw_main.cc | 16 | ||||
-rw-r--r-- | src/rgw/rgw_rest.cc | 14 | ||||
-rw-r--r-- | src/rgw/rgw_rest.h | 14 | ||||
-rw-r--r-- | src/rgw/rgw_rest_s3.cc | 47 | ||||
-rw-r--r-- | src/rgw/rgw_rest_swift.cc | 28 |
5 files changed, 62 insertions, 57 deletions
diff --git a/src/rgw/rgw_main.cc b/src/rgw/rgw_main.cc index e10d4d0aeed..c97764c4ca1 100644 --- a/src/rgw/rgw_main.cc +++ b/src/rgw/rgw_main.cc @@ -311,7 +311,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; } @@ -320,7 +320,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; @@ -329,26 +329,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; } @@ -358,7 +358,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; } } @@ -366,7 +366,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_rest.cc b/src/rgw/rgw_rest.cc index 2e3125034cb..058fbc6416c 100644 --- a/src/rgw/rgw_rest.cc +++ b/src/rgw/rgw_rest.cc @@ -400,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: @@ -438,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; @@ -446,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); } @@ -658,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); } @@ -941,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(); } diff --git a/src/rgw/rgw_rest.h b/src/rgw/rgw_rest.h index 12fcf783687..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); diff --git a/src/rgw/rgw_rest_s3.cc b/src/rgw/rgw_rest_s3.cc index 4f1959faab5..c44eba5853c 100644 --- a/src/rgw/rgw_rest_s3.cc +++ b/src/rgw/rgw_rest_s3.cc @@ -167,8 +167,7 @@ done: if (!content_type) content_type = "binary/octet-stream"; - dump_access_control(s, this); - 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()); @@ -191,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); @@ -244,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; @@ -290,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", @@ -317,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); } @@ -469,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 */ @@ -523,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); } /* @@ -1208,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; @@ -1226,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() @@ -1310,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"); } @@ -1349,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()); } @@ -1378,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); } @@ -1391,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; @@ -1466,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); } @@ -1478,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() @@ -1496,13 +1495,13 @@ void RGWOptionsCORS_ObjStore_S3::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); } int RGWInitMultipart_ObjStore_S3::get_params() @@ -1522,7 +1521,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", @@ -1540,7 +1539,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", @@ -1563,7 +1562,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() @@ -1571,7 +1570,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); @@ -1626,7 +1625,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; @@ -1697,7 +1696,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() |