From: Radoslaw Zarzynski Date: Thu, 6 Aug 2015 13:52:58 +0000 (+0200) Subject: rgw: rework X-Trans-Id header to be conform with Swift API. X-Git-Tag: v0.94.4~52^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=refs%2Fpull%2F5721%2Fhead;p=ceph.git rgw: rework X-Trans-Id header to be conform with Swift API. Fixes: #12108 Signed-off-by: Radoslaw Zarzynski (cherry picked from commit d1735a4e8ea2056d333a5001a7a410fc03fe1b9e) --- diff --git a/src/rgw/rgw_common.cc b/src/rgw/rgw_common.cc index f5b9a9b246158..f3988cffd3486 100644 --- a/src/rgw/rgw_common.cc +++ b/src/rgw/rgw_common.cc @@ -169,18 +169,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 0f46b63f9fdff..87d2cc33e8161 100644 --- a/src/rgw/rgw_common.h +++ b/src/rgw/rgw_common.h @@ -1063,8 +1063,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 10a672a4b4b15..af892c4058c29 100644 --- a/src/rgw/rgw_main.cc +++ b/src/rgw/rgw_main.cc @@ -555,10 +555,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 6717c54b74216..85791eabd6c94 100644 --- a/src/rgw/rgw_rados.cc +++ b/src/rgw/rgw_rados.cc @@ -1520,6 +1520,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 18213cf3a5499..cc2d1dd397112 100644 --- a/src/rgw/rgw_rados.h +++ b/src/rgw/rgw_rados.h @@ -1244,6 +1244,7 @@ protected: string region_name; string zone_name; + string trans_id_suffix; RGWQuotaHandler *quota_handler; @@ -2063,6 +2064,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 b59d6866a43fd..5f4c40043118e 100644 --- a/src/rgw/rgw_rest.cc +++ b/src/rgw/rgw_rest.cc @@ -495,7 +495,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());