-
Notifications
You must be signed in to change notification settings - Fork 4.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(build): revert OpenResty
ngx.req.read_body()
HTTP/2 chunked enc…
…oding limitation (#12658) Cherry picked from openresty/lua-nginx-module#2286. It was acknowledged by OpenResty as a mistaken breaking change, and we should revert it. FTI-5766 FTI-5795 (cherry picked from commit 55358df)
- Loading branch information
1 parent
46af830
commit 4ab4d67
Showing
3 changed files
with
372 additions
and
0 deletions.
There are no files selected for viewing
320 changes: 320 additions & 0 deletions
320
build/openresty/patches/nginx-1.25.3_03-http_revert_req_body_hardcode_limitation.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,320 @@ | ||
diff --git a/bundle/ngx_lua-0.10.26/README.markdown b/bundle/ngx_lua-0.10.26/README.markdown | ||
index d6ec8c9..02eb9af 100644 | ||
--- a/bundle/ngx_lua-0.10.26/README.markdown | ||
+++ b/bundle/ngx_lua-0.10.26/README.markdown | ||
@@ -2722,8 +2722,6 @@ lua_need_request_body | ||
|
||
**phase:** *depends on usage* | ||
|
||
-Due to the stream processing feature of HTTP/2 or HTTP/3, this configuration could potentially block the entire request. Therefore, this configuration is effective only when HTTP/2 or HTTP/3 requests send content-length header. For requests with versions lower than HTTP/2, this configuration can still be used without any problems. | ||
- | ||
Determines whether to force the request body data to be read before running rewrite/access/content_by_lua* or not. The Nginx core does not read the client request body by default and if request body data is required, then this directive should be turned `on` or the [ngx.req.read_body](#ngxreqread_body) function should be called within the Lua code. | ||
|
||
To read the request body data within the [$request_body](http://nginx.org/en/docs/http/ngx_http_core_module.html#var_request_body) variable, | ||
@@ -5426,8 +5424,6 @@ Reads the client request body synchronously without blocking the Nginx event loo | ||
local args = ngx.req.get_post_args() | ||
``` | ||
|
||
-Due to the stream processing feature of HTTP/2 or HTTP/3, this api could potentially block the entire request. Therefore, this api is effective only when HTTP/2 or HTTP/3 requests send content-length header. For requests with versions lower than HTTP/2, this api can still be used without any problems. | ||
- | ||
If the request body is already read previously by turning on [lua_need_request_body](#lua_need_request_body) or by using other modules, then this function does not run and returns immediately. | ||
|
||
If the request body has already been explicitly discarded, either by the [ngx.req.discard_body](#ngxreqdiscard_body) function or other modules, this function does not run and returns immediately. | ||
@@ -5643,7 +5639,7 @@ Returns a read-only cosocket object that wraps the downstream connection. Only [ | ||
|
||
In case of error, `nil` will be returned as well as a string describing the error. | ||
|
||
-Due to the streaming nature of HTTP2 and HTTP3, this API cannot be used when the downstream connection is HTTP2 and HTTP3. | ||
+**Note:** This method will block while waiting for client request body to be fully received. Block time depends on the [client_body_timeout](http://nginx.org/en/docs/http/ngx_http_core_module.html#client_body_timeout) directive and maximum body size specified by the [client_max_body_size](http://nginx.org/en/docs/http/ngx_http_core_module.html#client_max_body_size) directive. If read timeout occurs or client body size exceeds the defined limit, this function will not return and `408 Request Time-out` or `413 Request Entity Too Large` response will be returned to the client instead. | ||
|
||
The socket object returned by this method is usually used to read the current request's body in a streaming fashion. Do not turn on the [lua_need_request_body](#lua_need_request_body) directive, and do not mix this call with [ngx.req.read_body](#ngxreqread_body) and [ngx.req.discard_body](#ngxreqdiscard_body). | ||
|
||
diff --git a/bundle/ngx_lua-0.10.26/doc/HttpLuaModule.wiki b/bundle/ngx_lua-0.10.26/doc/HttpLuaModule.wiki | ||
index 305626c..0db9dd5 100644 | ||
--- a/bundle/ngx_lua-0.10.26/doc/HttpLuaModule.wiki | ||
+++ b/bundle/ngx_lua-0.10.26/doc/HttpLuaModule.wiki | ||
@@ -4741,8 +4741,7 @@ Returns a read-only cosocket object that wraps the downstream connection. Only [ | ||
|
||
In case of error, <code>nil</code> will be returned as well as a string describing the error. | ||
|
||
-Due to the streaming nature of HTTP2 and HTTP3, this API cannot be used when the downstream connection is HTTP2 and HTTP3. | ||
- | ||
+'''Note:''' This method will block while waiting for client request body to be fully received. Block time depends on the [http://nginx.org/en/docs/http/ngx_http_core_module.html#client_body_timeout client_body_timeout] directive and maximum body size specified by the [http://nginx.org/en/docs/http/ngx_http_core_module.html#client_max_body_size client_max_body_size] directive. If read timeout occurs or client body size exceeds the defined limit, this function will not return and <code>408 Request Time-out</code> or <code>413 Request Entity Too Large</code> response will be returned to the client instead. | ||
The socket object returned by this method is usually used to read the current request's body in a streaming fashion. Do not turn on the [[#lua_need_request_body|lua_need_request_body]] directive, and do not mix this call with [[#ngx.req.read_body|ngx.req.read_body]] and [[#ngx.req.discard_body|ngx.req.discard_body]]. | ||
|
||
If any request body data has been pre-read into the Nginx core request header buffer, the resulting cosocket object will take care of this to avoid potential data loss resulting from such pre-reading. | ||
diff --git a/bundle/ngx_lua-0.10.26/src/ngx_http_lua_accessby.c b/bundle/ngx_lua-0.10.26/src/ngx_http_lua_accessby.c | ||
index 2bf40aa..d40eab1 100644 | ||
--- a/bundle/ngx_lua-0.10.26/src/ngx_http_lua_accessby.c | ||
+++ b/bundle/ngx_lua-0.10.26/src/ngx_http_lua_accessby.c | ||
@@ -137,26 +137,6 @@ ngx_http_lua_access_handler(ngx_http_request_t *r) | ||
} | ||
|
||
if (llcf->force_read_body && !ctx->read_body_done) { | ||
- | ||
-#if (NGX_HTTP_V2) | ||
- if (r->main->stream && r->headers_in.content_length_n < 0) { | ||
- ngx_log_error(NGX_LOG_WARN, r->connection->log, 0, | ||
- "disable lua_need_request_body, since " | ||
- "http2 read_body may break http2 stream process"); | ||
- goto done; | ||
- } | ||
-#endif | ||
- | ||
-#if (NGX_HTTP_V3) | ||
- if (r->http_version == NGX_HTTP_VERSION_30 | ||
- && r->headers_in.content_length_n < 0) | ||
- { | ||
- ngx_log_error(NGX_LOG_WARN, r->connection->log, 0, | ||
- "disable lua_need_request_body, since " | ||
- "http2 read_body may break http2 stream process"); | ||
- goto done; | ||
- } | ||
-#endif | ||
r->request_body_in_single_buf = 1; | ||
r->request_body_in_persistent_file = 1; | ||
r->request_body_in_clean_file = 1; | ||
@@ -174,12 +154,6 @@ ngx_http_lua_access_handler(ngx_http_request_t *r) | ||
} | ||
} | ||
|
||
-#if defined(NGX_HTTP_V3) || defined(NGX_HTTP_V2) | ||
- | ||
-done: | ||
- | ||
-#endif | ||
- | ||
dd("calling access handler"); | ||
return llcf->access_handler(r); | ||
} | ||
diff --git a/bundle/ngx_lua-0.10.26/src/ngx_http_lua_contentby.c b/bundle/ngx_lua-0.10.26/src/ngx_http_lua_contentby.c | ||
index 2014d52..5e2ae55 100644 | ||
--- a/bundle/ngx_lua-0.10.26/src/ngx_http_lua_contentby.c | ||
+++ b/bundle/ngx_lua-0.10.26/src/ngx_http_lua_contentby.c | ||
@@ -196,26 +196,6 @@ ngx_http_lua_content_handler(ngx_http_request_t *r) | ||
} | ||
|
||
if (llcf->force_read_body && !ctx->read_body_done) { | ||
- | ||
-#if (NGX_HTTP_V2) | ||
- if (r->main->stream && r->headers_in.content_length_n < 0) { | ||
- ngx_log_error(NGX_LOG_WARN, r->connection->log, 0, | ||
- "disable lua_need_request_body, since " | ||
- "http2 read_body may break http2 stream process"); | ||
- goto done; | ||
- } | ||
-#endif | ||
- | ||
-#if (NGX_HTTP_V3) | ||
- if (r->http_version == NGX_HTTP_VERSION_30 | ||
- && r->headers_in.content_length_n < 0) | ||
- { | ||
- ngx_log_error(NGX_LOG_WARN, r->connection->log, 0, | ||
- "disable lua_need_request_body, since " | ||
- "http2 read_body may break http2 stream process"); | ||
- goto done; | ||
- } | ||
-#endif | ||
r->request_body_in_single_buf = 1; | ||
r->request_body_in_persistent_file = 1; | ||
r->request_body_in_clean_file = 1; | ||
@@ -234,12 +214,6 @@ ngx_http_lua_content_handler(ngx_http_request_t *r) | ||
} | ||
} | ||
|
||
-#if defined(NGX_HTTP_V3) || defined(NGX_HTTP_V2) | ||
- | ||
-done: | ||
- | ||
-#endif | ||
- | ||
dd("setting entered"); | ||
|
||
ctx->entered_content_phase = 1; | ||
diff --git a/bundle/ngx_lua-0.10.26/src/ngx_http_lua_req_body.c b/bundle/ngx_lua-0.10.26/src/ngx_http_lua_req_body.c | ||
index 61ab999..5d69735 100644 | ||
--- a/bundle/ngx_lua-0.10.26/src/ngx_http_lua_req_body.c | ||
+++ b/bundle/ngx_lua-0.10.26/src/ngx_http_lua_req_body.c | ||
@@ -85,23 +85,6 @@ ngx_http_lua_ngx_req_read_body(lua_State *L) | ||
return luaL_error(L, "request object not found"); | ||
} | ||
|
||
-/* http2 read body may break http2 stream process */ | ||
-#if (NGX_HTTP_V2) | ||
- if (r->main->stream && r->headers_in.content_length_n < 0) { | ||
- return luaL_error(L, "http2 requests are not supported" | ||
- " without content-length header"); | ||
- } | ||
-#endif | ||
- | ||
-#if (NGX_HTTP_V3) | ||
- if (r->http_version == NGX_HTTP_VERSION_30 | ||
- && r->headers_in.content_length_n < 0) | ||
- { | ||
- return luaL_error(L, "http3 requests are not supported" | ||
- " without content-length header"); | ||
- } | ||
-#endif | ||
- | ||
r->request_body_in_single_buf = 1; | ||
r->request_body_in_persistent_file = 1; | ||
r->request_body_in_clean_file = 1; | ||
@@ -349,23 +332,6 @@ ngx_http_lua_ngx_req_get_body_file(lua_State *L) | ||
return luaL_error(L, "request object not found"); | ||
} | ||
|
||
-/* http2 read body may break http2 stream process */ | ||
-#if (NGX_HTTP_V2) | ||
- if (r->main->stream && r->headers_in.content_length_n < 0) { | ||
- return luaL_error(L, "http2 requests are not supported" | ||
- " without content-length header"); | ||
- } | ||
-#endif | ||
- | ||
-#if (NGX_HTTP_V3) | ||
- if (r->http_version == NGX_HTTP_VERSION_30 | ||
- && r->headers_in.content_length_n < 0) | ||
- { | ||
- return luaL_error(L, "http3 requests are not supported" | ||
- " without content-length header"); | ||
- } | ||
-#endif | ||
- | ||
ngx_http_lua_check_fake_request(L, r); | ||
|
||
if (r->request_body == NULL || r->request_body->temp_file == NULL) { | ||
diff --git a/bundle/ngx_lua-0.10.26/src/ngx_http_lua_rewriteby.c b/bundle/ngx_lua-0.10.26/src/ngx_http_lua_rewriteby.c | ||
index c56bba5..4109f28 100644 | ||
--- a/bundle/ngx_lua-0.10.26/src/ngx_http_lua_rewriteby.c | ||
+++ b/bundle/ngx_lua-0.10.26/src/ngx_http_lua_rewriteby.c | ||
@@ -140,12 +140,7 @@ ngx_http_lua_rewrite_handler(ngx_http_request_t *r) | ||
return NGX_DONE; | ||
} | ||
|
||
-/* http2 read body may break http2 stream process */ | ||
-#if (NGX_HTTP_V2) | ||
- if (llcf->force_read_body && !ctx->read_body_done && !r->main->stream) { | ||
-#else | ||
if (llcf->force_read_body && !ctx->read_body_done) { | ||
-#endif | ||
r->request_body_in_single_buf = 1; | ||
r->request_body_in_persistent_file = 1; | ||
r->request_body_in_clean_file = 1; | ||
diff --git a/bundle/ngx_lua-0.10.26/src/ngx_http_lua_server_rewriteby.c b/bundle/ngx_lua-0.10.26/src/ngx_http_lua_server_rewriteby.c | ||
index 997262e..be86069 100644 | ||
--- a/bundle/ngx_lua-0.10.26/src/ngx_http_lua_server_rewriteby.c | ||
+++ b/bundle/ngx_lua-0.10.26/src/ngx_http_lua_server_rewriteby.c | ||
@@ -102,13 +102,8 @@ ngx_http_lua_server_rewrite_handler(ngx_http_request_t *r) | ||
return NGX_DONE; | ||
} | ||
|
||
-/* TODO: lscf do not have force_read_body | ||
- * http2 read body may break http2 stream process */ | ||
-#if (NGX_HTTP_V2) | ||
- if (llcf->force_read_body && !ctx->read_body_done && !r->main->stream) { | ||
-#else | ||
+ /* TODO: lscf do not have force_read_body */ | ||
if (llcf->force_read_body && !ctx->read_body_done) { | ||
-#endif | ||
r->request_body_in_single_buf = 1; | ||
r->request_body_in_persistent_file = 1; | ||
r->request_body_in_clean_file = 1; | ||
diff --git a/bundle/ngx_lua-0.10.26/t/023-rewrite/request_body.t b/bundle/ngx_lua-0.10.26/t/023-rewrite/request_body.t | ||
index 32c02e1..b867d3a 100644 | ||
--- a/bundle/ngx_lua-0.10.26/t/023-rewrite/request_body.t | ||
+++ b/bundle/ngx_lua-0.10.26/t/023-rewrite/request_body.t | ||
@@ -170,26 +170,3 @@ Expect: 100-Continue | ||
http finalize request: 500, "/echo_body?" a:1, c:2 | ||
http finalize request: 500, "/echo_body?" a:1, c:0 | ||
--- log_level: debug | ||
---- skip_eval: 4:$ENV{TEST_NGINX_USE_HTTP3} | ||
- | ||
- | ||
- | ||
-=== TEST 9: test HTTP2 reading request body was disabled | ||
---- config | ||
- location /echo_body { | ||
- lua_need_request_body on; | ||
- rewrite_by_lua_block { | ||
- ngx.print(ngx.var.request_body or "nil") | ||
- } | ||
- content_by_lua 'ngx.exit(ngx.OK)'; | ||
- } | ||
---- http2 | ||
---- request eval | ||
-"POST /echo_body | ||
-hello\x00\x01\x02 | ||
-world\x03\x04\xff" | ||
---- more_headers | ||
-Content-Length: | ||
---- response_body eval | ||
-"nil" | ||
---- no_error_log | ||
diff --git a/bundle/ngx_lua-0.10.26/t/024-access/request_body.t b/bundle/ngx_lua-0.10.26/t/024-access/request_body.t | ||
index 0aa12c8..fa03195 100644 | ||
--- a/bundle/ngx_lua-0.10.26/t/024-access/request_body.t | ||
+++ b/bundle/ngx_lua-0.10.26/t/024-access/request_body.t | ||
@@ -170,26 +170,3 @@ Expect: 100-Continue | ||
http finalize request: 500, "/echo_body?" a:1, c:2 | ||
http finalize request: 500, "/echo_body?" a:1, c:0 | ||
--- log_level: debug | ||
---- skip_eval: 4:$ENV{TEST_NGINX_USE_HTTP3} | ||
- | ||
- | ||
- | ||
-=== TEST 9: test HTTP2 reading request body was disabled | ||
---- config | ||
- location /echo_body { | ||
- lua_need_request_body on; | ||
- access_by_lua_block { | ||
- ngx.print(ngx.var.request_body or "nil") | ||
- } | ||
- content_by_lua 'ngx.exit(ngx.OK)'; | ||
- } | ||
---- http2 | ||
---- request eval | ||
-"POST /echo_body | ||
-hello\x00\x01\x02 | ||
-world\x03\x04\xff" | ||
---- more_headers | ||
-Content-Length: | ||
---- response_body eval | ||
-"nil" | ||
---- no_error_log | ||
diff --git a/bundle/ngx_lua-0.10.26/t/044-req-body.t b/bundle/ngx_lua-0.10.26/t/044-req-body.t | ||
index f4509e1..da3a28b 100644 | ||
--- a/bundle/ngx_lua-0.10.26/t/044-req-body.t | ||
+++ b/bundle/ngx_lua-0.10.26/t/044-req-body.t | ||
@@ -7,7 +7,7 @@ log_level('warn'); | ||
|
||
repeat_each(2); | ||
|
||
-plan tests => repeat_each() * (blocks() * 4 + 56); | ||
+plan tests => repeat_each() * (blocks() * 4 + 58 ); | ||
|
||
#no_diff(); | ||
no_long_string(); | ||
@@ -1774,23 +1774,3 @@ content length: 5 | ||
--- no_error_log | ||
[error] | ||
[alert] | ||
---- skip_eval: 4:$ENV{TEST_NGINX_USE_HTTP3} | ||
- | ||
- | ||
- | ||
-=== TEST 53: HTTP2 read buffered body was discarded | ||
---- config | ||
- location = /test { | ||
- content_by_lua_block { | ||
- local err = pcall(ngx.req.read_body()) | ||
- ngx.say(err) | ||
- } | ||
- } | ||
---- http2 | ||
---- request | ||
-POST /test | ||
-hello, world | ||
---- more_headers | ||
-Content-Length: | ||
---- error_code: 500 | ||
---- error_log: http2 requests are not supported without content-length header |
3 changes: 3 additions & 0 deletions
3
changelog/unreleased/kong/revert-req-body-limitation-patch.yml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
message: revert the hard-coded limitation of the ngx.read_body() API in OpenResty upstreams' new versions when downstream connections are in HTTP/2 or HTTP/3 stream modes. | ||
type: bugfix | ||
scope: Core |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
# vim:set ft= ts=4 sw=4 et fdm=marker: | ||
|
||
use Test::Nginx::Socket 'no_plan'; | ||
|
||
repeat_each(2); | ||
|
||
run_tests(); | ||
|
||
__DATA__ | ||
|
||
=== TEST 1: ngx.req.read_body() should work for HTTP2 GET requests that doesn't carry the content-length header | ||
--- config | ||
location = /test { | ||
content_by_lua_block { | ||
local ok, err = pcall(ngx.req.read_body) | ||
ngx.say(ok, " err: ", err) | ||
} | ||
} | ||
--- http2 | ||
--- request | ||
GET /test | ||
hello, world | ||
--- more_headers | ||
Content-Length: | ||
--- response_body | ||
true err: nil | ||
--- no_error_log | ||
[error] | ||
[alert] | ||
|
||
=== TEST 2: ngx.req.read_body() should work for HTTP2 POST requests that doesn't carry the content-length header | ||
--- config | ||
location = /test { | ||
content_by_lua_block { | ||
local ok, err = pcall(ngx.req.read_body) | ||
ngx.say(ok, " err: ", err) | ||
} | ||
} | ||
--- http2 | ||
--- request | ||
POST /test | ||
hello, world | ||
--- more_headers | ||
Content-Length: | ||
--- response_body | ||
true err: nil | ||
--- no_error_log | ||
[error] | ||
[alert] |