]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
6748: rgw: Optionally return the bucket name in a response header. 915/head
authorWido den Hollander <wido@42on.com>
Mon, 11 Nov 2013 15:37:40 +0000 (16:37 +0100)
committerWido den Hollander <wido@widodh.nl>
Thu, 16 Jan 2014 09:02:50 +0000 (10:02 +0100)
This can be useful in situations where accounting of traffic is done externally
when for example HTTP traffic is cached by a reverse proxy like Varnish.

Since not all traffic reaches the RGW daemon it can't fully account all traffic
and this the caching proxy needs to be aware of which bucket the request came for.

Signed-off-by: Wido den Hollander <wido@42on.com>
src/common/config_opts.h
src/rgw/rgw_main.cc
src/rgw/rgw_op.cc
src/rgw/rgw_op.h
src/rgw/rgw_rest.cc

index 47e3783de2fc03055103860cdb9c367d5501b590..43ef45c9f7639277f9d8b40ad2ac89d6bad4e491 100644 (file)
@@ -753,6 +753,7 @@ OPTION(rgw_replica_log_obj_prefix, OPT_STR, "replica_log") //
 OPTION(rgw_bucket_quota_ttl, OPT_INT, 600) // time for cached bucket stats to be cached within rgw instance
 OPTION(rgw_bucket_quota_soft_threshold, OPT_DOUBLE, 0.95) // threshold from which we don't rely on cached info for quota decisions
 OPTION(rgw_bucket_quota_cache_size, OPT_INT, 10000) // number of entries in bucket quota cache
+OPTION(rgw_expose_bucket, OPT_BOOL, false) // Return the bucket name in the 'Bucket' response header
 
 OPTION(rgw_frontends, OPT_STR, "") // alternative front ends
 
index e3efaf7e9e483268be87413836bd2dfa3bdb6410..e27efd6f7d61ecbc93325d845dcdb4ddf5018989 100644 (file)
@@ -467,10 +467,8 @@ static int process_request(RGWRados *store, RGWREST *rest, RGWRequest *req, RGWC
     goto done;
   }
 
-  if (s->expect_cont)
-    dump_continue(s);
-
   req->log(s, "executing");
+  op->pre_exec();
   op->execute();
   op->complete();
 done:
index 25c6b339878ee0929f2cd15c1bcf40cb37cadd83..ec17ea334d79931f208954672aa98497d3feaf87 100644 (file)
@@ -395,6 +395,14 @@ static int rgw_build_policies(RGWRados *store, struct req_state *s, bool only_bu
   return ret;
 }
 
+static void rgw_bucket_object_pre_exec(struct req_state *s)
+{
+  if (s->expect_cont)
+    dump_continue(s);
+
+  dump_bucket_from_state(s);
+}
+
 int RGWGetObj::verify_permission()
 {
   obj.init(s->bucket, s->object_str);
@@ -786,7 +794,7 @@ class RGWGetObj_CB : public RGWGetDataCB
 public:
   RGWGetObj_CB(RGWGetObj *_op) : op(_op) {}
   virtual ~RGWGetObj_CB() {}
-  
+
   int handle_data(bufferlist& bl, off_t bl_ofs, off_t bl_len) {
     return op->get_data_cb(bl, bl_ofs, bl_len);
   }
@@ -807,6 +815,11 @@ int RGWGetObj::get_data_cb(bufferlist& bl, off_t bl_ofs, off_t bl_len)
   return send_response_data(bl, bl_ofs, bl_len);
 }
 
+void RGWGetObj::pre_exec()
+{
+  rgw_bucket_object_pre_exec(s);
+}
+
 void RGWGetObj::execute()
 {
   void *handle = NULL;
@@ -1000,6 +1013,11 @@ int RGWStatBucket::verify_permission()
   return 0;
 }
 
+void RGWStatBucket::pre_exec()
+{
+  rgw_bucket_object_pre_exec(s);
+}
+
 void RGWStatBucket::execute()
 {
   RGWUserBuckets buckets;
@@ -1047,6 +1065,11 @@ int RGWListBucket::parse_max_keys()
   return 0;
 }
 
