From c7902689a5433e4c1a99428932a387a8b6ba72e9 Mon Sep 17 00:00:00 2001 From: Thibault Charbonnier Date: Fri, 17 May 2024 23:16:06 -0700 Subject: [PATCH] fix(proxy-wasm) cancel dispatch when immediately producing a response --- src/common/proxy_wasm/ngx_proxy_wasm.h | 7 +++--- src/common/proxy_wasm/ngx_proxy_wasm_util.c | 1 - .../proxy_wasm/ngx_http_proxy_wasm_dispatch.c | 10 ++++++-- .../proxy_wasm/ngx_http_proxy_wasm_dispatch.h | 2 ++ .../133-proxy_dispatch_http_edge_cases.t | 24 +++++++++++++++++++ .../hostcalls/src/types/test_http.rs | 6 +++++ 6 files changed, 43 insertions(+), 7 deletions(-) diff --git a/src/common/proxy_wasm/ngx_proxy_wasm.h b/src/common/proxy_wasm/ngx_proxy_wasm.h index 7d7f9d3e6..40a98472f 100644 --- a/src/common/proxy_wasm/ngx_proxy_wasm.h +++ b/src/common/proxy_wasm/ngx_proxy_wasm.h @@ -50,10 +50,9 @@ typedef enum { NGX_PROXY_WASM_ERR_START_FAILED = 5, NGX_PROXY_WASM_ERR_VM_START_FAILED = 6, NGX_PROXY_WASM_ERR_CONFIGURE_FAILED = 7, - NGX_PROXY_WASM_ERR_DISPATCH_FAILED = 8, - NGX_PROXY_WASM_ERR_INSTANCE_TRAPPED = 9, - NGX_PROXY_WASM_ERR_RETURN_ACTION = 10, - NGX_PROXY_WASM_ERR_UNKNOWN = 11, + NGX_PROXY_WASM_ERR_INSTANCE_TRAPPED = 8, + NGX_PROXY_WASM_ERR_RETURN_ACTION = 9, + NGX_PROXY_WASM_ERR_UNKNOWN = 10, } ngx_proxy_wasm_err_e; diff --git a/src/common/proxy_wasm/ngx_proxy_wasm_util.c b/src/common/proxy_wasm/ngx_proxy_wasm_util.c index 3e5ade1fb..e3629daa8 100644 --- a/src/common/proxy_wasm/ngx_proxy_wasm_util.c +++ b/src/common/proxy_wasm/ngx_proxy_wasm_util.c @@ -24,7 +24,6 @@ static ngx_str_t ngx_proxy_wasm_errlist[] = { ngx_string("on_context_create internal failure"), ngx_string("on_vm_start failure"), ngx_string("on_configure failure"), - ngx_string("dispatch failure"), ngx_string("instance trapped"), ngx_string("invalid return action"), ngx_string("unknown error") diff --git a/src/http/proxy_wasm/ngx_http_proxy_wasm_dispatch.c b/src/http/proxy_wasm/ngx_http_proxy_wasm_dispatch.c index d5a4c8fde..af999b1bb 100644 --- a/src/http/proxy_wasm/ngx_http_proxy_wasm_dispatch.c +++ b/src/http/proxy_wasm/ngx_http_proxy_wasm_dispatch.c @@ -94,8 +94,6 @@ ngx_http_proxy_wasm_dispatch_err(ngx_http_proxy_wasm_dispatch_t *call) } #endif - //pwexec->ecode = NGX_PROXY_WASM_ERR_DISPATCH_FAILED; - if (!pwexec->ictx->instance->hostcall || rctx->fake_request) { ngx_wasm_log_error(NGX_LOG_ERR, pwexec->log, 0, "%*s", p - (u_char *) &errbuf, &errbuf); @@ -389,6 +387,8 @@ ngx_http_proxy_wasm_dispatch(ngx_proxy_wasm_exec_t *pwexec, ngx_post_event(ev, &ngx_posted_events); + call->ev = ev; + ngx_queue_insert_head(&pwexec->calls, &call->q); ngx_proxy_wasm_ctx_set_next_action(pwctx, NGX_PROXY_WASM_ACTION_PAUSE); @@ -429,6 +429,11 @@ ngx_http_proxy_wasm_dispatch_destroy(ngx_http_proxy_wasm_dispatch_t *call) dd("enter"); + if (call->ev) { + ngx_delete_posted_event(call->ev); + call->ev = NULL; + } + ngx_wasm_socket_tcp_destroy(sock); if (call->host.data) { @@ -463,6 +468,7 @@ ngx_http_proxy_wasm_dispatch_handler(ngx_event_t *ev) ngx_wasm_socket_tcp_t *sock = &call->sock; ngx_free(ev); + call->ev = NULL; sock->resume_handler = ngx_http_proxy_wasm_dispatch_resume_handler; sock->data = call; diff --git a/src/http/proxy_wasm/ngx_http_proxy_wasm_dispatch.h b/src/http/proxy_wasm/ngx_http_proxy_wasm_dispatch.h index e83489127..a23e9a22e 100644 --- a/src/http/proxy_wasm/ngx_http_proxy_wasm_dispatch.h +++ b/src/http/proxy_wasm/ngx_http_proxy_wasm_dispatch.h @@ -49,6 +49,8 @@ struct ngx_http_proxy_wasm_dispatch_s { ngx_chain_t *req_body; ngx_chain_t *req_out; + ngx_event_t *ev; /* initial posted event */ + ngx_wasm_http_reader_ctx_t http_reader; ngx_http_proxy_wasm_dispatch_state_e state; ngx_http_request_t fake_r; diff --git a/t/03-proxy_wasm/hfuncs/133-proxy_dispatch_http_edge_cases.t b/t/03-proxy_wasm/hfuncs/133-proxy_dispatch_http_edge_cases.t index c2ae3fcc0..c77aaeda1 100644 --- a/t/03-proxy_wasm/hfuncs/133-proxy_dispatch_http_edge_cases.t +++ b/t/03-proxy_wasm/hfuncs/133-proxy_dispatch_http_edge_cases.t @@ -427,3 +427,27 @@ qr/\A\[error] .*? dispatch failed: tcp socket - Connection refused [crit] [emerg] [alert] + + + +=== TEST 13: proxy_wasm - dispatch_http_call() followed by a local response +Cancels pending posted event for dispatch +--- skip_no_debug +--- valgrind +--- load_nginx_modules: ngx_http_echo_module +--- wasm_modules: hostcalls +--- config + location /t { + proxy_wasm hostcalls 'on=request_headers \ + test=/t/dispatch_and_local_response \ + host=127.0.0.1:1'; + echo_status 200; + } +--- error_code: 201 +--- response_body +--- error_log +proxy_wasm http dispatch cancelled +--- no_error_log +[crit] +[emerg] +[alert] diff --git a/t/lib/proxy-wasm-tests/hostcalls/src/types/test_http.rs b/t/lib/proxy-wasm-tests/hostcalls/src/types/test_http.rs index ace8a7381..b50b1eb27 100644 --- a/t/lib/proxy-wasm-tests/hostcalls/src/types/test_http.rs +++ b/t/lib/proxy-wasm-tests/hostcalls/src/types/test_http.rs @@ -107,6 +107,12 @@ impl TestHttp { return Action::Pause; } + /* edge case: dispatch + local response */ + "/t/dispatch_and_local_response" => { + self.send_http_dispatch(0); + test_send_status(self, 201) + } + /* shared memory */ "/t/shm/get_shared_data" => test_get_shared_data(self), "/t/shm/set_shared_data" => test_set_shared_data(self),