From d1735a4e8ea2056d333a5001a7a410fc03fe1b9e Mon Sep 17 00:00:00 2001 From: Radoslaw Zarzynski Date: Thu, 6 Aug 2015 15:52:58 +0200 Subject: [PATCH] rgw: rework X-Trans-Id header to be conform with Swift API. Fixes: #12108 Signed-off-by: Radoslaw Zarzynski --- src/rgw/rgw_common.cc | 12 ------------ src/rgw/rgw_common.h | 2 -- src/rgw/rgw_main.cc | 5 ++--- src/rgw/rgw_rados.cc | 2 ++ src/rgw/rgw_rados.h | 29 +++++++++++++++++++++++++++++ src/rgw/rgw_rest.cc | 2 +- 6 files changed, 34 insertions(+), 18 deletions(-) diff --git a/src/rgw/rgw_common.cc b/src/rgw/rgw_common.cc index 57bedc3ef52fe..682f7fb467634 100644 --- a/src/rgw/rgw_common.cc +++ b/src/rgw/rgw_common.cc @@ -184,18 +184,6 @@ req_state::~req_state() { delete object_acl; } -void req_state::gen_trans_id() -{ - char buf[256]; - timeval timetest; - gettimeofday(&timetest, NULL); - if (strftime(buf, sizeof(buf), "%Y%m%d:%H%M%S",gmtime(&(timetest.tv_sec))) == 0) - return; - - snprintf(buf + strlen(buf), sizeof(buf)-strlen(buf) ,":%03ld", timetest.tv_usec/1000); - trans_id = req_id + "-" + buf; -} - struct str_len { const char *str; int len; diff --git a/src/rgw/rgw_common.h b/src/rgw/rgw_common.h index 34c5c12110094..9582c8c23c206 100644 --- a/src/rgw/rgw_common.h +++ b/src/rgw/rgw_common.h @@ -1071,8 +1071,6 @@ struct req_state { req_state(CephContext *_cct, class RGWEnv *e); ~req_state(); - - void gen_trans_id(); }; /** Store basic data on an object */ diff --git a/src/rgw/rgw_main.cc b/src/rgw/rgw_main.cc index bbf2ed6e6d488..860300c94b876 100644 --- a/src/rgw/rgw_main.cc +++ b/src/rgw/rgw_main.cc @@ -556,10 +556,9 @@ static int process_request(RGWRados *store, RGWREST *rest, RGWRequest *req, RGWC s->obj_ctx = &rados_ctx; s->req_id = store->unique_id(req->id); + s->trans_id = store->unique_trans_id(req->id); - s->gen_trans_id(); - - req->log(s, "initializing"); + req->log_format(s, "initializing for trans_id = %s", s->trans_id.c_str()); RGWOp *op = NULL; int init_error = 0; diff --git a/src/rgw/rgw_rados.cc b/src/rgw/rgw_rados.cc index b5c359fa941e1..1bbf6a169ea3d 100644 --- a/src/rgw/rgw_rados.cc +++ b/src/rgw/rgw_rados.cc @@ -1546,6 +1546,8 @@ int RGWRados::init_complete() if (ret < 0) return ret; + init_unique_trans_id_deps(); + ret = region_map.read(cct, this); if (ret < 0) { if (ret != -ENOENT) { diff --git a/src/rgw/rgw_rados.h b/src/rgw/rgw_rados.h index 25caf2ca12342..a4a2efff6b153 100644 --- a/src/rgw/rgw_rados.h +++ b/src/rgw/rgw_rados.h @@ -1250,6 +1250,7 @@ protected: string region_name; string zone_name; + string trans_id_suffix; RGWQuotaHandler *quota_handler; @@ -2110,6 +2111,34 @@ public: return s; } + void init_unique_trans_id_deps() { + char buf[16 + 2 + 1]; /* uint64_t needs 16, 2 hyphens add further 2 */ + + snprintf(buf, sizeof(buf), "-%llx-", (unsigned long long)instance_id()); + url_encode(string(buf) + zone.name, trans_id_suffix); + } + + /* In order to preserve compability with Swift API, transaction ID + * should contain at least 32 characters satisfying following spec: + * - first 21 chars must be in range [0-9a-f]. Swift uses this + * space for storing fragment of UUID obtained through a call to + * uuid4() function of Python's uuid module; + * - char no. 22 must be a hyphen; + * - at least 10 next characters constitute hex-formatted timestamp + * padded with zeroes if necessary. All bytes must be in [0-9a-f] + * range; + * - last, optional part of transaction ID is any url-encoded string + * without restriction on length. */ + string unique_trans_id(const uint64_t unique_num) { + char buf[41]; /* 2 + 21 + 1 + 16 (timestamp can consume up to 16) + 1 */ + time_t timestamp = time(NULL); + + snprintf(buf, sizeof(buf), "tx%021llx-%010llx", + (unsigned long long)unique_num, + (unsigned long long)timestamp); + + return string(buf) + trans_id_suffix; + } void get_log_pool_name(string& name) { name = zone.log_pool.name; diff --git a/src/rgw/rgw_rest.cc b/src/rgw/rgw_rest.cc index a03e31fabf2ec..e47fc7a091d92 100644 --- a/src/rgw/rgw_rest.cc +++ b/src/rgw/rgw_rest.cc @@ -497,7 +497,7 @@ void dump_start(struct req_state *s) void dump_trans_id(req_state *s) { if (s->prot_flags & RGW_REST_SWIFT) { - s->cio->print("X-Trans-Id: ts-%s\r\n", s->trans_id.c_str()); + s->cio->print("X-Trans-Id: %s\r\n", s->trans_id.c_str()); } else { s->cio->print("x-amz-request-id: %s\r\n", s->trans_id.c_str()); -- 2.39.5