diff --git a/src/common/proxy_wasm/ngx_proxy_wasm.c b/src/common/proxy_wasm/ngx_proxy_wasm.c index c5394daff..65f14f93e 100644 --- a/src/common/proxy_wasm/ngx_proxy_wasm.c +++ b/src/common/proxy_wasm/ngx_proxy_wasm.c @@ -732,8 +732,14 @@ ngx_proxy_wasm_resume(ngx_proxy_wasm_ctx_t *pwctx, case NGX_PROXY_WASM_STEP_TICK: case NGX_PROXY_WASM_STEP_DONE: case NGX_PROXY_WASM_STEP_RESP_BODY: - case NGX_PROXY_WASM_STEP_RESP_HEADERS: case NGX_PROXY_WASM_STEP_DISPATCH_RESPONSE: + break; + case NGX_PROXY_WASM_STEP_RESP_HEADERS: + if (pwctx->last_step < NGX_PROXY_WASM_STEP_RESP_HEADERS) { + /* first execution of response phases, ensure the chain is reset */ + ngx_proxy_wasm_ctx_reset_chain(pwctx); + } + break; default: if (step <= pwctx->last_step) { diff --git a/src/common/proxy_wasm/ngx_proxy_wasm.h b/src/common/proxy_wasm/ngx_proxy_wasm.h index f3b0e2f53..c001994e7 100644 --- a/src/common/proxy_wasm/ngx_proxy_wasm.h +++ b/src/common/proxy_wasm/ngx_proxy_wasm.h @@ -434,6 +434,18 @@ ngx_proxy_wasm_ctx_set_next_action(ngx_proxy_wasm_ctx_t *pwctx, } +static ngx_inline void +ngx_proxy_wasm_ctx_reset_chain(ngx_proxy_wasm_ctx_t *pwctx) +{ + ngx_proxy_wasm_log_error(NGX_LOG_DEBUG, pwctx->log, 0, + "resetting filter chain: pwctx->exec_index " + "%ld to 0 (pwctx: %p)", + pwctx->exec_index, pwctx); + + pwctx->exec_index = 0; +} + + static ngx_inline ngx_proxy_wasm_exec_t * ngx_proxy_wasm_instance2pwexec(ngx_wavm_instance_t *instance) { 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..2b7a792d3 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 @@ -417,7 +417,38 @@ Hello world -=== TEST 18: proxy_wasm - send_local_response() in chained filters +=== TEST 18: proxy_wasm - send_local_response() executes all chained filters response steps +should run all response steps of all chained filters +--- wasm_modules: hostcalls +--- config + location /t { + proxy_wasm hostcalls; + proxy_wasm hostcalls 'test=/t/send_local_response/body'; + proxy_wasm hostcalls; + } +--- response_body +Hello world +--- grep_error_log eval: qr/\[info\] .*? on_(request|response|log).*/ +--- grep_error_log_out eval +qr/\A.*? on_request_headers, \d+ headers.* +.*? on_request_headers, \d+ headers.* +.*? on_response_headers, \d+ headers.* +.*? on_response_headers, \d+ headers.* +.*? on_response_headers, \d+ headers.* +.*? on_response_body, \d+ bytes, eof: true.* +.*? on_response_body, \d+ bytes, eof: true.* +.*? on_response_body, \d+ bytes, eof: true.* +.*? on_log.* +.*? on_log.* +.*? on_log/ +--- no_error_log +[error] +[crit] +[alert] + + + +=== TEST 19: proxy_wasm - send_local_response() invoked twice in chained filters should interrupt the current phase, preventing "response already stashed" should still run all response phases --- wasm_modules: hostcalls @@ -445,7 +476,7 @@ qr/.*? on_request_headers, \d+ headers.* -=== TEST 19: proxy_wasm - send_local_response() in chained filters as a subrequest +=== TEST 20: proxy_wasm - send_local_response() in chained filters as a subrequest should interrupt the current phase, preventing "response already stashed" should still run all response phases should not have a log phase (subrequest)