diff options
author | Andrei Zeliankou <zelenkov@nginx.com> | 2023-11-08 17:34:59 +0000 |
---|---|---|
committer | Andrei Zeliankou <zelenkov@nginx.com> | 2023-11-08 17:34:59 +0000 |
commit | a88e857b5b4100bb62be8a73c1badd999561b328 (patch) | |
tree | 652f98a6d9792bcb22b5fe23427f789e7853faf9 | |
parent | 6ae7142840a0f5dd28fb0623dbd88d82d6b29f7a (diff) | |
download | unit-a88e857b5b4100bb62be8a73c1badd999561b328.tar.gz unit-a88e857b5b4100bb62be8a73c1badd999561b328.tar.bz2 |
Var: $request_id variable.
This variable contains a string that is formed using random data and
can be used as a unique request identifier.
This closes #714 issue on GitHub.
-rw-r--r-- | docs/changes.xml | 7 | ||||
-rw-r--r-- | src/nxt_http_variables.c | 32 | ||||
-rw-r--r-- | test/test_variables.py | 20 |
3 files changed, 59 insertions, 0 deletions
diff --git a/docs/changes.xml b/docs/changes.xml index 74cd5db7..2c01a1e0 100644 --- a/docs/changes.xml +++ b/docs/changes.xml @@ -26,6 +26,13 @@ NGINX Unit updated to 1.32.0. </para> </change> +<change type="feature"> +<para> +$request_id variable contains a string that is formed using random data and +can be used as a unique request identifier. +</para> +</change> + </changes> diff --git a/src/nxt_http_variables.c b/src/nxt_http_variables.c index 46594a6b..ec744317 100644 --- a/src/nxt_http_variables.c +++ b/src/nxt_http_variables.c @@ -28,6 +28,8 @@ static u_char *nxt_http_log_date(u_char *buf, nxt_realtime_t *now, struct tm *tm, size_t size, const char *format); static nxt_int_t nxt_http_var_request_line(nxt_task_t *task, nxt_str_t *str, void *ctx, void *data); +static nxt_int_t nxt_http_var_request_id(nxt_task_t *task, nxt_str_t *str, + void *ctx, void *data); static nxt_int_t nxt_http_var_status(nxt_task_t *task, nxt_str_t *str, void *ctx, void *data); static nxt_int_t nxt_http_var_body_bytes_sent(nxt_task_t *task, nxt_str_t *str, @@ -90,6 +92,10 @@ static nxt_var_decl_t nxt_http_vars[] = { .handler = nxt_http_var_request_line, .cacheable = 1, }, { + .name = nxt_string("request_id"), + .handler = nxt_http_var_request_id, + .cacheable = 1, + }, { .name = nxt_string("status"), .handler = nxt_http_var_status, .cacheable = 1, @@ -396,6 +402,32 @@ nxt_http_var_request_line(nxt_task_t *task, nxt_str_t *str, void *ctx, static nxt_int_t +nxt_http_var_request_id(nxt_task_t *task, nxt_str_t *str, void *ctx, + void *data) +{ + nxt_random_t *rand; + nxt_http_request_t *r; + + r = ctx; + + str->start = nxt_mp_nget(r->mem_pool, 32); + if (nxt_slow_path(str->start == NULL)) { + return NXT_ERROR; + } + + str->length = 32; + + rand = &task->thread->random; + + (void) nxt_sprintf(str->start, str->start + 32, "%08xD%08xD%08xD%08xD", + nxt_random(rand), nxt_random(rand), + nxt_random(rand), nxt_random(rand)); + + return NXT_OK; +} + + +static nxt_int_t nxt_http_var_body_bytes_sent(nxt_task_t *task, nxt_str_t *str, void *ctx, void *data) { diff --git a/test/test_variables.py b/test/test_variables.py index c9b173fa..813bd8c6 100644 --- a/test/test_variables.py +++ b/test/test_variables.py @@ -211,6 +211,26 @@ def test_variables_request_line(search_in_file, wait_for_record): assert wait_for_record(reg, 'access.log') is not None +def test_variables_request_id(search_in_file, wait_for_record, findall): + set_format('$uri $request_id $request_id') + + assert search_in_file(r'/request_id', 'access.log') is None + assert client.get(url='/request_id_1')['status'] == 200 + assert client.get(url='/request_id_2')['status'] == 200 + assert wait_for_record(r'/request_id_2', 'access.log') is not None + + id1 = findall( + r'^\/request_id_1 ([0-9a-f]{32}) ([0-9a-f]{32})$', 'access.log' + )[0] + id2 = findall( + r'^\/request_id_2 ([0-9a-f]{32}) ([0-9a-f]{32})$', 'access.log' + )[0] + + assert id1[0] == id1[1], 'same ids first' + assert id2[0] == id2[1], 'same ids second' + assert id1[0] != id2[0], 'first id != second id' + + def test_variables_status(search_in_file, wait_for_record): set_format('$status') |