+void RGWListBucket::pre_exec()
+{
+  rgw_bucket_object_pre_exec(s);
+}
+
 void RGWListBucket::execute()
 {
   string no_ns;
@@ -1111,6 +1134,11 @@ static int forward_request_to_master(struct req_state *s, obj_version *objv, RGW
   return 0;
 }
 
+void RGWCreateBucket::pre_exec()
+{
+  rgw_bucket_object_pre_exec(s);
+}
+
 void RGWCreateBucket::execute()
 {
   RGWAccessControlPolicy old_policy(s->cct);
@@ -1196,7 +1224,7 @@ void RGWCreateBucket::execute()
    * from a partial create by retrying it. */
   ldout(s->cct, 20) << "rgw_create_bucket returned ret=" << ret << " bucket=" << s->bucket << dendl;
 
-  if (ret && ret != -EEXIST)   
+  if (ret && ret != -EEXIST)
     return;
 
   existed = (ret == -EEXIST);
@@ -1234,6 +1262,11 @@ int RGWDeleteBucket::verify_permission()
   return 0;
 }
 
+void RGWDeleteBucket::pre_exec()
+{
+  rgw_bucket_object_pre_exec(s);
+}
+
 void RGWDeleteBucket::execute()
 {
   ret = -EINVAL;
@@ -1392,6 +1425,11 @@ void RGWPutObj::dispose_processor(RGWPutObjProcessor *processor)
   delete processor;
 }
 
+void RGWPutObj::pre_exec()
+{
+  rgw_bucket_object_pre_exec(s);
+}
+
 void RGWPutObj::execute()
 {
   RGWPutObjProcessor *processor = NULL;
@@ -1548,6 +1586,11 @@ void RGWPostObj::dispose_processor(RGWPutObjProcessor *processor)
   delete processor;
 }
 
+void RGWPostObj::pre_exec()
+{
+  rgw_bucket_object_pre_exec(s);
+}
+
 void RGWPostObj::execute()
 {
   RGWPutObjProcessor *processor = NULL;
@@ -1557,7 +1600,7 @@ void RGWPostObj::execute()
   bufferlist bl, aclbl;
   int len = 0;
 
-  // read in the data from the POST form 
+  // read in the data from the POST form
   ret = get_params();
   if (ret < 0)
     goto done;
@@ -1648,6 +1691,11 @@ int RGWPutMetadata::verify_permission()
   return 0;
 }
 
+void RGWPutMetadata::pre_exec()
+{
+  rgw_bucket_object_pre_exec(s);
+}
+
 void RGWPutMetadata::execute()
 {
   const char *meta_prefix = RGW_ATTR_META_PREFIX;
@@ -1714,6 +1762,11 @@ int RGWDeleteObj::verify_permission()
   return 0;
 }
 
+void RGWDeleteObj::pre_exec()
+{
+  rgw_bucket_object_pre_exec(s);
+}
+
 void RGWDeleteObj::execute()
 {
   ret = -EINVAL;
@@ -1866,6 +1919,11 @@ void RGWCopyObj::progress_cb(off_t ofs)
   last_ofs = ofs;
 }
 
+void RGWCopyObj::pre_exec()
+{
+  rgw_bucket_object_pre_exec(s);
+}
+
 void RGWCopyObj::execute()
 {
   rgw_obj src_obj, dst_obj;
@@ -1916,13 +1974,18 @@ int RGWGetACLs::verify_permission()
   return 0;
 }
 
+void RGWGetACLs::pre_exec()
+{
+  rgw_bucket_object_pre_exec(s);
+}
+
 void RGWGetACLs::execute()
 {
   stringstream ss;
   RGWAccessControlPolicy *acl = (s->object ? s->object_acl : s->bucket_acl);
   RGWAccessControlPolicy_S3 *s3policy = static_cast<RGWAccessControlPolicy_S3 *>(acl);
   s3policy->to_xml(ss);
-  acls = ss.str(); 
+  acls = ss.str();
 }
 
 
@@ -1941,6 +2004,11 @@ int RGWPutACLs::verify_permission()
   return 0;
 }
 
