diff --git a/.github/workflows/commitlint.yml b/.github/workflows/commitlint.yml
deleted file mode 100644
index 0901434386e..00000000000
--- a/.github/workflows/commitlint.yml
+++ /dev/null
@@ -1,12 +0,0 @@
-name: commit-lint
-
-on: [push, pull_request]
-
-jobs:
- lint:
- runs-on: ubuntu-latest
-
- steps:
- - uses: ahmadnassri/action-commit-lint@v2
- with:
- config: conventional
diff --git a/build/dockerfiles/deb.Dockerfile b/build/dockerfiles/deb.Dockerfile
index a55b3706fcf..c25cbadd5d5 100644
--- a/build/dockerfiles/deb.Dockerfile
+++ b/build/dockerfiles/deb.Dockerfile
@@ -20,6 +20,7 @@ COPY ${KONG_ARTIFACT_PATH}${KONG_ARTIFACT} /tmp/kong.deb
RUN apt-get update \
&& apt-get -y upgrade \
&& apt-get -y autoremove \
+ && DEBIAN_FRONTEND=noninteractive apt-get install -y tzdata \
&& apt-get install -y --no-install-recommends /tmp/kong.deb \
&& rm -rf /var/lib/apt/lists/* \
&& rm -rf /tmp/kong.deb \
diff --git a/build/openresty/patches/nginx-1.25.3_03-http_revert_req_body_hardcode_limitation.patch b/build/openresty/patches/nginx-1.25.3_03-http_revert_req_body_hardcode_limitation.patch
new file mode 100644
index 00000000000..00a38352402
--- /dev/null
+++ b/build/openresty/patches/nginx-1.25.3_03-http_revert_req_body_hardcode_limitation.patch
@@ -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, 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 [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 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|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
diff --git a/build/package/nfpm.yaml b/build/package/nfpm.yaml
index 388b7d0be89..2e0bbf0c691 100644
--- a/build/package/nfpm.yaml
+++ b/build/package/nfpm.yaml
@@ -42,6 +42,9 @@ contents:
dst: /lib/systemd/system/kong.service
- src: build/package/kong.logrotate
dst: /etc/kong/kong.logrotate
+ file_info:
+ mode: 0644
+
scripts:
postinstall: ./build/package/postinstall.sh
replaces:
diff --git a/changelog/unreleased/kong/add_tzdata.yml b/changelog/unreleased/kong/add_tzdata.yml
new file mode 100644
index 00000000000..91c8df9c2ad
--- /dev/null
+++ b/changelog/unreleased/kong/add_tzdata.yml
@@ -0,0 +1,3 @@
+message: |
+ Add package `tzdata` to DEB Docker image for convenient timezone setting.
+type: dependency
diff --git a/changelog/unreleased/kong/fix-file-permission-of-logrotate.yml b/changelog/unreleased/kong/fix-file-permission-of-logrotate.yml
new file mode 100644
index 00000000000..2fb24c9e2f5
--- /dev/null
+++ b/changelog/unreleased/kong/fix-file-permission-of-logrotate.yml
@@ -0,0 +1,3 @@
+message: update file permission of kong.logrotate to 644
+type: bugfix
+scope: Core
diff --git a/changelog/unreleased/kong/revert-req-body-limitation-patch.yml b/changelog/unreleased/kong/revert-req-body-limitation-patch.yml
new file mode 100644
index 00000000000..55da8ff9197
--- /dev/null
+++ b/changelog/unreleased/kong/revert-req-body-limitation-patch.yml
@@ -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
diff --git a/kong/router/fields.lua b/kong/router/fields.lua
index 126bbce671f..4294e84b760 100644
--- a/kong/router/fields.lua
+++ b/kong/router/fields.lua
@@ -199,6 +199,11 @@ end -- is_http
-- stream subsystem needs not to generate func
local function get_field_accessor(funcs, field)
+ local f = FIELDS_FUNCS[field]
+ if f then
+ return f
+ end
+
error("unknown router matching schema field: " .. field)
end
@@ -259,7 +264,7 @@ if is_http then
get_field_accessor = function(funcs, field)
- local f = funcs[field]
+ local f = FIELDS_FUNCS[field] or funcs[field]
if f then
return f
end
@@ -447,8 +452,7 @@ end
function _M:get_value(field, params, ctx)
- local func = FIELDS_FUNCS[field] or
- get_field_accessor(self.funcs, field)
+ local func = get_field_accessor(self.funcs, field)
return func(params, ctx)
end
diff --git a/scripts/explain_manifest/explain.py b/scripts/explain_manifest/explain.py
index d9f807b2dc2..1916401024e 100644
--- a/scripts/explain_manifest/explain.py
+++ b/scripts/explain_manifest/explain.py
@@ -64,12 +64,14 @@ def __init__(self, path, relpath):
# use lstat to get the mode, uid, gid of the symlink itself
self.mode = os.lstat(path).st_mode
+ # unix style mode
+ self.file_mode = '0' + oct(self.mode & 0o777)[2:]
self.uid = os.lstat(path).st_uid
self.gid = os.lstat(path).st_gid
if not Path(path).is_symlink():
self.size = os.stat(path).st_size
-
+
self._lazy_evaluate_attrs.update({
"binary_content": lambda: open(path, "rb").read(),
"text_content": lambda: open(path, "rb").read().decode('utf-8'),
@@ -129,7 +131,7 @@ def __init__(self, path, relpath):
binary = lief.parse(path)
if not binary: # not an ELF file, malformed, etc
return
-
+
self.arch = binary.header.machine_type.name
for d in binary.dynamic_entries:
@@ -152,7 +154,7 @@ def __init__(self, path, relpath):
self.version_requirement[f.name] = [LooseVersion(
a.name) for a in f.get_auxiliary_symbols()]
self.version_requirement[f.name].sort()
-
+
self._lazy_evaluate_attrs.update({
"exported_symbols": self.get_exported_symbols,
"imported_symbols": self.get_imported_symbols,
diff --git a/scripts/explain_manifest/suites.py b/scripts/explain_manifest/suites.py
index 89fb06ecfe2..daed3029939 100644
--- a/scripts/explain_manifest/suites.py
+++ b/scripts/explain_manifest/suites.py
@@ -19,6 +19,8 @@ def common_suites(expect, libxcrypt_no_obsolete_api: bool = False):
expect("/etc/kong/kong.logrotate", "includes logrotate config").exists()
+ expect("/etc/kong/kong.logrotate", "logrotate config should have 0644 permissions").file_mode.equals("0644")
+
expect("/usr/local/kong/include/openssl/**.h", "includes OpenSSL headers").exists()
# binary correctness
diff --git a/t/04-patch/02-ngx-read-body-block.t b/t/04-patch/02-ngx-read-body-block.t
new file mode 100644
index 00000000000..a086b125704
--- /dev/null
+++ b/t/04-patch/02-ngx-read-body-block.t
@@ -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]
\ No newline at end of file