From 5ec1d93344f1b1164ae59b2af3e07eeef4866cc8 Mon Sep 17 00:00:00 2001 From: Caio Casimiro Date: Wed, 20 Sep 2023 11:58:39 +0100 Subject: [PATCH] wip --- .../hfuncs/102-proxy_send_local_response.t | 4 + t/04-openresty/ffi/103-proxy_wasm_attach.t | 4 + t/05-others/010-connection_drop.t | 281 ++++++++++++++++++ .../proxy-wasm-tests/hostcalls/src/filter.rs | 6 + .../proxy-wasm-tests/on-phases/src/filter.rs | 18 +- 5 files changed, 312 insertions(+), 1 deletion(-) create mode 100644 t/05-others/010-connection_drop.t diff --git a/t/03-proxy_wasm/hfuncs/102-proxy_send_local_response.t b/t/03-proxy_wasm/hfuncs/102-proxy_send_local_response.t index 269e9f5a2..e9f90253e 100644 --- a/t/03-proxy_wasm/hfuncs/102-proxy_send_local_response.t +++ b/t/03-proxy_wasm/hfuncs/102-proxy_send_local_response.t @@ -143,6 +143,7 @@ qr/.*? on_request_headers, 2 headers, .* .*? testing in "RequestHeaders", .* .*? on_response_headers, 5 headers, .* .*? on_response_body, 0 bytes, eof: true, .* +.*? on_done.* .*? on_log.*/ --- no_error_log [error] @@ -248,6 +249,7 @@ qr/.*? on_request_headers, 2 headers, .* .*? testing in "RequestHeaders", .* .*? on_response_headers, 16 headers, .* .*? on_response_body, 0 bytes, eof: true, .* +.*? on_done.* .*? on_log.*/ --- no_error_log [error] @@ -436,7 +438,9 @@ qr/.*? on_request_headers, \d+ headers.* .*? on_response_headers, \d+ headers.* .*? on_response_body, \d+ bytes, eof: true.* .*? on_response_body, \d+ bytes, eof: true.* +.*? on_done.* .*? on_log.* +.*? on_done.* .*? on_log.*/ --- no_error_log [error] diff --git a/t/04-openresty/ffi/103-proxy_wasm_attach.t b/t/04-openresty/ffi/103-proxy_wasm_attach.t index a18828d9c..9b7a0ef9d 100644 --- a/t/04-openresty/ffi/103-proxy_wasm_attach.t +++ b/t/04-openresty/ffi/103-proxy_wasm_attach.t @@ -105,6 +105,7 @@ qr/^[^#]*#0 on_vm_start[^#]* #\d+ on_response_headers, 5 headers[^#]* #\d+ on_response_body, 3 bytes, eof: false[^#]* #\d+ on_response_body, 0 bytes, eof: true[^#]* +#\d+ on_done[^#]* #\d+ on_log[^#]*$/ --- error_log eval qr/\[error\] .*? previous plan already attached/ @@ -156,6 +157,7 @@ qr/^[^#]*#0 on_vm_start[^#]* #\d+ on_response_headers, 5 headers[^#]* #\d+ on_response_body, 3 bytes, eof: false[^#]* #\d+ on_response_body, 0 bytes, eof: true[^#]* +#\d+ on_done[^#]* #\d+ on_log[^#]*$/ --- no_error_log [error] @@ -207,6 +209,7 @@ qr/^[^#]*#0 on_vm_start[^#]* #\d+ on_response_headers, 5 headers[^#]* #\d+ on_response_body, 3 bytes, eof: false[^#]* #\d+ on_response_body, 0 bytes, eof: true[^#]* +#\d+ on_done[^#]* #\d+ on_log[^#]*$/ --- no_error_log [error] @@ -258,6 +261,7 @@ qr/^[^#]*#0 on_vm_start[^#]* #\d+ on_response_headers, 5 headers[^#]* #\d+ on_response_body, 3 bytes, eof: false[^#]* #\d+ on_response_body, 0 bytes, eof: true[^#]* +#\d+ on_done[^#]* #\d+ on_log[^#]*$/ --- no_error_log [error] diff --git a/t/05-others/010-connection_drop.t b/t/05-others/010-connection_drop.t new file mode 100644 index 000000000..993c6066b --- /dev/null +++ b/t/05-others/010-connection_drop.t @@ -0,0 +1,281 @@ +# vim:set ft= ts=4 sts=4 sw=4 et fdm=marker: + +use strict; +use lib '.'; +use t::TestWasm; + +plan tests => repeat_each() * (blocks() * 4); + +run_tests(); + +__DATA__ + +=== TEST 1: client connection drop - proxy_wasm & echo - chained filters +If a client drops the connection immediately after sending an HTTP request, +and the sent request is answered by the echo directive, +all filters executing on that request will have their on_response_headers, +on_response_body, on_log and on_done entrypoints invoked. + +--- load_nginx_modules: ngx_http_echo_module +--- wasm_modules: on_phases +--- config + location /t { + proxy_wasm on_phases; + proxy_wasm on_phases; + echo ok; + } +--- shutdown +--- ignore_response +--- grep_error_log eval: qr/#\d+ on_(response|log|done).*/ +--- grep_error_log_out eval +qr/#\d+ on_response_headers, 5 headers.* +#\d+ on_response_headers, 5 headers.* +#\d+ on_response_body, 3 bytes, eof: false.* +#\d+ on_response_body, 3 bytes, eof: false.* +#\d+ on_response_body, 0 bytes, eof: true.* +#\d+ on_response_body, 0 bytes, eof: true.* +#\d+ on_done.* +#\d+ on_log.* +#\d+ on_done.* +#\d+ on_log.*/ +--- no_error_log +[error] +[crit] +[stub] + + + +=== TEST 2: client connection drop - proxy_wasm & proxy_pass - chained filters +If a client drops the connection immediately after sending an HTTP request, +and sent request is proxied by proxy_pass, +all filters executing on that request will only have their on_log and on_done +entrypoints invoked. + +--- wasm_modules: on_phases +--- http_config eval +qq{ + server { + listen unix:$ENV{TEST_NGINX_UNIX_SOCKET}; + + location / { + return 200; + } + } +} +--- config + location /t { + proxy_wasm on_phases; + proxy_wasm on_phases; + proxy_pass http://unix:$TEST_NGINX_UNIX_SOCKET:/; + } +--- shutdown +--- ignore_response +--- grep_error_log eval: qr/\[info\] .*? on_(response|log|done).*/ +--- grep_error_log_out eval +qr/\[info\] .*? on_done.* +\[info\] .*? on_log.*/ +--- no_error_log eval +[ + qr/\[info\] .*? on_response.*/, + "[error]", + "[crit]" +] + + + +=== TEST 3: client connection drop - proxy_wasm - filters dispatch HTTP call +If a client drops the connection immediately after sending an HTTP request, +all filters executing on that request that have dispatched HTTP calls will have +their on_http_call_response entrypoint invoked. + +--- load_nginx_modules: ngx_http_echo_module +--- wasm_modules: hostcalls +--- http_config eval +qq{ + server { + listen unix:$ENV{TEST_NGINX_UNIX_SOCKET}; + + location /status/200 { + return 200; + } + + location /status/201 { + return 201; + } + } +} +--- config + location /t { + proxy_wasm hostcalls 'test=/t/dispatch_http_call \ + host=unix:$TEST_NGINX_UNIX_SOCKET \ + path=/status/200'; + proxy_wasm hostcalls 'test=/t/dispatch_http_call \ + host=unix:$TEST_NGINX_UNIX_SOCKET \ + path=/status/201'; + echo ok; + } +--- shutdown +--- ignore_response +--- grep_error_log eval: qr/\*\d+.*?on_http_call_response.*/ +--- grep_error_log_out eval +qr/^\*\d+ .*? on_http_call_response \(id: \d+, status: 200[^*].* +\*\d+ .*? on_http_call_response \(id: \d+, status: 201[^*].*/ +--- no_error_log +[error] +[crit] +[stub] + + + +=== TEST 4: client connection drop - proxy_wasm - send_local_response() +If a client drops the connection immediately after sending an HTTP request, +and a filter running on that request calls send_local_response(), +a response will be produced; + +filters running on the same request and declared after the filter which called +send_local_response() will have their on_response_headers, on_response_body, +on_log and on_done entrypoints invoked; + +filters running on the same request and declared before the filter will have +only their on_response_body, on_log and on_done entrypoints invoked. + +--- wasm_modules: hostcalls on_phases +--- config + location /t { + proxy_wasm on_phases; + proxy_wasm hostcalls 'test=/t/send_local_response/body'; + proxy_wasm on_phases; + } +--- shutdown +--- ignore_response +--- grep_error_log eval: qr/\[info\] .*? on_(response|log|done).*/ +--- grep_error_log_out eval +qr/.*\["hostcalls" #1\].* on_response_headers.* +.*\["on_phases" #2\].* on_response_headers.* +.*\["on_phases" #1\].* on_response_body.* +.*\["hostcalls" #1\].* on_response_body.* +.*\["on_phases" #2\].* on_response_body.* +.*\["on_phases" #1\].* on_done.* +.*\["on_phases" #1\].* on_log.* +.*\["hostcalls" #1\].* on_done.* +.*\["hostcalls" #1\].* on_log.* +.*\["on_phases" #2\].* on_done.* +.*\["on_phases" #2\].* on_log.*/ +--- no_error_log eval +[ + qr/.*\["on_phases" #1\].* on_response_headers.*/, + "[error]", + "[crit]", +] + + + +=== TEST 6: client connection drop - wasm_call & echo - body_filter +If a client drops the connection immediately after sending an HTTP request, +and that request is answered by the echo directive, +wasm functions configured to execute on content/header_filter/body_filter phases +will be invoked. + +--- SKIP: This test is intermitently passing on CI. +--- load_nginx_modules: ngx_http_echo_module +--- wasm_modules: ngx_rust_tests +--- config + location /t { + wasm_call content ngx_rust_tests log_notice_hello; + wasm_call header_filter ngx_rust_tests log_notice_hello; + wasm_call body_filter ngx_rust_tests log_notice_hello; + echo ok; + } +--- shutdown +--- ignore_response +--- grep_error_log eval: qr/\[debug\] .*? \*\d wasm ops calling .* in .* phase.*/ +--- grep_error_log_out eval +qr/\[debug\] .* wasm ops calling "ngx_rust_tests.log_notice_hello" in "content" phase.* +\[debug\] .* wasm ops calling "ngx_rust_tests.log_notice_hello" in "header_filter" phase.* +\[debug\] .* wasm ops calling "ngx_rust_tests.log_notice_hello" in "body_filter" phase.* +\[debug\] .* wasm ops calling "ngx_rust_tests.log_notice_hello" in "body_filter" phase.*/ +--- no_error_log +[error] +[crit] +[stub] + + + +=== TEST 7: client connection drop - wasm_call & proxy_pass - body_filter +If a client drops the connection immediately after sending an HTTP request, +and that request is proxied by proxy_pass, +only wasm functions configured to execute in content phase will be invoked. + +--- SKIP: This test is intermitently passing on CI. +--- load_nginx_modules: ngx_http_echo_module +--- wasm_modules: ngx_rust_tests +--- http_config eval +qq{ + server { + listen unix:$ENV{TEST_NGINX_UNIX_SOCKET}; + + location / { + return 201; + } + } +} +--- config + location /t { + wasm_call content ngx_rust_tests log_notice_hello; + wasm_call header_filter ngx_rust_tests log_notice_hello; + wasm_call body_filter ngx_rust_tests log_notice_hello; + proxy_pass http://unix:$TEST_NGINX_UNIX_SOCKET:/; + } +--- shutdown +--- ignore_response +--- grep_error_log eval: qr/\[debug\] .*? \*\d wasm ops calling .* in .* phase.*/ +--- grep_error_log_out eval +qr/\[debug\] .* wasm ops calling "ngx_rust_tests.log_notice_hello" in "content" phase.*/ +--- no_error_log eval +[ + qr/\[debug\] .* wasm ops calling .* in "(header_filter|body_filter)" phase.*/, + "[error]", + "[crit]", +] + + + +=== TEST 5: upstream connection drop - dispatch_http_call() +--- SKIP +--- wasm_modules: hostcalls +--- tcp_listen: $TEST_NGINX_UNIX_SOCKET +--- tcp_reply eval +sub { + return ["HTTP/1.1 100 OK\r\n", + "Connection: close\r\n", + "Content-Length: 0\r\n", + "\r\n"]; +} +--- config + location /t { + proxy_wasm hostcalls 'test=/t/dispatch_http_call \ + host=unix:$TEST_NGINX_UNIX_SOCKET \ + on_http_call_response=echo_response_headers'; + return 204; + } +--- ignore_response +--- grep_error_log eval: qr/(wasm tcp socket|recv:).*/ +--- grep_error_log_out eval +qr/wasm tcp socket connected to "unix:$ENV{TEST_NGINX_UNIX_SOCKET}:0" +wasm tcp socket sent all the data +wasm tcp socket handler.* +wasm tcp socket resuming +wasm tcp socket handler.* +wasm tcp socket receive handler for "unix:$ENV{TEST_NGINX_UNIX_SOCKET}:0" +wasm tcp socket resuming +wasm tcp socket trying to receive data.* +recv: eof:1, avail:-1 +recv: fd:\d+ 0 of 1024 +wasm tcp socket eof +wasm tcp socket no bytes to parse +wasm tcp socket reading done +wasm tcp socket closing/ +--- no_error_log +[error] +[crit] +[stub] diff --git a/t/lib/proxy-wasm-tests/hostcalls/src/filter.rs b/t/lib/proxy-wasm-tests/hostcalls/src/filter.rs index 3c305ee85..3c61dcc14 100644 --- a/t/lib/proxy-wasm-tests/hostcalls/src/filter.rs +++ b/t/lib/proxy-wasm-tests/hostcalls/src/filter.rs @@ -105,6 +105,12 @@ impl Context for TestHttp { self.resume_http_request() } + + fn on_done(&mut self) -> bool { + info!("[hostcalls] on_done"); + + true + } } impl HttpContext for TestHttp { diff --git a/t/lib/proxy-wasm-tests/on-phases/src/filter.rs b/t/lib/proxy-wasm-tests/on-phases/src/filter.rs index 447cc1367..11fc304c3 100644 --- a/t/lib/proxy-wasm-tests/on-phases/src/filter.rs +++ b/t/lib/proxy-wasm-tests/on-phases/src/filter.rs @@ -109,7 +109,23 @@ impl OnPhases { } } -impl Context for OnPhases {} +impl Context for OnPhases { + fn on_done(&mut self) -> bool { + info!("#{} on_done", self.context_id); + + let log_msg = self + .config + .get("log_msg") + .map_or(String::new(), |s| s.to_string()); + + if !log_msg.is_empty() { + info!("#{} log_msg: {}", self.context_id, log_msg); + } + + true + } +} + impl HttpContext for OnPhases { fn on_http_request_headers(&mut self, nheaders: usize, _eof: bool) -> Action { info!(