+void RGWPutACLs::pre_exec()
+{
+  rgw_bucket_object_pre_exec(s);
+}
+
 void RGWPutACLs::execute()
 {
   bufferlist bl;
@@ -2140,7 +2208,7 @@ void RGWOptionsCORS::execute()
 
   origin = s->info.env->get("HTTP_ORIGIN");
   if (!origin) {
-    dout(0) << 
+    dout(0) <<
     "Preflight request without mandatory Origin header"
     << dendl;
     ret = -EINVAL;
@@ -2148,7 +2216,7 @@ void RGWOptionsCORS::execute()
   }
   req_meth = s->info.env->get("HTTP_ACCESS_CONTROL_REQUEST_METHOD");
   if (!req_meth) {
-    dout(0) << 
+    dout(0) <<
     "Preflight request without mandatory Access-control-request-method header"
     << dendl;
     ret = -EINVAL;
@@ -2176,6 +2244,11 @@ int RGWInitMultipart::verify_permission()
   return 0;
 }
 
+void RGWInitMultipart::pre_exec()
+{
+  rgw_bucket_object_pre_exec(s);
+}
+
 void RGWInitMultipart::execute()
 {
   bufferlist aclbl;
@@ -2273,6 +2346,11 @@ int RGWCompleteMultipart::verify_permission()
   return 0;
 }
 
+void RGWCompleteMultipart::pre_exec()
+{
+  rgw_bucket_object_pre_exec(s);
+}
+
 void RGWCompleteMultipart::execute()
 {
   RGWMultiCompleteUpload *parts;
@@ -2370,7 +2448,7 @@ void RGWCompleteMultipart::execute()
   target_obj.init(s->bucket, s->object_str);
 
   list<string> remove_objs; /* objects to be removed from index listing */
-  
+
   for (obj_iter = obj_parts.begin(); obj_iter != obj_parts.end(); ++obj_iter) {
     RGWUploadPartInfo& obj_part = obj_iter->second;
     string oid = mp.get_part(obj_iter->second.num);
@@ -2422,6 +2500,11 @@ int RGWAbortMultipart::verify_permission()
   return 0;
 }
 
+void RGWAbortMultipart::pre_exec()
+{
+  rgw_bucket_object_pre_exec(s);
+}
+
 void RGWAbortMultipart::execute()
 {
   ret = -EINVAL;
@@ -2438,7 +2521,7 @@ void RGWAbortMultipart::execute()
   if (upload_id.empty() || s->object_str.empty())
     return;
 
-  mp.init(s->object_str, upload_id); 
+  mp.init(s->object_str, upload_id);
   meta_oid = mp.get_meta();
 
   ret = get_multiparts_info(store, s, meta_oid, obj_parts, policy, attrs);
@@ -2482,6 +2565,11 @@ int RGWListMultipart::verify_permission()
   return 0;
 }
 
+void RGWListMultipart::pre_exec()
+{
+  rgw_bucket_object_pre_exec(s);
+}
+
 void RGWListMultipart::execute()
 {
   map<string, bufferlist> xattrs;
@@ -2506,6 +2594,11 @@ int RGWListBucketMultiparts::verify_permission()
   return 0;
 }
 
+void RGWListBucketMultiparts::pre_exec()
+{
+  rgw_bucket_object_pre_exec(s);
+}
+
 void RGWListBucketMultiparts::execute()
 {
   vector<RGWObjEnt> objs;
@@ -2552,6 +2645,11 @@ int RGWDeleteMultiObj::verify_permission()
   return 0;
 }
 
+void RGWDeleteMultiObj::pre_exec()
+{
+  rgw_bucket_object_pre_exec(s);
+}
+
 void RGWDeleteMultiObj::execute()
 {
   RGWMultiDelDelete *multi_delete;
index ab6f925dbc919b2623e93f1aebdecfea115fd68c..0051bdfc3016f932d9d7a237623ffbfbf024d958 100644 (file)
@@ -64,6 +64,7 @@ public:
   virtual bool prefetch_data() { return false; }
   virtual int verify_permission() = 0;
   virtual int verify_op_mask();
+  virtual void pre_exec() {}
   virtual void execute() = 0;
   virtual void send_response() {}
   virtual void complete() {
@@ -125,6 +126,7 @@ public:
     this->get_data = get_data;
   }
   int verify_permission();
+  void pre_exec();
   void execute();
   int read_user_manifest_part(rgw_bucket& bucket, RGWObjEnt& ent, RGWAccessControlPolicy *bucket_policy, off_t start_ofs, off_t end_ofs);
   int iterate_user_manifest_parts(rgw_bucket& bucket, string& obj_prefix, RGWAccessControlPolicy *bucket_policy,
@@ -219,6 +221,7 @@ public:
     is_truncated = false;
   }
   int verify_permission();
+  void pre_exec();
   void execute();
 
   virtual int get_params() = 0;
@@ -248,6 +251,7 @@ public:
   ~RGWStatBucket() {}
 
   int verify_permission();
+  void pre_exec();
   void execute();
 
   virtual void send_response() = 0;
@@ -270,6 +274,7 @@ public:
   RGWCreateBucket() : ret(0) {}
 
   int verify_permission();
+  void pre_exec();
   void execute();
   virtual void init(RGWRados *store, struct req_state *s, RGWHandler *h) {
     RGWOp::init(store, s, h);
@@ -291,6 +296,7 @@ public:
   RGWDeleteBucket() : ret(0) {}
 
   int verify_permission();
+  void pre_exec();
   void execute();
 
   virtual void send_response() = 0;
@@ -333,6 +339,7 @@ public:
   void dispose_processor(RGWPutObjProcessor *processor);
 
   int verify_permission();
+  void pre_exec();
   void execute();
 
   virtual int get_params() = 0;
@@ -372,6 +379,7 @@ public:
   }
 
   int verify_permission();
+  void pre_exec();
   void execute();
 
   RGWPutObjProcessor *select_processor();
@@ -404,6 +412,7 @@ public:
     policy.set_ctx(s->cct);
   }
   int verify_permission();
+  void pre_exec();
   void execute();
 
   virtual int get_params() = 0;
@@ -420,6 +429,7 @@ public:
   RGWDeleteObj() : ret(0) {}
 
   int verify_permission();
+  void pre_exec();
   void execute();
 
   virtual void send_response() = 0;
@@ -488,6 +498,7 @@ public:
     dest_policy.set_ctx(s->cct);
   }
   int verify_permission();
+  void pre_exec();
   void execute();
   void progress_cb(off_t ofs);
 
@@ -508,6 +519,7 @@ public:
   RGWGetACLs() : ret(0) {}
 
   int verify_permission();
+  void pre_exec();
   void execute();
 
   virtual void send_response() = 0;
@@ -532,6 +544,7 @@ public:
   }
 
   int verify_permission();
