From fa7a66e6326891b8d996701bbbd867e059e6c4c0 Mon Sep 17 00:00:00 2001 From: Thibault Charbonnier Date: Tue, 9 Jul 2024 17:35:56 -0700 Subject: [PATCH] fix(proxy-wasm) only inject shim headers after on_response_headers Due to some Nginx internals (some response headers are added after our module is executed but before the response is sent) we inject "shim headers" into the `get_http_response_headers()` API. Some heuristics are used to determine whether or not `Transfer-Encoding`, `Connection`, or other "last minute" headers will be injected or not. The issue is that the heuristics used are only valid during response production and after (e.g. `r->chunked` or `r->headers_out.content_length_n` may only be relevant during response production). If a user uses `get_http_response_headers()` in request phases, the returned headers may include elements that will not actually be included in the response (e.g. `Transfer-Encoding`). We now enforce that shim response headers should only be injected during and after `on_http_response_headers`. --- src/common/proxy_wasm/ngx_proxy_wasm_maps.c | 20 ++++++++++++++++--- .../104-proxy_get_http_response_headers.t | 2 -- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/common/proxy_wasm/ngx_proxy_wasm_maps.c b/src/common/proxy_wasm/ngx_proxy_wasm_maps.c index 7512e0c9d..20c175bea 100644 --- a/src/common/proxy_wasm/ngx_proxy_wasm_maps.c +++ b/src/common/proxy_wasm/ngx_proxy_wasm_maps.c @@ -143,6 +143,8 @@ ngx_proxy_wasm_maps_get_all(ngx_wavm_instance_t *instance, #ifdef NGX_WASM_HTTP ngx_table_elt_t *shim; ngx_array_t *shims; + ngx_proxy_wasm_ctx_t *pwctx; + ngx_proxy_wasm_exec_t *pwexec; #endif list = ngx_proxy_wasm_maps_get_map(instance, map_type); @@ -178,10 +180,22 @@ ngx_proxy_wasm_maps_get_all(ngx_wavm_instance_t *instance, } #ifdef NGX_WASM_HTTP - if (map_type == NGX_PROXY_WASM_MAP_HTTP_RESPONSE_HEADERS) { - /* inject shim response headers - * (produced by ngx_http_header_filter) + pwexec = ngx_proxy_wasm_instance2pwexec(instance); + pwctx = pwexec->parent; + + if (map_type == NGX_PROXY_WASM_MAP_HTTP_RESPONSE_HEADERS + && (pwctx->step == NGX_PROXY_WASM_STEP_RESP_HEADERS + || pwctx->step == NGX_PROXY_WASM_STEP_RESP_BODY + || pwctx->step == NGX_PROXY_WASM_STEP_LOG)) + { + /** + * Inject shim response headers during and after + * on_http_response_headers step as they are produced by + * ngx_http_header_filter. */ + ngx_log_debug0(NGX_LOG_DEBUG_WASM, pwexec->log, 0, + "injecting shim headers in response headers map"); + shims = ngx_http_wasm_get_shim_headers( ngx_http_proxy_wasm_get_rctx(instance)); diff --git a/t/03-proxy_wasm/hfuncs/104-proxy_get_http_response_headers.t b/t/03-proxy_wasm/hfuncs/104-proxy_get_http_response_headers.t index 1b2544faf..4338cc6b0 100644 --- a/t/03-proxy_wasm/hfuncs/104-proxy_get_http_response_headers.t +++ b/t/03-proxy_wasm/hfuncs/104-proxy_get_http_response_headers.t @@ -46,8 +46,6 @@ response --- grep_error_log eval: qr/(testing in|resp) .*/ --- grep_error_log_out eval qr/testing in "RequestHeaders".* -resp Transfer-Encoding: chunked.* -resp Connection: close.* testing in "ResponseHeaders".* resp :status: 200.* resp Content-Type: text\/plain.*