summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYehuda Sadeh <yehuda@inktank.com>2013-08-22 13:38:55 -0700
committerYehuda Sadeh <yehuda@inktank.com>2013-09-11 09:45:14 -0700
commit71873aba6553492d3ad71596cefd7c841030a277 (patch)
tree84743d347b7364f533efef38eee6c937af82060d
parent94e7b594d85dbd26e58d823b41f418032e9f163f (diff)
downloadceph-71873aba6553492d3ad71596cefd7c841030a277.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.cc16
-rw-r--r--src/rgw/rgw_rest.cc14
-rw-r--r--src/rgw/rgw_rest.h14
-rw-r--r--src/rgw/rgw_rest_s3.cc47
-rw-r--r--src/rgw/rgw_rest_swift.cc28
5 files changed, 62 insertions, 57 deletions
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_rest.cc b/src/rgw/rgw_rest.cc
index 87aead0b250..196bd29e99b 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 9e27c37e448..9e95dd95542 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);
}
/*
@@ -1213,7 +1212,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;
@@ -1231,7 +1230,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()
@@ -1315,7 +1314,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");
}
@@ -1354,7 +1353,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());
}
@@ -1383,7 +1382,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);
}
@@ -1396,7 +1395,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;
@@ -1471,7 +1470,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);
}
@@ -1483,7 +1482,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()
@@ -1501,13 +1500,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()
@@ -1527,7 +1526,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",
@@ -1545,7 +1544,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",
@@ -1568,7 +1567,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()
@@ -1576,7 +1575,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);
@@ -1631,7 +1630,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;
@@ -1702,7 +1701,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()