]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: tie CORS header response to all relevant operations
authorYehuda Sadeh <yehuda@inktank.com>
Thu, 22 Aug 2013 20:38:55 +0000 (13:38 -0700)
committerYehuda Sadeh <yehuda@inktank.com>
Wed, 11 Sep 2013 16:45:14 +0000 (09:45 -0700)
Have the CORS responses on all relevant operations. Also add headers
on failure cases.

Signed-off-by: Yehuda Sadeh <yehuda@inktank.com>
src/rgw/rgw_main.cc
src/rgw/rgw_rest.cc
src/rgw/rgw_rest.h
src/rgw/rgw_rest_s3.cc
src/rgw/rgw_rest_swift.cc

index 12301ba9c5fc6b3751416bc3be758e1b5de53e90..54db609521cc8fc397a69f22cf0a7676bcb2caae 100644 (file)
@@ -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;
   }
 
index 87aead0b2507a9bf51672da855235d6b2e992630..196bd29e99b27484dae0020265dc007717225a16 100644 (file)
@@ -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();
 }
index 12fcf783687eaa9995e497496adb5c1afc49e7c2..15ac863aa52d99467bb28d4eb59e69c354dd089e 100644 (file)
@@ -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);
index 9e27c37e448865c383a3ddd863de39eb863a7970..9e95dd95542dc2aa84fbc3de9cfcb98dba7d7f18 100644 (file)
@@ -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/");
 
index b4f830830f9ff25e922a8df2683579536910578e..651c4635d3788e1c121c073850e2c1861e605d0b 100644 (file)
@@ -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()