From: Wido den Hollander Date: Mon, 11 Nov 2013 15:37:40 +0000 (+0100) Subject: 6748: rgw: Optionally return the bucket name in a response header. X-Git-Tag: v0.78~325^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=f97264d4842cd2d28e089e2dd8a409b93bb1a825;p=ceph.git 6748: rgw: Optionally return the bucket name in a response header. 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 --- diff --git a/src/common/config_opts.h b/src/common/config_opts.h index 47e3783de2fc..43ef45c9f763 100644 --- a/src/common/config_opts.h +++ b/src/common/config_opts.h @@ -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 diff --git a/src/rgw/rgw_main.cc b/src/rgw/rgw_main.cc index e3efaf7e9e48..e27efd6f7d61 100644 --- a/src/rgw/rgw_main.cc +++ b/src/rgw/rgw_main.cc @@ -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: diff --git a/src/rgw/rgw_op.cc b/src/rgw/rgw_op.cc index 25c6b339878e..ec17ea334d79 100644 --- a/src/rgw/rgw_op.cc +++ b/src/rgw/rgw_op.cc @@ -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(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 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 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 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; diff --git a/src/rgw/rgw_op.h b/src/rgw/rgw_op.h index ab6f925dbc91..0051bdfc3016 100644 --- a/src/rgw/rgw_op.h +++ b/src/rgw/rgw_op.h @@ -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; diff --git a/src/rgw/rgw_rest.cc b/src/rgw/rgw_rest.cc index ede0c329003e..53282c1c2f8b 100644 --- a/src/rgw/rgw_rest.cc +++ b/src/rgw/rgw_rest.cc @@ -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);