+  void pre_exec();
   void execute();
 
   virtual int get_policy_from_state(RGWRados *store, struct req_state *s, stringstream& ss) { return 0; }
@@ -627,6 +640,7 @@ public:
     policy.set_ctx(s->cct);
   }
   int verify_permission();
+  void pre_exec();
   void execute();
 
   virtual int get_params() = 0;
@@ -656,6 +670,7 @@ public:
   }
 
   int verify_permission();
+  void pre_exec();
   void execute();
 
   virtual int get_params() = 0;
@@ -672,6 +687,7 @@ public:
   RGWAbortMultipart() : ret(0) {}
 
   int verify_permission();
+  void pre_exec();
   void execute();
 
   virtual void send_response() = 0;
@@ -700,6 +716,7 @@ public:
     policy = RGWAccessControlPolicy(s->cct);
   }
   int verify_permission();
+  void pre_exec();
   void execute();
 
   virtual int get_params() = 0;
@@ -803,6 +820,7 @@ public:
   }
 
   int verify_permission();
+  void pre_exec();
   void execute();
 
   virtual int get_params() = 0;
@@ -833,6 +851,7 @@ public:
     status_dumped = false;
   }
   int verify_permission();
+  void pre_exec();
   void execute();
 
   virtual int get_params() = 0;
index ede0c329003e70e1c3401c00e115f8c36bb68647..53282c1c2f8b1f19430f8aeb9361e01365c01aab 100644 (file)
@@ -269,8 +269,11 @@ void dump_pair(struct req_state *s, const char *key, const char *value)
 
 void dump_bucket_from_state(struct req_state *s)
 {
-  if (!s->bucket_name_str.empty())
-    s->cio->print("Bucket: \"%s\"\n", s->bucket_name_str.c_str());
+  int expose_bucket = g_conf->rgw_expose_bucket;
+  if (expose_bucket) {
+    if (!s->bucket_name_str.empty())
+      s->cio->print("Bucket: \"%s\"\n", s->bucket_name_str.c_str());
+  }
 }
 
 void dump_object_from_state(struct req_state *s)
@@ -462,6 +465,7 @@ void abort_early(struct req_state *s, RGWOp *op, int err_no)
   }
   set_req_state_err(s, err_no);
   dump_errno(s);
+  dump_bucket_from_state(s);
   end_header(s, op);
   rgw_flush_formatter_and_reset(s, s->formatter);
   perfcounter->inc(l_rgw_failed_req);