From 9b57205e83cc98524822677d22fb7e37e7f8b5c9 Mon Sep 17 00:00:00 2001 From: spacewander Date: Mon, 10 Jan 2022 19:25:08 +0800 Subject: [PATCH] feat: set proxy_request_buffering --- lib/resty/apisix/client.lua | 14 +++ .../nginx-proxy_request_buffering.patch | 26 ++++++ src/ngx_http_apisix_module.c | 33 +++++++ src/ngx_http_apisix_module.h | 4 + t/proxy_request_buffering.t | 85 +++++++++++++++++++ 5 files changed, 162 insertions(+) create mode 100644 patch/1.19.9/nginx-proxy_request_buffering.patch create mode 100644 t/proxy_request_buffering.t diff --git a/lib/resty/apisix/client.lua b/lib/resty/apisix/client.lua index 910334d..d6231d2 100644 --- a/lib/resty/apisix/client.lua +++ b/lib/resty/apisix/client.lua @@ -23,6 +23,9 @@ ngx_http_apisix_enable_mirror(ngx_http_request_t *r); ngx_int_t ngx_http_apisix_set_real_ip(ngx_http_request_t *r, const u_char *text, size_t len, unsigned int port); + +ngx_int_t +ngx_http_apisix_set_proxy_request_buffering(ngx_http_request_t *r, int on); ]]) local _M = {} @@ -65,4 +68,15 @@ function _M.set_real_ip(ip, port) end +function _M.set_proxy_request_buffering(on) + local r = get_request() + local ret = C.ngx_http_apisix_set_proxy_request_buffering(r, on and 1 or 0) + if ret == NGX_ERROR then + return nil, "error while setting proxy_request_buffering" + end + + return true +end + + return _M diff --git a/patch/1.19.9/nginx-proxy_request_buffering.patch b/patch/1.19.9/nginx-proxy_request_buffering.patch new file mode 100644 index 0000000..f103407 --- /dev/null +++ b/patch/1.19.9/nginx-proxy_request_buffering.patch @@ -0,0 +1,26 @@ +diff --git src/http/modules/ngx_http_proxy_module.c src/http/modules/ngx_http_proxy_module.c +index 3f05235..41c2313 100644 +--- src/http/modules/ngx_http_proxy_module.c ++++ src/http/modules/ngx_http_proxy_module.c +@@ -8,6 +8,9 @@ + #include + #include + #include ++#if (NGX_HTTP_APISIX) ++#include "ngx_http_apisix_module.h" ++#endif + + + #define NGX_HTTP_PROXY_COOKIE_SECURE 0x0001 +@@ -1013,7 +1016,11 @@ ngx_http_proxy_handler(ngx_http_request_t *r) + + u->accel = 1; + ++#if (NGX_HTTP_APISIX) ++ if (!ngx_http_apisix_is_request_buffering(r, plcf->upstream.request_buffering) ++#else + if (!plcf->upstream.request_buffering ++#endif + && plcf->body_values == NULL && plcf->upstream.pass_request_body + && (!r->headers_in.chunked + || plcf->http_version == NGX_HTTP_VERSION_11)) diff --git a/src/ngx_http_apisix_module.c b/src/ngx_http_apisix_module.c index 5cb0cd4..73ed1b7 100644 --- a/src/ngx_http_apisix_module.c +++ b/src/ngx_http_apisix_module.c @@ -498,3 +498,36 @@ ngx_http_apisix_is_mirror_enabled(ngx_http_request_t *r) ctx = ngx_http_apisix_get_module_ctx(r); return ctx != NULL && ctx->mirror_enabled; } + + +ngx_int_t +ngx_http_apisix_set_proxy_request_buffering(ngx_http_request_t *r, int on) +{ + ngx_http_apisix_ctx_t *ctx; + + ctx = ngx_http_apisix_get_module_ctx(r); + + if (ctx == NULL) { + return NGX_ERROR; + } + + ctx->request_buffering = on; + ctx->request_buffering_set = 1; + return NGX_OK; +} + + +ngx_int_t +ngx_http_apisix_is_request_buffering(ngx_http_request_t *r, ngx_flag_t static_conf) +{ + ngx_http_apisix_ctx_t *ctx; + + ctx = ngx_http_apisix_get_module_ctx(r); + + if (ctx != NULL && ctx->request_buffering_set) { + return ctx->request_buffering; + } + + /* use the static conf if we haven't changed it dynamically */ + return static_conf; +} diff --git a/src/ngx_http_apisix_module.h b/src/ngx_http_apisix_module.h index 9b2e3dc..be89ddd 100644 --- a/src/ngx_http_apisix_module.h +++ b/src/ngx_http_apisix_module.h @@ -27,6 +27,8 @@ typedef struct { unsigned client_max_body_size_set:1; unsigned mirror_enabled:1; + unsigned request_buffering:1; + unsigned request_buffering_set:1; } ngx_http_apisix_ctx_t; @@ -43,4 +45,6 @@ ngx_int_t ngx_http_apisix_get_gzip_compress_level(ngx_http_request_t *r); ngx_int_t ngx_http_apisix_is_mirror_enabled(ngx_http_request_t *r); +ngx_int_t ngx_http_apisix_is_request_buffering(ngx_http_request_t *r, ngx_flag_t static_conf); + #endif /* _NGX_HTTP_APISIX_H_INCLUDED_ */ diff --git a/t/proxy_request_buffering.t b/t/proxy_request_buffering.t new file mode 100644 index 0000000..cc87f0a --- /dev/null +++ b/t/proxy_request_buffering.t @@ -0,0 +1,85 @@ +use t::APISIX_NGINX 'no_plan'; + +run_tests; + +__DATA__ + +=== TEST 1: proxy_request_buffering off +--- config + proxy_request_buffering off; + location /t { + proxy_pass http://127.0.0.1:1984/up; + } + location /up { + return 200; + } +--- request eval +"POST /t +" . "12345" x 10240 +--- grep_error_log eval +qr/a client request body is buffered to a temporary file/ +--- grep_error_log_out + + + +=== TEST 2: proxy_request_buffering off by Lua API +--- config + proxy_request_buffering on; + location /t { + access_by_lua_block { + local client = require("resty.apisix.client") + assert(client.set_proxy_request_buffering(false)) + } + proxy_pass http://127.0.0.1:1984/up; + } + location /up { + return 200; + } +--- request eval +"POST /t +" . "12345" x 10240 +--- grep_error_log eval +qr/a client request body is buffered to a temporary file/ +--- grep_error_log_out + + + +=== TEST 3: proxy_request_buffering on +--- config + proxy_request_buffering on; + location /t { + proxy_pass http://127.0.0.1:1984/up; + } + location /up { + return 200; + } +--- request eval +"POST /t +" . "12345" x 10240 +--- grep_error_log eval +qr/a client request body is buffered to a temporary file/ +--- grep_error_log_out +a client request body is buffered to a temporary file + + + +=== TEST 4: proxy_request_buffering on by Lua API +--- config + proxy_request_buffering off; + location /t { + access_by_lua_block { + local client = require("resty.apisix.client") + assert(client.set_proxy_request_buffering(true)) + } + proxy_pass http://127.0.0.1:1984/up; + } + location /up { + return 200; + } +--- request eval +"POST /t +" . "12345" x 10240 +--- grep_error_log eval +qr/a client request body is buffered to a temporary file/ +--- grep_error_log_out +a client request body is buffered to a temporary file