From f52a34c17af4543245ff79e3227b9d514b8cfa5c Mon Sep 17 00:00:00 2001 From: Samuele Date: Tue, 14 Nov 2023 16:56:51 +0100 Subject: [PATCH] feat(src): request id (#65 + #70) (#73) * feat(error_log): custom error handler (#65) * Defines a new error log handler and a directive lua_kong_error_log_request_id that enable configuring a Request ID from the value of an nginx variable, to append to the error log. * includes tests for the new directive * tests(*): fix github workflow Co-authored-by: Chrono Co-authored-by: Datong Sun * tests(stream): fix mockbin failing tests * feat(variables): add new variable `$kong_request_id` (#70) Similar to `$request_id`, but from pseudo-random number source instead of OpenSSL's `RAND_bytes` for better performance. KAG-2734 --------- Co-authored-by: Chrono Co-authored-by: Datong Sun --- README.md | 34 ++- config | 4 +- src/ngx_http_lua_kong_common.h | 12 + src/ngx_http_lua_kong_directive.h | 4 + src/ngx_http_lua_kong_log_handler.c | 147 ++++++++++ src/ngx_http_lua_kong_module.c | 48 +++- ...ng_var.c => ngx_http_lua_kong_var_index.c} | 5 +- src/ngx_http_lua_kong_vars.c | 81 ++++++ t/009-error-log-append.t | 259 ++++++++++++++++++ t/010-request-id.t | 41 +++ t/stream/001-upstream-tls.t | 85 +++++- 11 files changed, 704 insertions(+), 16 deletions(-) create mode 100644 src/ngx_http_lua_kong_log_handler.c rename src/{ngx_http_lua_kong_var.c => ngx_http_lua_kong_var_index.c} (98%) create mode 100644 src/ngx_http_lua_kong_vars.c create mode 100644 t/009-error-log-append.t create mode 100644 t/010-request-id.t diff --git a/README.md b/README.md index f50bd4de..a9b1c8ce 100644 --- a/README.md +++ b/README.md @@ -11,8 +11,11 @@ Table of Contents * [Install](#install) * [Directives](#directives) * [lua_kong_load_var_index](#lua_kong_load_var_index) + * [lua\_kong\_error\_log\_request\_id](#lua_kong_error_log_request_id) * [Methods](#methods) * [resty.kong.tls.request\_client\_certificate](#restykongtlsrequest_client_certificate) +* [Variables](#variables) + * [$kong\_request\_id](#kong_request_id) * [resty.kong.tls.disable\_session\_reuse](#restykongtlsdisable_session_reuse) * [resty.kong.tls.get\_full\_client\_certificate\_chain](#restykongtlsget_full_client_certificate_chain) * [resty.kong.tls.set\_upstream\_cert\_and\_key](#restykongtlsset_upstream_cert_and_key) @@ -121,6 +124,25 @@ indexed variable access. [Back to TOC](#table-of-contents) +lua\_kong\_error\_log\_request\_id +------------------------------------------- +**syntax:** *lua_kong_error_log_request_id $variable;* + +**context:** *http* *server* *location* + +Append a Request ID to the standard error log format, load the ID value from `$variable`. `$variable` must be previously defined. + +For example, with this configuration: +``` +lua_kong_error_log_request_id $request_id; +``` +An error log line may look similar to the following: +``` +2023/09/06 11:33:36 [error] 94085#0: *6 [lua] content_by_lua(nginx.conf:27):7: hello world, client: 127.0.0.1, server: , request: "GET /foo HTTP/1.1", host: "localhost:8080", request_id: "cd7706e903db672ac5fac333bc8db5ed" +``` + +[Back to TOC](#table-of-contents) + Methods ======= @@ -147,6 +169,16 @@ This function returns `true` when the call is successful. Otherwise it returns [Back to TOC](#table-of-contents) +Variables +========= + +$kong\_request\_id +------------------ +Unique request identifier generated from 16 pseudo-random bytes, in hexadecimal. +This variable is indexed. + +[Back to TOC](#table-of-contents) + resty.kong.tls.disable\_session\_reuse -------------------------------------- **syntax:** *succ, err = resty.kong.tls.disable\_session\_reuse()* @@ -398,7 +430,7 @@ License ======= ``` -Copyright 2020 Kong Inc. +Copyright 2020-2023 Kong Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/config b/config index de040052..56e97342 100644 --- a/config +++ b/config @@ -4,8 +4,10 @@ ngx_module_srcs=" \ $ngx_addon_dir/src/ngx_http_lua_kong_apple_m1.c \ $ngx_addon_dir/src/ngx_http_lua_kong_grpc.c \ $ngx_addon_dir/src/ngx_http_lua_kong_ssl.c \ - $ngx_addon_dir/src/ngx_http_lua_kong_var.c \ + $ngx_addon_dir/src/ngx_http_lua_kong_var_index.c \ $ngx_addon_dir/src/ngx_http_lua_kong_module.c \ + $ngx_addon_dir/src/ngx_http_lua_kong_log_handler.c \ + $ngx_addon_dir/src/ngx_http_lua_kong_vars.c \ " ngx_module_incs="$ngx_addon_dir/src" diff --git a/src/ngx_http_lua_kong_common.h b/src/ngx_http_lua_kong_common.h index 742cc5bf..563ae1f9 100644 --- a/src/ngx_http_lua_kong_common.h +++ b/src/ngx_http_lua_kong_common.h @@ -33,9 +33,15 @@ typedef struct { unsigned upstream_ssl_verify:1; unsigned upstream_ssl_verify_set:1; unsigned upstream_ssl_verify_depth_set:1; + ngx_http_log_handler_pt orig_log_handler; } ngx_http_lua_kong_ctx_t; +typedef struct { + ngx_int_t request_id_var_index; +} ngx_http_lua_kong_loc_conf_t; + + #ifdef NGX_LUA_USE_ASSERT #include # define ngx_http_lua_kong_assert(a) assert(a) @@ -48,4 +54,10 @@ extern ngx_module_t ngx_http_lua_kong_module; ngx_http_lua_kong_ctx_t *ngx_http_lua_kong_get_module_ctx( ngx_http_request_t *r); +char *ngx_http_lua_kong_error_log_init( + ngx_conf_t *cf); + +ngx_int_t +ngx_http_lua_kong_add_vars(ngx_conf_t *cf); + #endif /* _NGX_HTTP_LUA_KONG_COMMON_H_INCLUDED_ */ diff --git a/src/ngx_http_lua_kong_directive.h b/src/ngx_http_lua_kong_directive.h index fe8c8fc5..7ba7aa98 100644 --- a/src/ngx_http_lua_kong_directive.h +++ b/src/ngx_http_lua_kong_directive.h @@ -26,4 +26,8 @@ char * ngx_http_lua_kong_load_var_index(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); +char * +ngx_http_lua_kong_error_log_request_id(ngx_conf_t *cf, ngx_command_t *cmd, + void *conf); + #endif /* _NGX_HTTP_LUA_KONG_DIRECTIVE_H_INCLUDED_ */ diff --git a/src/ngx_http_lua_kong_log_handler.c b/src/ngx_http_lua_kong_log_handler.c new file mode 100644 index 00000000..380d8af3 --- /dev/null +++ b/src/ngx_http_lua_kong_log_handler.c @@ -0,0 +1,147 @@ +/** + * Copyright 2019-2023 Kong Inc. + + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + + * http://www.apache.org/licenses/LICENSE-2.0 + + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ngx_http_lua_kong_common.h" + + +/* + * This function contains the logic to append the Request ID to + * the error log line when being called + */ +static u_char * +ngx_http_lua_kong_error_log_handler(ngx_http_request_t *r, u_char *buf, size_t len) +{ + ngx_http_variable_value_t *value; + ngx_http_lua_kong_loc_conf_t *lcf; + + lcf = ngx_http_get_module_loc_conf(r, ngx_http_lua_kong_module); + if (lcf->request_id_var_index == NGX_CONF_UNSET) { + return buf; + } + + value = ngx_http_get_indexed_variable(r, lcf->request_id_var_index); + if (value == NULL || value->not_found) { + return buf; + } + + buf = ngx_snprintf(buf, len, ", request_id: \"%v\"", value); + + return buf; +} + + +/* + * This function replaces the original HTTP error + * log handler (r->log_handler). It executes the original logic + * and then our error log handler: ngx_http_lua_kong_error_log_handler + */ +static u_char * +ngx_http_lua_kong_combined_error_log_handler(ngx_http_request_t *r, + ngx_http_request_t *sr, u_char *buf, size_t len) +{ + u_char *p; + ngx_http_lua_kong_ctx_t *ctx; + + ctx = ngx_http_lua_kong_get_module_ctx(r); + if (ctx == NULL || ctx->orig_log_handler == NULL) { + return buf; + } + + /* original log handler */ + p = ctx->orig_log_handler(r, sr, buf, len); + len -= p - buf; + buf = p; + + /* Kong log handler */ + buf = ngx_http_lua_kong_error_log_handler(r, buf, len); + + return buf; +} + + +static ngx_int_t +ngx_http_lua_kong_replace_error_log_handler(ngx_http_request_t *r) +{ + ngx_http_lua_kong_ctx_t *ctx; + + ctx = ngx_http_lua_kong_get_module_ctx(r); + if (ctx == NULL) { + return NGX_ERROR; + } + + if (r->log_handler == NULL) { + return NGX_DECLINED; + } + + /* + * Store the original log handler in ctx->orig_log_handler, replace + * it with the combined log handler, which will execute the original + * handler's logic in addition to our own. + */ + ctx->orig_log_handler = r->log_handler; + r->log_handler = ngx_http_lua_kong_combined_error_log_handler; + + return NGX_DECLINED; +} + + +char * +ngx_http_lua_kong_error_log_init(ngx_conf_t *cf) +{ + ngx_http_handler_pt *h; + ngx_http_core_main_conf_t *cmcf; + + cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module); + + h = ngx_array_push(&cmcf->phases[NGX_HTTP_POST_READ_PHASE].handlers); + if (h == NULL) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "failed setting error log handler"); + return NGX_CONF_ERROR; + } + + *h = ngx_http_lua_kong_replace_error_log_handler; + + return NGX_CONF_OK; +} + + +char * +ngx_http_lua_kong_error_log_request_id(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) +{ + ngx_str_t *value; + ngx_http_lua_kong_loc_conf_t *lcf = conf; + + value = cf->args->elts; + + if (value[1].data[0] != '$') { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "invalid variable name \"%V\"", &value[1]); + return NGX_CONF_ERROR; + } + + value[1].len--; + value[1].data++; + + lcf->request_id_var_index = ngx_http_get_variable_index(cf, &value[1]); + if (lcf->request_id_var_index == NGX_ERROR) { + return NGX_CONF_ERROR; + } + + return NGX_CONF_OK; +} + + diff --git a/src/ngx_http_lua_kong_module.c b/src/ngx_http_lua_kong_module.c index e568b280..3e686057 100644 --- a/src/ngx_http_lua_kong_module.c +++ b/src/ngx_http_lua_kong_module.c @@ -20,10 +20,12 @@ static ngx_int_t ngx_http_lua_kong_init(ngx_conf_t *cf); +static void* ngx_http_lua_kong_create_loc_conf(ngx_conf_t* cf); +static char* ngx_http_lua_kong_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child); static ngx_http_module_t ngx_http_lua_kong_module_ctx = { - NULL, /* preconfiguration */ + ngx_http_lua_kong_add_vars, /* preconfiguration */ ngx_http_lua_kong_init, /* postconfiguration */ NULL, /* create main configuration */ @@ -32,8 +34,8 @@ static ngx_http_module_t ngx_http_lua_kong_module_ctx = { NULL, /* create server configuration */ NULL, /* merge server configuration */ - NULL, /* create location configuration */ - NULL /* merge location configuration */ + ngx_http_lua_kong_create_loc_conf, /* create location configuration */ + ngx_http_lua_kong_merge_loc_conf /* merge location configuration */ }; static ngx_command_t ngx_http_lua_kong_commands[] = { @@ -45,6 +47,13 @@ static ngx_command_t ngx_http_lua_kong_commands[] = { 0, NULL }, + { ngx_string("lua_kong_error_log_request_id"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, + ngx_http_lua_kong_error_log_request_id, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_lua_kong_loc_conf_t, request_id_var_index), + NULL }, + ngx_null_command }; @@ -68,6 +77,10 @@ ngx_module_t ngx_http_lua_kong_module = { static ngx_int_t ngx_http_lua_kong_init(ngx_conf_t *cf) { + if (ngx_http_lua_kong_error_log_init(cf) != NGX_CONF_OK) { + return NGX_ERROR; + } + return ngx_http_lua_kong_ssl_init(cf); } @@ -112,3 +125,32 @@ ngx_http_lua_kong_get_module_ctx(ngx_http_request_t *r) } +static void * +ngx_http_lua_kong_create_loc_conf(ngx_conf_t* cf) +{ + ngx_http_lua_kong_loc_conf_t *conf; + + conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_lua_kong_loc_conf_t)); + if (conf == NULL) { + return NULL; + } + + conf->request_id_var_index = NGX_CONF_UNSET; + + return conf; +} + + +static char* +ngx_http_lua_kong_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child) +{ + ngx_http_lua_kong_loc_conf_t *prev = parent; + ngx_http_lua_kong_loc_conf_t *conf = child; + + /* conf->tag is NGX_HTTP_LOC_CONF only */ + ngx_conf_merge_value(conf->request_id_var_index, prev->request_id_var_index, NGX_CONF_UNSET); + + return NGX_CONF_OK; +} + + diff --git a/src/ngx_http_lua_kong_var.c b/src/ngx_http_lua_kong_var_index.c similarity index 98% rename from src/ngx_http_lua_kong_var.c rename to src/ngx_http_lua_kong_var_index.c index ec36e5d4..eb9a8c29 100644 --- a/src/ngx_http_lua_kong_var.c +++ b/src/ngx_http_lua_kong_var_index.c @@ -72,7 +72,7 @@ static ngx_str_t default_vars[] = { ngx_string("server_addr"), ngx_string("server_port"), -/* --with-http_ssl_module */ + /* --with-http_ssl_module */ #if (NGX_SSL) ngx_string("ssl_cipher"), ngx_string("ssl_client_raw_cert"), @@ -86,6 +86,9 @@ static ngx_str_t default_vars[] = { ngx_string("upstream_http_upgrade"), ngx_string("upstream_status"), + /* lua-kong-module vars */ + ngx_string("kong_request_id"), + ngx_null_string }; diff --git a/src/ngx_http_lua_kong_vars.c b/src/ngx_http_lua_kong_vars.c new file mode 100644 index 00000000..5d180fc8 --- /dev/null +++ b/src/ngx_http_lua_kong_vars.c @@ -0,0 +1,81 @@ +/** + * Copyright 2019-2023 Kong Inc. + + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + + * http://www.apache.org/licenses/LICENSE-2.0 + + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#include "ngx_http_lua_kong_common.h" + + +#define NGX_HTTP_LUA_KONG_RANDOM_COUNT 4 +#define NGX_HTTP_LUA_KONG_UINT32_HEX_LEN sizeof(uint32_t) * 2 + + +static ngx_int_t +ngx_http_lua_kong_variable_request_id(ngx_http_request_t *r, + ngx_http_variable_value_t *v, uintptr_t data) +{ + u_char *id; + uint32_t i, rnd; + + id = ngx_pnalloc(r->pool, + NGX_HTTP_LUA_KONG_RANDOM_COUNT * + NGX_HTTP_LUA_KONG_UINT32_HEX_LEN); + if (id == NULL) { + return NGX_ERROR; + } + + v->valid = 1; + v->no_cacheable = 0; + v->not_found = 0; + + v->len = NGX_HTTP_LUA_KONG_RANDOM_COUNT * + NGX_HTTP_LUA_KONG_UINT32_HEX_LEN; + v->data = id; + + for (i = 0; i < NGX_HTTP_LUA_KONG_RANDOM_COUNT; i++) { + rnd = (uint32_t) ngx_random(); + id = ngx_hex_dump(id, (u_char *) &rnd, sizeof(uint32_t)); + } + + return NGX_OK; +} + + +static ngx_http_variable_t ngx_http_lua_kong_variables[] = { + + { ngx_string("kong_request_id"), NULL, + ngx_http_lua_kong_variable_request_id, + 0, 0, 0 }, + + ngx_http_null_variable +}; + + +ngx_int_t +ngx_http_lua_kong_add_vars(ngx_conf_t *cf) +{ + ngx_http_variable_t *cv, *v; + + for (cv = ngx_http_lua_kong_variables; cv->name.len; cv++) { + v = ngx_http_add_variable(cf, &cv->name, cv->flags); + if (v == NULL) { + return NGX_ERROR; + } + + *v = *cv; + } + + return NGX_OK; +} diff --git a/t/009-error-log-append.t b/t/009-error-log-append.t new file mode 100644 index 00000000..7b97c306 --- /dev/null +++ b/t/009-error-log-append.t @@ -0,0 +1,259 @@ +use Test::Nginx::Socket::Lua; + +#worker_connections(1014); +#master_process_enabled(1); +#log_level('warn'); + +repeat_each(2); + +plan tests => repeat_each() * (blocks() * 5) + 10; + +#no_diff(); +no_long_string(); +#master_on(); +#workers(2); +check_accum_error_log(); +run_tests(); + +__DATA__ + + +=== TEST 1: sanity: without directive there is no appended request ID +and the original error log is preserved +--- http_config + lua_package_path "../lua-resty-core/lib/?.lua;lualib/?.lua;;"; +--- config + location = /test { + content_by_lua_block { + ngx.log(ngx.INFO, "log_msg") + ngx.exit(200) + } + } +--- request +GET /test +--- error_log eval +qr/log_msg.*client:.*server:.*request:.*host:.*$/ +--- no_error_log eval +[ + qr/log_msg.*request_id/, + "[error]", + "[crit]", + "[alert]", +] + + +=== TEST 2: value is appended correctly to error logs +--- http_config + lua_package_path "../lua-resty-core/lib/?.lua;lualib/?.lua;;"; +--- config + location = /test { + set $my_var "yay!"; + lua_kong_error_log_request_id $my_var; + content_by_lua_block { + ngx.log(ngx.INFO, "log_msg") + ngx.exit(200) + } + } +--- request +GET /test +--- error_log eval +qr/log_msg.*request_id: "yay!"$/ +--- no_error_log +[error] +[crit] +[alert] + + +=== TEST 3: value is appended correctly to error logs when a runtime error occurs +--- http_config + lua_package_path "../lua-resty-core/lib/?.lua;lualib/?.lua;;"; +--- config + location = /test { + set $req_id 123456; + lua_kong_error_log_request_id "$req_id"; + + content_by_lua_block { + error("error_message") + } + } +--- request +GET /test +--- error_code: 500 +--- error_log eval +qr/.*request_id: "123456".*$/ + + +=== TEST 4: scoping: value is appended correctly to error logs +based on the location where the directive is defined +--- http_config + lua_package_path "../lua-resty-core/lib/?.lua;lualib/?.lua;;"; +--- config + location = /append_req_id { + set $req_id_a 123456; + lua_kong_error_log_request_id $req_id_a; + + content_by_lua_block { + ngx.log(ngx.INFO, "log_msg") + ngx.exit(200) + } + } + location = /append_method { + set $req_id_b 654321; + lua_kong_error_log_request_id $req_id_b; + + content_by_lua_block { + ngx.log(ngx.INFO, "log_msg") + ngx.exit(200) + } + } +--- pipelined_requests eval +["GET /append_req_id", "GET /append_method"] +--- error_code eval +[200, 200, 200] +--- error_log eval +[ 'request_id: "123456"', 'request_id: "654321"' ] +--- no_error_log +[error] +[crit] +[alert] + + +=== TEST 5: scoping: value is NOT appended to error logs +for the location where the directive is NOT defined +--- http_config + lua_package_path "../lua-resty-core/lib/?.lua;lualib/?.lua;;"; +--- config + location = /append { + set $req_id 123456; + lua_kong_error_log_request_id $req_id; + + content_by_lua_block { + ngx.log(ngx.ERR, "log_msg") + ngx.exit(200) + } + } + + location = /no_append { + content_by_lua_block { + ngx.log(ngx.INFO, "log_msg") + ngx.exit(200) + } + } +--- request +GET /no_append +--- error_code: 200 +--- no_error_log eval +qr/log_msg.*request_id/ + + +=== TEST 6: scoping: value is appended correctly to error logs +when the directive is in the main configuration +--- http_config + lua_package_path "../lua-resty-core/lib/?.lua;lualib/?.lua;;"; + lua_kong_error_log_request_id $req_id; +--- config + set $req_id 123456; + location = /test { + content_by_lua_block { + ngx.log(ngx.INFO, "log_msg") + ngx.exit(200) + } + } +--- request +GET /test +--- error_code: 200 +--- error_log eval +qr/log_msg.*request_id: "123456"$/ +--- no_error_log +[error] +[crit] +[alert] + + +=== TEST 7: scoping: value is appended correctly to error logs +and the local directive overrides the global one +--- http_config + lua_package_path "../lua-resty-core/lib/?.lua;lualib/?.lua;;"; + lua_kong_error_log_request_id $req_id_global; +--- config + set $req_id_global global; + set $req_id_local local; + + location = /test { + lua_kong_error_log_request_id $req_id_local; + content_by_lua_block { + ngx.log(ngx.INFO, "log_msg") + ngx.exit(200) + } + } +--- request +GET /test +--- error_code: 200 +--- error_log eval +qr/log_msg.*request_id: "local"$/ +--- no_error_log eval +qr/log_msg.*request_id: "global"$/ + + +=== TEST 8: Request ID variable changes are applied to the error log output +--- http_config + lua_package_path "../lua-resty-core/lib/?.lua;lualib/?.lua;;"; +--- config + location = /test { + set $my_var ""; + lua_kong_error_log_request_id $my_var; + rewrite_by_lua_block { + ngx.log(ngx.INFO, "rewrite_0") + ngx.var.my_var = "changed_in_rewrite" + ngx.log(ngx.INFO, "rewrite_1") + ngx.var.my_var = "changed_in_rewrite_2" + ngx.log(ngx.INFO, "rewrite_2") + } + access_by_lua_block { + ngx.log(ngx.INFO, "access_0") + ngx.var.my_var = "changed_in_access" + ngx.log(ngx.INFO, "access_1") + ngx.var.my_var = "changed_in_access_2" + ngx.log(ngx.INFO, "access_2") + ngx.exit(200) + } + } +--- request +GET /test +--- error_log eval +[ + qr/rewrite_0.*request_id: ""$/, + qr/rewrite_1.*request_id: "changed_in_rewrite"$/, + qr/rewrite_2.*request_id: "changed_in_rewrite_2"$/, + qr/access_0.*request_id: "changed_in_rewrite_2"$/, + qr/access_1.*request_id: "changed_in_access"$/, + qr/access_2.*request_id: "changed_in_access_2"$/, +] +--- no_error_log +[error] +[crit] +[alert] + + +=== TEST 9: $kong_request_id is appended correctly to error logs +--- http_config + lua_package_path "../lua-resty-core/lib/?.lua;lualib/?.lua;;"; + lua_kong_error_log_request_id $kong_request_id; +--- config + location = /test { + content_by_lua_block { + ngx.log(ngx.INFO, "log_msg") + ngx.exit(200) + } + } +--- request +GET /test +--- error_code: 200 +--- error_log eval +qr/log_msg.*request_id: "[0-9a-f]{32}"$/ +--- no_error_log +[error] +[crit] +[alert] + + diff --git a/t/010-request-id.t b/t/010-request-id.t new file mode 100644 index 00000000..b1ed0a83 --- /dev/null +++ b/t/010-request-id.t @@ -0,0 +1,41 @@ +# vim:set ft= ts=4 sw=4 et: + +use Test::Nginx::Socket::Lua; +use Cwd qw(cwd); + +repeat_each(2); + +plan tests => repeat_each() * (blocks() * 5); + +my $pwd = cwd(); + +$ENV{TEST_NGINX_HTML_DIR} ||= html_dir(); + +no_long_string(); + +run_tests(); + +__DATA__ + +=== TEST 1: $kong_request_id works +--- config + location /t { + content_by_lua_block { + local rid = ngx.var.kong_request_id + assert(ngx.re.match(rid, "[0-9a-f]{32}")) + ngx.say("ok") + } + } + +--- request +GET /t +--- response_body_like +ok + +--- error_code: 200 +--- no_error_log +[error] +[crit] +[alert] + + diff --git a/t/stream/001-upstream-tls.t b/t/stream/001-upstream-tls.t index 9688eb85..e6585e27 100644 --- a/t/stream/001-upstream-tls.t +++ b/t/stream/001-upstream-tls.t @@ -4,6 +4,9 @@ use Test::Nginx::Socket::Lua::Stream; #worker_connections(1014); #master_process_enabled(1); + +$ENV{TEST_NGINX_HTML_DIR} ||= html_dir(); + log_level('warn'); repeat_each(2); @@ -17,36 +20,98 @@ run_tests(); __DATA__ === TEST 1: upstream TLS proxying works +--- http_config + lua_package_path "../lua-resty-core/lib/?.lua;lualib/?.lua;;"; + + server { + listen unix:$TEST_NGINX_HTML_DIR/nginx.sock ssl; + server_name example.com; + ssl_certificate ../../cert/example.com.crt; + ssl_certificate_key ../../cert/example.com.key; + + server_tokens off; + + location /foo { + default_type 'text/plain'; + more_clear_headers Date; + echo 'it works!'; + } + } +--- stream_config + upstream foo { + server unix:$TEST_NGINX_HTML_DIR/nginx.sock; + } --- stream_server_config - proxy_pass mockbin.com:443; + proxy_ssl_trusted_certificate ../../cert/ca.crt; + proxy_ssl_verify on; + proxy_ssl_name example.com; proxy_ssl on; - proxy_ssl_server_name on; + + proxy_pass foo; + proxy_ssl_session_reuse off; + --- stream_request eval -"GET / HTTP/1.0\r\nHost: mockbin.com\r\n\r\n" ---- stream_response_like: ^HTTP/1.1 200 OK +"GET /foo HTTP/1.0\r\nHost: example.com\r\n\r\n" + +--- stream_response_like +it works! + --- no_error_log [error] === TEST 2: upstream plaintext proxying works +--- http_config + lua_package_path "../lua-resty-core/lib/?.lua;lualib/?.lua;;"; + + server { + listen unix:$TEST_NGINX_HTML_DIR/nginx.sock; + server_name example.com; + + server_tokens off; + + location /foo { + default_type 'text/plain'; + more_clear_headers Date; + echo 'it works!'; + } + } +--- stream_config + upstream foo { + server unix:$TEST_NGINX_HTML_DIR/nginx.sock; + } --- stream_server_config - proxy_pass mockbin.com:80; proxy_ssl off; + proxy_pass foo; + --- stream_request eval -"GET / HTTP/1.0\r\nHost: mockbin.com\r\n\r\n" ---- stream_response_like: ^HTTP/1.1 200 OK +"GET /foo HTTP/1.0\r\nHost: example.com\r\n\r\n" + +--- stream_response_like +it works! + --- no_error_log [error] === TEST 3: upstream TLS proxying inhibit works ---- stream_config +--- http_config lua_package_path "../lua-resty-core/lib/?.lua;lualib/?.lua;;"; + server { + listen unix:$TEST_NGINX_HTML_DIR/nginx.sock ssl; + server_name example.com; + ssl_certificate ../../cert/example.com.crt; + ssl_certificate_key ../../cert/example.com.key; + + server_tokens off; + } +--- stream_config + proxy_ssl_session_reuse off; --- stream_server_config - proxy_pass mockbin.com:443; + proxy_pass unix:$TEST_NGINX_HTML_DIR/nginx.sock; proxy_ssl on; preread_by_lua_block { @@ -55,7 +120,7 @@ __DATA__ assert(tls.disable_proxy_ssl()) } --- stream_request eval -"GET / HTTP/1.0\r\nHost: mockbin.com\r\n\r\n" +"GET / HTTP/1.0\r\nHost: example.com\r\n\r\n" --- stream_response_like: ^.+400 The plain HTTP request was sent to HTTPS port.+$ --- no_error_log [error]