aboutsummaryrefslogtreecommitdiffstats
path: root/main/nginx
diff options
context:
space:
mode:
Diffstat (limited to 'main/nginx')
-rw-r--r--main/nginx/APKBUILD175
-rw-r--r--main/nginx/CVE-2023-44487.patch71
-rw-r--r--main/nginx/naxsi~assert.patch23
-rw-r--r--main/nginx/naxsi~compat.patch133
-rw-r--r--main/nginx/naxsi~ff-header.patch62
-rw-r--r--main/nginx/nchan~dont-fail-redis-cluster-before-consensus.patch49
-rw-r--r--main/nginx/nchan~fix-redis-race-condition.patch270
-rw-r--r--main/nginx/nginx-module-vts~cast-key-length-to-correct-type.patch24
-rw-r--r--main/nginx/nginx-module-vts~fix-uri-overflow.patch30
-rw-r--r--main/nginx/nginx-module-vts~set-histogram-buckets-on-first-request.patch147
-rw-r--r--main/nginx/nginx-upload-module~fix-nginx-compat.patch40
-rw-r--r--main/nginx/nginx-upload-module~fixes.patch620
-rw-r--r--main/nginx/nginx-upload-progress-module~fix-http2.patch44
-rw-r--r--main/nginx/nginx-upload-progress-module~fix.patch937
-rw-r--r--main/nginx/nginx.conf10
-rw-r--r--main/nginx/nginx.post-upgrade47
-rw-r--r--main/nginx/ngx-fancyindex~fix-404-on-fs-root.patch27
-rw-r--r--main/nginx/ngx-fancyindex~fix-missing-saturday.patch25
-rw-r--r--main/nginx/njs~nginx-1.20.x-compat.patch15
-rw-r--r--main/nginx/no-werror.patch11
-rw-r--r--main/nginx/stream.conf2
-rw-r--r--main/nginx/traffic-accounting-nginx-module~fix-memory-leak.patch253
-rw-r--r--main/nginx/zstd-nginx-module~fix-infinite-loop.patch47
23 files changed, 2741 insertions, 321 deletions
diff --git a/main/nginx/APKBUILD b/main/nginx/APKBUILD
index 0160d648472..d6240bc1499 100644
--- a/main/nginx/APKBUILD
+++ b/main/nginx/APKBUILD
@@ -4,6 +4,11 @@
# Contributor: Jakub Jirutka <jakub@jirutka.cz>
#
# secfixes:
+# 1.24.0-r12:
+# - CVE-2023-44487
+# 1.22.1-r0:
+# - CVE-2022-41741
+# - CVE-2022-41742
# 1.20.2-r2:
# - CVE-2021-46461
# - CVE-2021-46462
@@ -25,24 +30,30 @@
# - CVE-2018-16845
# 1.12.1-r0:
# - CVE-2017-7529
+# 0:
+# - CVE-2022-3638
#
pkgname=nginx
# NOTE: Upgrade only to even-numbered versions (e.g. 1.14.z, 1.16.z)!
# Odd-numbered versions are mainline (development) versions.
-pkgver=1.22.0
-pkgrel=6
+pkgver=1.24.0
+pkgrel=18
# Revision of nginx-tests to use for check().
-_tests_hgrev=bd21a4a7c9f5
-_njs_ver=0.7.6
+_tests_hgrev=22f45bf99a9e
+_njs_ver=0.8.3
+# if this isn't set higher than testing/openresty that comes first for some reason
+# even though this has a higher version..
+provider_priority=100
pkgdesc="HTTP and reverse proxy server (stable version)"
url="https://www.nginx.org/"
arch="all"
license="BSD-2-Clause"
-depends=""
makedepends="
brotli-dev
gd-dev
geoip-dev
+ hiredis-dev
+ jansson-dev
libmaxminddb-dev
libxml2-dev
libxslt-dev
@@ -53,6 +64,8 @@ makedepends="
pkgconf
zeromq-dev
zlib-dev
+ zstd-dev
+ !zstd-static
"
checkdepends="
gd
@@ -70,23 +83,29 @@ _grp_www="www-data"
pkggroups="$_grp_ngx $_grp_www"
install="$pkgname.pre-install $pkgname.post-install $pkgname.pre-upgrade $pkgname.post-upgrade"
subpackages="$pkgname-debug $pkgname-doc $pkgname-openrc $pkgname-vim::noarch"
-source="https://nginx.org/download/$pkgname-$pkgver.tar.gz
+source="https://nginx.org/download/nginx-$pkgver.tar.gz
+ CVE-2023-44487.patch
$pkgname-tests-$_tests_hgrev.tar.gz::https://hg.nginx.org/nginx-tests/archive/$_tests_hgrev.tar.gz
$pkgname-njs-$_njs_ver.tar.gz::https://hg.nginx.org/njs/archive/$_njs_ver.tar.gz
nginx-dav-ext-module~pr-56.patch::https://github.com/arut/nginx-dav-ext-module/pull/56.patch
nginx-dav-ext-module~pr-62.patch::https://github.com/arut/nginx-dav-ext-module/commit/bbf93f75ca58657fb0f8376b0898f854f13cef91.patch
- nginx-module-vts~01-938c19d.patch::https://github.com/vozlt/nginx-module-vts/commit/938c19d2e49d5f3355df5375725982d15f1270c4.patch
- nginx-module-vts~02-ad40022.patch::https://github.com/vozlt/nginx-module-vts/commit/ad4002262c19e81390f518a14f99bb594862c575.patch
- nginx-module-vts~03-c08781c.patch::https://github.com/vozlt/nginx-module-vts/commit/c08781c5095d9e6090c47176bdea322ce983ecb6.patch
- nginx-module-vts~04-1a01a87.patch::https://github.com/vozlt/nginx-module-vts/commit/1a01a87e66c9f111fb399cf40def33ab193ae393.patch
- nginx-module-vts~05-ead62a0.patch::https://github.com/vozlt/nginx-module-vts/commit/ead62a0caf405731c88ac138c4c0a82bb316cc18.patch
- nginx-module-vts~fix-uri-overflow.patch
- nginx-module-vts~cast-key-length-to-correct-type.patch
- nginx-module-vts~set-histogram-buckets-on-first-request.patch
+ no-werror.patch
traffic-accounting-nginx-module~disable-stream-module.patch
+ traffic-accounting-nginx-module~fix-memory-leak.patch
nginx_cookie_flag_module~fix-mem-allocations.patch
njs~mktemp-busybox-compat.patch
- njs~nginx-1.20.x-compat.patch
+ naxsi~assert.patch
+ naxsi~ff-header.patch
+ naxsi~compat.patch
+ nginx-upload-progress-module~fix.patch
+ nginx-upload-progress-module~fix-http2.patch
+ ngx-fancyindex~fix-404-on-fs-root.patch
+ ngx-fancyindex~fix-missing-saturday.patch
+ nchan~dont-fail-redis-cluster-before-consensus.patch
+ nchan~fix-redis-race-condition.patch
+ nginx-upload-module~fixes.patch
+ nginx-upload-module~fix-nginx-compat.patch
+ zstd-nginx-module~fix-infinite-loop.patch
nginx.conf
default.conf
stream.conf
@@ -94,13 +113,12 @@ source="https://nginx.org/download/$pkgname-$pkgver.tar.gz
$pkgname.initd
$pkgname.confd
"
-builddir="$srcdir/$pkgname-$pkgver"
_modules_dir="usr/lib/$pkgname/modules"
_stream_js_depends="$pkgname-mod-stream"
case "$CARCH" in
- riscv64) _has_luajit=false;;
+ ppc64le|riscv64) _has_luajit=false;;
*) _has_luajit=true; makedepends="$makedepends luajit-dev";;
esac
@@ -152,25 +170,28 @@ _add_module() {
subpackages="$subpackages $pkgname-mod-$name:_module"
}
-_add_module "devel-kit" "v0.3.1" "https://github.com/vision5/ngx_devel_kit"
+_add_module "devel-kit" "v0.3.3" "https://github.com/vision5/ngx_devel_kit"
_devel_kit_so="ndk_http_module.so"
_add_module "http-accounting" "v2.0" "https://github.com/Lax/traffic-accounting-nginx-module"
-_add_module "http-array-var" "v0.05" "https://github.com/openresty/array-var-nginx-module"
+_add_module "http-array-var" "v0.06" "https://github.com/openresty/array-var-nginx-module"
_http_array_var_depends="$pkgname-mod-devel-kit"
+_add_module "http-auth-jwt" "0.6.0" "https://github.com/kjdev/nginx-auth-jwt"
+_http_auth_jwt_desc="Nginx third-party module kjdev/nginx-auth-jwt (version $_http_auth_jwt_ver)"
+
_add_module "http-brotli" "v1.0.0rc" "https://github.com/google/ngx_brotli"
_http_brotli_so="ngx_http_brotli_filter_module.so ngx_http_brotli_static_module.so"
-_add_module "http-cache-purge" "2.5.2" "https://github.com/nginx-modules/ngx_cache_purge"
+_add_module "http-cache-purge" "2.5.3" "https://github.com/nginx-modules/ngx_cache_purge"
_add_module "http-cookie-flag" "v1.1.0" "https://github.com/AirisX/nginx_cookie_flag_module"
_http_cookie_flag_so="ngx_http_cookie_flag_filter_module.so"
_add_module "http-dav-ext" "v3.0.0" "https://github.com/arut/nginx-dav-ext-module"
-_add_module "http-echo" "v0.62" "https://github.com/openresty/echo-nginx-module"
+_add_module "http-echo" "v0.63" "https://github.com/openresty/echo-nginx-module"
_add_module "http-encrypted-session" "v0.09" "https://github.com/openresty/encrypted-session-nginx-module"
_http_encrypted_session_depends="$pkgname-mod-devel-kit"
@@ -181,13 +202,15 @@ _add_module "http-geoip2" "3.4" "https://github.com/leev/ngx_http_geoip2_module"
_add_module "stream-geoip2" "3.4" "https://github.com/leev/ngx_http_geoip2_module"
_stream_geoip2_depends="$pkgname-mod-stream"
-_add_module "http-headers-more" "v0.33" "https://github.com/openresty/headers-more-nginx-module"
+_add_module "http-headers-more" "v0.37" "https://github.com/openresty/headers-more-nginx-module"
_http_headers_more_so="ngx_http_headers_more_filter_module.so"
+_add_module "http-keyval" "0.2.0" "https://github.com/kjdev/nginx-keyval"
+
_add_module "http-log-zmq" "v1.0.0" "https://github.com/danifbento/nginx-log-zmq"
# luajit is required for lua-nginx-module since v0.10.14
-_add_module "http-lua" "v0.10.21" "https://github.com/openresty/lua-nginx-module" "" "$_has_luajit"
+_add_module "http-lua" "v0.10.26" "https://github.com/openresty/lua-nginx-module" "" "$_has_luajit"
_http_lua_depends="$pkgname-mod-devel-kit lua-resty-core"
_http_lua_provides="$pkgname-lua" # for backward compatibility
@@ -197,7 +220,7 @@ _http_lua_upstream_depends="$pkgname-mod-http-lua"
_add_module "http-naxsi" "1.3" "https://github.com/nbs-system/naxsi" "naxsi_src"
_naxsi_provides="$pkgname-naxsi" # for backward compatibility
-_add_module "http-nchan" "v1.3.0" "https://github.com/slact/nchan"
+_add_module "http-nchan" "v1.3.6" "https://github.com/slact/nchan"
_http_nchan_so="ngx_nchan_module.so"
_add_module "http-redis2" "v0.15" "https://github.com/openresty/redis2-nginx-module"
@@ -205,7 +228,7 @@ _add_module "http-redis2" "v0.15" "https://github.com/openresty/redis2-nginx-mod
_add_module "http-set-misc" "v0.33" "https://github.com/openresty/set-misc-nginx-module"
_http_set_misc_depends="$pkgname-mod-devel-kit"
-_add_module "http-shibboleth" "v2.0.1" "https://github.com/nginx-shib/nginx-http-shibboleth"
+_add_module "http-shibboleth" "v2.0.2" "https://github.com/nginx-shib/nginx-http-shibboleth"
_add_module "http-untar" "v1.1" "https://github.com/ajax16384/ngx_http_untar_module"
@@ -216,19 +239,21 @@ _http_upload_progress_so="ngx_http_uploadprogress_module.so"
_add_module "http-upstream-fair" "0.1.3" "https://github.com/itoffshore/nginx-upstream-fair"
-_add_module "http-upstream-jdomain" "1.4.0" "https://github.com/nicholaschiasson/ngx_upstream_jdomain"
+_add_module "http-upstream-jdomain" "1.5.0" "https://github.com/nicholaschiasson/ngx_upstream_jdomain"
-_add_module "http-vod" "1.29" "https://github.com/kaltura/nginx-vod-module"
+_add_module "http-vod" "1.33" "https://github.com/kaltura/nginx-vod-module"
-_add_module "http-vts" "v0.1.18" "https://github.com/vozlt/nginx-module-vts"
+_add_module "http-vts" "v0.2.2" "https://github.com/vozlt/nginx-module-vts"
_http_vts_so="ngx_http_vhost_traffic_status_module.so"
-_add_module "http-zip" "1.2.0" "https://github.com/evanmiller/mod_zip"
+_add_module "http-zip" "1.3.0" "https://github.com/evanmiller/mod_zip"
+
+_add_module "http-zstd" "0.1.1" "https://github.com/tokers/zstd-nginx-module"
+_http_zstd_so="ngx_http_zstd_filter_module.so ngx_http_zstd_static_module.so"
_add_module "rtmp" "v1.2.2" "https://github.com/arut/nginx-rtmp-module"
_rtmp_provides="$pkgname-rtmp" # for backward compatibility
-
prepare() {
local file; for file in $source; do
file=${file%%::*}
@@ -260,6 +285,14 @@ _build() {
export LUAJIT_INC="$(pkgconf --variable=includedir luajit)"
fi
+ # Fix compilation with gcc 13.1.
+ # TODO: Remove after upgrade to njs 0.7.13.
+ # https://github.com/nginx/njs/commit/e60d10f2007c332391d7a104453e13567ebbe52d
+ export NJS_CFLAGS="-Wno-error=dangling-pointer"
+
+ # Enable support for Redis store in the http-keyval module.
+ export NGX_HTTP_KEYVAL_ZONE_REDIS=1
+
# --without-pcre2 - Lua module is not compatible with PCRE2 yet
# https://github.com/openresty/lua-nginx-module/issues/1984
./configure \
@@ -319,8 +352,6 @@ _build() {
}
build() {
- cd "$builddir"
-
_build --with-debug
mv objs objs-debug
@@ -339,18 +370,18 @@ check() {
;;
esac
- TEST_NGINX_BINARY="$builddir/objs/nginx" prove .
+ : ${JOBS:-1}
+ TEST_NGINX_BINARY="$builddir/objs/nginx" prove -j $((JOBS > 20 ? 20 : JOBS)) .
- if [ -n "$_njs_mods" ]; then
- msg "Running njs tests..."
- cd "$srcdir"/njs-*
- make test
- fi
+ # FIXME: see !46437
+ #if [ -n "$_njs_mods" ]; then
+ # msg "Running njs tests..."
+ # cd "$srcdir"/njs-*
+ # make test
+ #fi
}
package() {
- cd "$builddir"
-
make DESTDIR="$pkgdir" install
chown root:root "$pkgdir"/usr/sbin/nginx
@@ -420,6 +451,7 @@ _module() {
pkgdesc="Nginx module ${name//_/-}"
[ "$ver" ] && pkgdesc="Nginx third-party module ${name//_/-} (version $ver)"
+ pkgdesc="$(getvar "_${name}_desc" "$pkgdesc")"
url=$(getvar "_${name}_url" "$url")
sonames=$(getvar "_${name}_so" "ngx_${name}_module.so")
depends="$pkgname $(getvar "_${name}_depends")"
@@ -452,7 +484,7 @@ _module() {
;;
stream)
mkdir -p ./etc/nginx/stream.d
- install -m644 "$srcdir"/stream.conf ./etc/nginx/stream.conf
+ install -m644 -D "$srcdir"/stream.conf ./etc/nginx/conf.d/stream.conf
;;
esac
}
@@ -463,56 +495,65 @@ getvar() {
}
sha512sums="
-074782dba9cd5f8f493fbb57e20bda6dc9171814d919a47ee9f825d93f12c9f9d496e25d063c983191b55ad6a236bcef252ce16ecc1d253dc8b23433557559b1 nginx-1.22.0.tar.gz
-13ad8b3f7626f7fa11a1c395ccb361babb1b896789f8eda4350c7b214ec0c4674b9bfec253d29f6e82788da21a1b60cf2b0baef54f3ed2e5e404f286a6a9fbe7 nginx-tests-bd21a4a7c9f5.tar.gz
-ef7d362c5d6c48d302ee0d74b72d7e1c19a14c414cc49432c33b2873c118717343c7fa195e210246b35c643ce98cd8ef8a07946dfce57c75f77255a215c57bd4 nginx-njs-0.7.6.tar.gz
+1114e37de5664a8109c99cfb2faa1f42ff8ac63c932bcf3780d645e5ed32c0b2ac446f80305b4465994c8f9430604968e176ae464fd80f632d1cb2c8f6007ff3 nginx-1.24.0.tar.gz
+18b69643648119dfab45101bb9404be667aeb9d550aa3bc9706e63e7da1c2806106e9a6bbfb2d10bd57ef56b9b5b0b524059353ec30a51469b44641cb7dbd8a6 CVE-2023-44487.patch
+d882d7f79814bd5caf323099aef318a5f4c75c2eb81f13bbd9688fd5404f5a2e4dc653dbc23121f77cc5ccf59742f80fb34db38b8788030c54b376eb9a2065ff nginx-tests-22f45bf99a9e.tar.gz
+1cec9a322c40aa2b4ec6eb5bea78d7442880b0cff3a41ad171a3dc3157a6990baec6c8b9eda99ee02a9e51c0b933f13ef17431079a5ff409aaf84b912c7f4df7 nginx-njs-0.8.3.tar.gz
4c7a94aaebbb69599b0067e74f9f3db54ec383ca9499292fec5b875bb0b5859aa11dc14cef5664c94dd54aba231f31e85feacddc49f7622aa4d0fdb38709b6e1 nginx-dav-ext-module~pr-56.patch
fdd66e433126e194a3ef22737993191a04fcc4c8caa044b27cb22bea0e7f16c8fdbc900553507d2bb541cdb82b542845a297db2a48c2460a38dd772d0ebfca9d nginx-dav-ext-module~pr-62.patch
-fa96e91f495e9891c03730bcafd948e597e7c5d74f2d30df0a8483ae04f7b30c89065a994a0baa5245470f8991db5844b26da925b23ff26c178a384f5f1a887c nginx-module-vts~01-938c19d.patch
-1c37e58921478325bb4dd608900588cda49d608e859127f45a1df73176b228b060bf71d9530dc1ad434a287c7a3225e8fe307fcf1bd15758f327436283db6fb9 nginx-module-vts~02-ad40022.patch
-9f9cda2f3f163654100adf9cde892b26f80d3de30ffec9fcdb0b3c1a42856f9219ebb024fd4c156fd8c4c4a6c7b17faca89e16916128da232d9f3bc825d716ff nginx-module-vts~03-c08781c.patch
-e87d9c8cbebc147881e3a40e6944acfe836f29eb7b393af0465b04dd27f1fa42f17ab63d2bcc75053812140a92dceca4eb4e1f0e35877919af4bd3cd0b2b771a nginx-module-vts~04-1a01a87.patch
-dfcfd4dd14ccb205ea80d28eae8cadd123015d5eddc004a31b7742d8117c69cad1b56868ba94dd75e22b7ef9f44da21c02e5f5f1ecd4f90473cd9fa6128518c5 nginx-module-vts~05-ead62a0.patch
-5d6b5b2f409d8183576d7d58f75a92b859922e6dc6d2e12d3abb92f3491eca4962231c1ba5860366fd83c86283711b79a19c3c7823f042267f14925d7a49cc78 nginx-module-vts~fix-uri-overflow.patch
-90efd127fef5c89ae3148ab626a4061875d84af376d41b2bd36b2cf3188c2a244013bf1d3b09fbde51b68f59f0893e0bfaf929319aeb818904c8cdadd853c229 nginx-module-vts~cast-key-length-to-correct-type.patch
-48689e09dc87f395095408127669c9f21a32c13b1b700ffad225db0c8920ae9e4f08e88332c12c01d96ded2d091ad2033885d81d5d7c9479745b10620f36562d nginx-module-vts~set-histogram-buckets-on-first-request.patch
+c89fab6d3d4226e37f2a8d2122d825046fc9a787e464fc75351a19fbda5b47016ddb907e0a61241a007304af921e11a0715895ba7b6d4c1112afe816177ed02a no-werror.patch
09ec9f18323197eafa55ff68e8c836ad3dd830e6cd3bd4aeaf34e179ef3f72f734a0117288c1c58813aff59f3f1f0f29ccd772a672e17551e7a4fd0693a89c92 traffic-accounting-nginx-module~disable-stream-module.patch
+5a7e72fc6ade460b725e6b91d5eafeb2792ad9832fbdb84ed868bd9a25d43116e42877df587b5f3885a1e38769f072ed4e8605393aca672d61bc71dd106d392b traffic-accounting-nginx-module~fix-memory-leak.patch
ac0f912ae90e0083cc761a622290223edeed0bd32213bbe766d637ac2dfd9835d163e5d16ef28740cbad05d6d92cc418d62df3413c70b4f2c63db02f8ca1c7cc nginx_cookie_flag_module~fix-mem-allocations.patch
4db527d663dbe9e8b503c3cbaa4eae34b45990a5359b3bb98ce970c705faefcac98de49439f2557756a2be8e2e06acc67f98942de01674c498832d80c3cb90c3 njs~mktemp-busybox-compat.patch
-df1d910d5a433ef8aa6620e46bd46cb82c45c840e35420bf81a76e5a868ac73ad88aa3934d1c11bcf004a88a9cd13bf69a96ee1b08540251b09903a30430b199 njs~nginx-1.20.x-compat.patch
-9c5ee975dffa15b76688ef798371635f38f1e6773b143c738add26297878dddfc20ebf276e3871a60f28b197e8a70496ca17d4816c2136171978c157bb8e591f nginx.conf
+eee45b82a594c4dfa5eecf94cf14cd247bd1dd7d627aa0a26666828b3e2da1a358da251a23f0b5feeb5f95f6ba205af6ead54c1e6bcb67f6d11149c0580de3af naxsi~assert.patch
+7c35f51d73b6c20b6b9b030e76a4898752eae38e0f8e4001286a93633f0b1b11c39fd883116d86a323338027766d15d99c824a9cd9ffe934bea80b7af2a3070c naxsi~ff-header.patch
+3e000d58e1259a656bb49af23623e6542ec994e3fe699e0005afde9ded5d505e7a174b206390b55ef639e53fd47516a86d88de675df86d550808da1d2732e683 naxsi~compat.patch
+745e900573bc4d1ca6dd40da4743387f9ffaa764cca59591fcbfb1afe67980e529184f81a7cf8f047ddd1962a6a26ed65f1589d69a4f63f6f5701549f38a0652 nginx-upload-progress-module~fix.patch
+24bcde151301ed41eaea65c3792219b25dbb76e3eddd74064937038326698b83d6620d2515a954984502ad2a1c6c53843680952c2ce813f2da34652047675ddf nginx-upload-progress-module~fix-http2.patch
+37ad4288684d8918045d406f9f46510211413ab343e47aa149e52fd773ad95e6ff10a1b4e7cdd60acaf9231a0c6a935ab489c25880444f1a79e8624693fa166e ngx-fancyindex~fix-404-on-fs-root.patch
+d54eb2152b2ddbf3e8956cb7b4634b1657635b21b9b4f91309d45a43553c9506ad70161d265e0840c1e84c9e04c0e89061600176ad2ec39311b5c0ce75e42f1e ngx-fancyindex~fix-missing-saturday.patch
+abda15727e34178db2f8013a1c47e480ba323a3b3b88a44bbada0169b8ce66743911ec7b551272fc8540199070b62eadc78a19989f770794b43877c6743f573d nchan~dont-fail-redis-cluster-before-consensus.patch
+2a87aee322a146a55e58d48636cdb6a3a182c308a6fe5327c9c2ece0487f669fe6b3f231f56e395e12b7c2ae2dd929a72a03dc18b1032ccc733184aac50d2381 nchan~fix-redis-race-condition.patch
+ef57603bd65ffbbb216fd748dab0126d3df7aafdfa70dce0ea9ef91373df95269546ec2fcaa03f842a8db3a16879274184a23b18db17b4f9be3916aedacb7765 nginx-upload-module~fixes.patch
+bae6c3153810bf6f460248668f2c48e332aba37081e25e45a1691344508530ef1be9acee4d52f506cb09510c4fce8d93ca3178ba45af771c54e37126f4f11b1b nginx-upload-module~fix-nginx-compat.patch
+97ed3a3ad636a8853a993db3a33c67da303063e7ac43c20eeac6afb9f71adafa5dedf5f5f8c6705a256294c0566e3ac9f5fa41930048ad80b10a7d2a7d3c9b53 zstd-nginx-module~fix-infinite-loop.patch
+c209a220b6afc9354a1c4c39817199327425485b3da44778d632cdfd1d95b8412c58ba9b27a5c96599e7a34cc039f5b7d914ad82153c610b27dfbe21fdcdca77 nginx.conf
0907f69dc2d3dc1bad3a04fb6673f741f1a8be964e22b306ef9ae2f8e736e1f5733a8884bfe54f3553fff5132a0e5336716250f54272c3fec2177d6ba16986f3 default.conf
-f3321a45736697009817db335ad36d3f1d05f60d98ac90a943220cdd4c00c52632f018db6a6076d5431a483525aacc5725b87b765b590e2f63b3ef98c5b16bd8 stream.conf
+426f0c317322af7cab152f2070398c7aa5c059276ba504617a212f1e060bbb1dd9edc54e62d4cf5f14e3678235351c808ebeabe8b122757c74b3f505e8427106 stream.conf
09b110693e3f4377349ccea3c43cb8199c8579ee351eae34283299be99fdf764b0c1bddd552e13e4d671b194501618b29c822e1ad53b34101a73a63954363dbb nginx.logrotate
ee10a5687740dde0c3d18d8b3555f49fcdc6abfc0a3bc2de1de3be0e99951a346fe8027d916aab73071ecd4e2c50871e7c867aca3a7a0fd16e3374c5caed1c57 nginx.initd
0b9b9ed01ac077e334c034faa2679f6e26740fb3362eebf8cef82d22b2af2a3faaa53bae3c9e14af51cbf64720a7c66431905ca5cc43f978366456cc4e3b7f4a nginx.confd
-de1e3349d8dd08e5982279b2219dc8a8006739f0409b8e0f5c50d93434beff1fbafba43e9c5ac85a5fab90afc5c0a7244a340610339c36f82f2cba7233e72de9 ngx_devel_kit-0.3.1.tar.gz
+a255e3a4a9b902b3e15140dc88bbbb152b0a9cdc64604152de41e1b254e81aa2a1e2c95c06cb4905c1520886acf9070031d63913b53fe98b034f8adad2bccf61 ngx_devel_kit-0.3.3.tar.gz
0df34c3765e18dc5cc5a053d3a17dbee17a686a1f6e76ad057c262741c4e4465c66bcef86e627a19258f836cad5f14745bf046fd396b00960ad79ed20c2a07bb traffic-accounting-nginx-module-2.0.tar.gz
-7c9fa9b76bc7cd2473ceae6d5ffb8de26993be9293ea967908d6c4550e086affa7016df4c936fb0b79f1142dc0aa1a5f2058d417e6433b5a3497a45d7e866e84 array-var-nginx-module-0.05.tar.gz
+bc72158856a1be18a26ee04c6b5b0f0a20bcce688610a493bf31e2a133e7eb12e11f7c18197a09a72b1513f6a08348ee5281b9d5b84cf43603539040ebd23c26 array-var-nginx-module-0.06.tar.gz
+56fe87b7b456856c167b47e5dfc579ac77f15487785dd8411397f6041561b991218518218b4adf3054392fdf1569469a4eff288706f320cf8d2c45b066ef780b nginx-auth-jwt-0.6.0.tar.gz
05a880d5e48ac83be84498ed41fb4750211b827a9d7541acfd6ef494e5205a6e853d5594bfec3ab4ae668ea3f803e4f4b0ba550c76811971c8e266e42663c56d ngx_brotli-1.0.0rc.tar.gz
-a5e5f901823559d42421f9bc8f2aaba6cc3ad9ddfba2bbad154bb6b70e2001ed1bf25781c2117faeea3c20d824c74827cdf6b97f45eda343b60f50b964e69c40 ngx_cache_purge-2.5.2.tar.gz
+aebc9b19a3e7dda3b57e6bd6d86a5ab66d25e05cf5c6c99c71234c789700eb9da8e29529b8b2abf3d775ff3c2610e695fc88e647738769f0d3730bcafc3be38b ngx_cache_purge-2.5.3.tar.gz
352cc3d033cc67ee34209f958dac13ada2147de429f4dd3da301c865d52970d80c8aa3c193f7fb28cf4854b88baff07b6efc3bae1fb813fe53d5956a87dfc81a nginx_cookie_flag_module-1.1.0.tar.gz
d0193ba90f1ef46c4e470630c4394bdf99d94fd2e3bd8be6cb2ba1655ec59944b1269025f032b79dc2c6dad366e54389ef6a6da2ddeb91d535a4027f2162fbde nginx-dav-ext-module-3.0.0.tar.gz
-240896b1c559a71ca6ca87136d8535edd25b1d65ebb80d46080ad41c09ed1cec9737828f9efe260782294d660cea66cf402f4e75bba3fed26f3a94de0ae2f89b echo-nginx-module-0.62.tar.gz
+c325ac4e3f3f735739e156d8c7ada503b34475c62533b4830231ff1b42c25cb0c841aae06b3448b589c2ab35da8d211436ed194d6fd062cad925af8152c5e789 echo-nginx-module-0.63.tar.gz
399ce2690e85ee27802e8031954a1a3aa3fdc9246e17323a72a298d235931a8dbebdcb121ac8788e074872df0ef5b5a8a3d512b17fbe860b38f696ce42de3655 encrypted-session-nginx-module-0.09.tar.gz
c208cdf3e245527d7b313f9ef1f5d36ca26e3bdafe67df56492a13b7726587538665e5d9fd50f295fc933f218dc33394f2fe442713d15631701dbfc4a156799b ngx-fancyindex-0.5.2.tar.gz
18dea21e5ae2647bea1fc448058a1b773c936917245edef8d861d5e23ed92e9a3b1ec4ef43ffb2ece7b5899d787910adcf4fbd39f84d7e8d7c54759e2fee5b72 ngx_http_geoip2_module-3.4.tar.gz
-13165b1b8d4be281b8bd2404fa48d456013d560bace094c81da08a35dc6a4f025a809a3ae3a42be6bbf67abbcbe41e0730aba06f905220f3baeb01e1192a7d37 headers-more-nginx-module-0.33.tar.gz
+0cc2fffe506194d439e3669644d41b7943e2c3cffa3483eb70b92067930b358d506a14646eff8362b191a11c624db29f6b53d830876929dcb4ce1c9d7b2bc40d headers-more-nginx-module-0.37.tar.gz
+45b8f107a492f415f5053b9b95d3dad481d5736c603b87c1342541214e89b9acbe37925f93acc396782406232e607879b52f9bb480f9021c10d405b832298022 nginx-keyval-0.2.0.tar.gz
015a358d987476bb61302fbbe1cb105f5314edc1a8b7ee6310aae697f755c79fcb1834ff561fced054c8cd5624f5387fcc1de729731ccd70662f2eb72bcdc174 nginx-log-zmq-1.0.0.tar.gz
-c7594be48a3a5a8cc7bbda9288cb836c4c854ad22f91766dba944316d471ab8857a6b6a52813eb041af81939df73614db54ccd3ed35af87036d76317ebbe2e97 lua-nginx-module-0.10.21.tar.gz
+9abf00844ef00ce1dc5ff08d6fe4ddccf843f2ad2de6fd450854b38a66b45add71e814205dba9b19225b9165e67eb93578e83e5fe37af4e0c891e61e6a6bfb3d lua-nginx-module-0.10.26.tar.gz
72887c4490854b099cb26bb3f840073a36b0d812bde4486f04dc1be182ca74f0d1e3fd709e77c240c2dcf37665f74cf04e188ea9efe8e127c6789b27b487d0cd lua-upstream-nginx-module-0.07.tar.gz
d7aac69b5eceeb1b0db4741201159ade1e0e7f6f7c3e8c4afa2f8959c6c00c3b5285d5185747c2fb0b1400efda02e96799836315e7e492bb4a059b14acb2142d naxsi-1.3.tar.gz
-c8cd3eb0b06fc0f17b5a9013d32f5a6d5a8252015b3ac27fbf74a7a1b97bc7ae78c5c8cdd7372e36f5f9d137b59635f007d836746282c85c4a972b6984ba2bef nchan-1.3.0.tar.gz
+0f1c25d460dcf4e3407a1ef4bfcefe17eba7b0ff250f267e5bde0eb4298e9596c1e6992fc58fe35d8420888065353bf3883a1f1bbc5e607a00128992eb1ee6d2 nchan-1.3.6.tar.gz
d6ca250db8de93edbd7875afca35e73cecdaf82132d1a7ee933cf94c6b8afa8e629e9e647a9321f2bc1fbb92137ec0d32dcd89b82ac5fae31e342537fb7e0431 redis2-nginx-module-0.15.tar.gz
1ff4c947538a5bd5f9d6adcd87b37f2702f5cc90e3342bc08359cbe8f290b705a3a2daa3dedfb1df3ce4bc19478c8fcac07081c4a53a804fc2862d50078278dc set-misc-nginx-module-0.33.tar.gz
-1730845ea2e52be8c2f6cfceb2894304c5a07959a96940bb1617ee0e7cf81d22283304f411d9a219ddb71e4d9a66012bba0f6f5574d101aeb3c406f26c5d6a4e nginx-http-shibboleth-2.0.1.tar.gz
+0f0c5167e999ffad0caa816d4b7d0a121f0598d578391834fe3293a3e023453d91b36ffc32a431ff3af3f9f376d2d78703998560094d20643b4049c2fec84bda nginx-http-shibboleth-2.0.2.tar.gz
c3a7dd29c4a4e47d396b19622a290a04d4cceb97c1b8a508bc984eb8c81d17da4bf5789514bb996987f8343bc801ee4457a86a274bde98b49a809afdfc04cbde ngx_http_untar_module-1.1.tar.gz
a0da355888398f86a6b5d065e58c05f9e057589ee785be9f515d77d7a020ae5a7b0656f5af30fb3b026f457326db2e26f4fed29026221ec5fc8156ef8586da25 nginx-upload-module-2.3.0.tar.gz
c31c46344d49704389722325a041b9cd170fa290acefe92cfc572c07f711cd3039de78f28df48ca7dcb79b2e4bbe442580aaaf4d92883fd3a14bf41d66dd9d8c nginx-upload-progress-module-0.9.2.tar.gz
8adb7453c27748f4e685e3352e9b318b408da818754dc5b6244e908423941a8ba337561104f6e481f2553cbc0e334dcea73b57f8e810a9d6e974bb69ff8859e5 nginx-upstream-fair-0.1.3.tar.gz
-bbf3f4808f17fa797fa0c27bc1351098aa5d6b5d227376a0ab01b4f424942ec5ad9f5c09c7af284345988b119268bf579b24065fb6bc6bc2f2b2392e918f09bc ngx_upstream_jdomain-1.4.0.tar.gz
-4ffbd9f1f641e4304ffda2dfeee627d27fee69ca4f55cf7f5286c415a5962b5d332e69a73be026ebe253c1f7253c5843ea6cffb2663bded0e934ea0015a89bb0 nginx-vod-module-1.29.tar.gz
-86b980095b3b80c8dce2e355db514cb4b3039c8408a2f5ca6df9e105d5462952fddd70f6581ec6aa2763e560b591664c27eefd978c4ea777b1f1f808bc60d4ec nginx-module-vts-0.1.18.tar.gz
-92e1e5aa570b68a19bb718817f864c4347f6dc89f90d828071ab3d06c784cc2786674d9d64fffef8c23749d0a653f2eb996b412ab10015eea1ed895d81268ce1 mod_zip-1.2.0.tar.gz
+2ac8351d8d325353534c87e0ef6034a5d3897411895b4e03f22fa06343337d86897331797541ab9201cd7dc8b0376d6d76eb4458849900348f5e199e0b0bd357 ngx_upstream_jdomain-1.5.0.tar.gz
+29ef77f1bbdb2410ff317ebdd7434f31b8ec370ae6b617b92e745e87c11bc820b451181d1d2b57156b414348da14ac448b689b32b17ab418144292eda094512d nginx-vod-module-1.33.tar.gz
+7295c1af3267b067793fb88e3d3a74fdba5187742141d447f597b8d726c455bfb163209eca5d00b00a57adc3f627078b404a43f5318f910a68c6aeaffb189b1c nginx-module-vts-0.2.2.tar.gz
+8c5dda14da06ef776fe2b496c2f1b80d2c25c9269309aa560a006c369044c52917024a90f897b7212b2409a874bf2e0a3ab2dbc1e10ad84fa64f54f1f4df3d0d mod_zip-1.3.0.tar.gz
+6feb544face95121ea076db5df8ca34854085b57602e732c7ba427be5e3f2bf668729d45497a2c91212f98ed8a2c347aa8778a54594f5d241e39e094a2556e4c zstd-nginx-module-0.1.1.tar.gz
3f8c803221854c4b1a06aadc6313fbfec74bd7179c0ee51d4365b26ffa8875881a6e1e48f777a9c9efbb9170ab7478a82920d5448a2c2df485503d37bb03ab81 nginx-rtmp-module-1.2.2.tar.gz
"
diff --git a/main/nginx/CVE-2023-44487.patch b/main/nginx/CVE-2023-44487.patch
new file mode 100644
index 00000000000..b9fcfbf7d6c
--- /dev/null
+++ b/main/nginx/CVE-2023-44487.patch
@@ -0,0 +1,71 @@
+
+# HG changeset patch
+# User Maxim Dounin <mdounin@mdounin.ru>
+# Date 1696940019 -10800
+# Node ID cdda286c0f1b4b10f30d4eb6a63fefb9b8708ecc
+# Parent 3db945fda515014d220151046d02f3960bcfca0a
+HTTP/2: per-iteration stream handling limit.
+
+To ensure that attempts to flood servers with many streams are detected
+early, a limit of no more than 2 * max_concurrent_streams new streams per one
+event loop iteration was introduced. This limit is applied even if
+max_concurrent_streams is not yet reached - for example, if corresponding
+streams are handled synchronously or reset.
+
+Further, refused streams are now limited to maximum of max_concurrent_streams
+and 100, similarly to priority_limit initial value, providing some tolerance
+to clients trying to open several streams at the connection start, yet
+low tolerance to flooding attempts.
+
+diff -r 3db945fda515 -r cdda286c0f1b src/http/v2/ngx_http_v2.c
+--- a/src/http/v2/ngx_http_v2.c Fri Sep 22 19:23:57 2023 +0400
++++ b/src/http/v2/ngx_http_v2.c Tue Oct 10 15:13:39 2023 +0300
+@@ -347,6 +347,7 @@
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http2 read handler");
+
+ h2c->blocked = 1;
++ h2c->new_streams = 0;
+
+ if (c->close) {
+ c->close = 0;
+@@ -1284,6 +1285,14 @@
+ goto rst_stream;
+ }
+
++ if (h2c->new_streams++ >= 2 * h2scf->concurrent_streams) {
++ ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
++ "client sent too many streams at once");
++
++ status = NGX_HTTP_V2_REFUSED_STREAM;
++ goto rst_stream;
++ }
++
+ if (!h2c->settings_ack
+ && !(h2c->state.flags & NGX_HTTP_V2_END_STREAM_FLAG)
+ && h2scf->preread_size < NGX_HTTP_V2_DEFAULT_WINDOW)
+@@ -1349,6 +1358,12 @@
+
+ rst_stream:
+
++ if (h2c->refused_streams++ > ngx_max(h2scf->concurrent_streams, 100)) {
++ ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
++ "client sent too many refused streams");
++ return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_NO_ERROR);
++ }
++
+ if (ngx_http_v2_send_rst_stream(h2c, h2c->state.sid, status) != NGX_OK) {
+ return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_INTERNAL_ERROR);
+ }
+diff -r 3db945fda515 -r cdda286c0f1b src/http/v2/ngx_http_v2.h
+--- a/src/http/v2/ngx_http_v2.h Fri Sep 22 19:23:57 2023 +0400
++++ b/src/http/v2/ngx_http_v2.h Tue Oct 10 15:13:39 2023 +0300
+@@ -131,6 +131,8 @@
+ ngx_uint_t processing;
+ ngx_uint_t frames;
+ ngx_uint_t idle;
++ ngx_uint_t new_streams;
++ ngx_uint_t refused_streams;
+ ngx_uint_t priority_limit;
+
+ size_t send_window;
+
diff --git a/main/nginx/naxsi~assert.patch b/main/nginx/naxsi~assert.patch
new file mode 100644
index 00000000000..35ae171d48a
--- /dev/null
+++ b/main/nginx/naxsi~assert.patch
@@ -0,0 +1,23 @@
+Patch-Source: https://github.com/nbs-system/naxsi/commit/aa9da98b1b9b52e5d95bbc28dc8126c0920cb4cb
+
+From aa9da98b1b9b52e5d95bbc28dc8126c0920cb4cb Mon Sep 17 00:00:00 2001
+From: Giovanni <561184+wargio@users.noreply.github.com>
+Date: Fri, 18 Dec 2020 11:31:42 +0100
+Subject: [PATCH] Fix #541 - Removing useless assert.
+
+---
+ naxsi_src/naxsi_runtime.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/naxsi_src/naxsi_runtime.c b/naxsi_src/naxsi_runtime.c
+index eccdce3e..28e0b29d 100644
+--- a/naxsi_src/naxsi_runtime.c
++++ b/naxsi_src/naxsi_runtime.c
+@@ -1073,7 +1073,6 @@ ngx_http_nx_log(ngx_http_request_ctx_t* ctx,
+ ** don't handle uri > 4k, string will be split
+ */
+
+- assert(strlen(fmt_config) != 0);
+ sub = snprintf((char*)fragment->data,
+ sz_left,
+ fmt_base,
diff --git a/main/nginx/naxsi~compat.patch b/main/nginx/naxsi~compat.patch
new file mode 100644
index 00000000000..ac9a2d64064
--- /dev/null
+++ b/main/nginx/naxsi~compat.patch
@@ -0,0 +1,133 @@
+Patch-Source: https://github.com/nbs-system/naxsi/commit/d714f1636ea49a9a9f4f06dba14aee003e970834
+
+From d714f1636ea49a9a9f4f06dba14aee003e970834 Mon Sep 17 00:00:00 2001
+From: Danila Vershinin <ciapnz@gmail.com>
+Date: Mon, 27 Jun 2022 19:45:00 +0300
+Subject: [PATCH] Fixes NGINX >= v.1.23.0 (all credits @lubomudr) (#598)
+
+---
+ naxsi_src/naxsi.h | 4 ++--
+ naxsi_src/naxsi_runtime.c | 42 ++++++++++++++++++++++++++++++++-------
+ 2 files changed, 37 insertions(+), 9 deletions(-)
+
+diff --git a/naxsi_src/naxsi.h b/naxsi_src/naxsi.h
+index b2f5c1a5..8c1939e1 100644
+--- a/naxsi_src/naxsi.h
++++ b/naxsi_src/naxsi.h
+@@ -9,12 +9,12 @@
+
+ #define NAXSI_VERSION "1.3"
+
++#include <ngx_config.h>
++#include <ngx_core.h>
+ #include "ext/libinjection/libinjection_sqli.h"
+ #include "ext/libinjection/libinjection_xss.h"
+ #include <ctype.h>
+ #include <nginx.h>
+-#include <ngx_config.h>
+-#include <ngx_core.h>
+ #include <ngx_event.h>
+ #include <ngx_http.h>
+ #include <ngx_http_core_module.h>
+diff --git a/naxsi_src/naxsi_runtime.c b/naxsi_src/naxsi_runtime.c
+index 784852b0..6b55d2b3 100644
+--- a/naxsi_src/naxsi_runtime.c
++++ b/naxsi_src/naxsi_runtime.c
+@@ -4,8 +4,8 @@
+ * Licensed under GNU GPL v3.0 – See the LICENSE notice for details
+ */
+
+-#include "assert.h"
+ #include "naxsi.h"
++#include "assert.h"
+ #include "naxsi_macros.h"
+ #include "naxsi_net.h"
+
+@@ -2912,20 +2912,20 @@ ngx_http_naxsi_data_parse(ngx_http_request_ctx_t* ctx, ngx_http_request_t* r)
+ /* and the presence of data to parse */
+ r->request_body && ((!ctx->block || ctx->learning) && !ctx->drop))
+ ngx_http_naxsi_body_parse(ctx, r, cf, main_cf);
++#if (NGX_HTTP_X_FORWARDED_FOR)
+ ngx_str_t tag;
+ tag.len = 15;
+ tag.data = ngx_pcalloc(r->pool, tag.len + 1);
+ if (tag.data)
+ memcpy(tag.data, "x-forwarded-for", 15);
++#if (nginx_version < 1023000)
+ unsigned int n = 0;
+ ngx_table_elt_t** h = NULL;
+ ngx_array_t a;
+-#if (NGX_HTTP_X_FORWARDED_FOR)
+ if (r->headers_in.x_forwarded_for.nelts >= 1) {
+ a = r->headers_in.x_forwarded_for;
+ n = a.nelts;
+ }
+-#endif
+ if (n >= 1)
+ h = a.elts;
+ if (n >= 1) {
+@@ -2933,6 +2933,16 @@ ngx_http_naxsi_data_parse(ngx_http_request_ctx_t* ctx, ngx_http_request_t* r)
+
+ ngx_http_naxsi_update_current_ctx_status(ctx, cf, r, &tag, (ngx_str_t*)h[0]->value.data);
+ }
++#else
++ ngx_table_elt_t* xff = NULL;
++ if (r->headers_in.x_forwarded_for != NULL) {
++ xff = r->headers_in.x_forwarded_for;
++ ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "xfor %s", xff->value.data);
++
++ ngx_http_naxsi_update_current_ctx_status(ctx, cf, r, &tag, (ngx_str_t*)xff->value.data);
++ }
++#endif
++#endif
+ }
+
+ void
+@@ -2947,19 +2957,20 @@ ngx_http_naxsi_update_current_ctx_status(ngx_http_request_ctx_t* ctx,
+ ngx_http_check_rule_t* cr;
+
+ ngx_http_special_score_t* sc;
+- unsigned int n = 0;
+
+ NX_DEBUG(_debug_custom_score, NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "XX-custom check rules");
+
+ int ignore = 0;
+- ngx_table_elt_t** h;
+- ngx_array_t a;
+
+ ctx->ignore = 0;
+
+ /*cr, sc, cf, ctx*/
+ if (cf->check_rules && ctx->special_scores) {
+ #if (NGX_HTTP_X_FORWARDED_FOR)
++#if (nginx_version < 1023000)
++ unsigned int n = 0;
++ ngx_table_elt_t** h;
++ ngx_array_t a;
+ if (r->headers_in.x_forwarded_for.nelts >= 1) {
+ a = r->headers_in.x_forwarded_for;
+ n = a.nelts;
+@@ -2978,6 +2989,23 @@ ngx_http_naxsi_update_current_ctx_status(ngx_http_request_ctx_t* ctx,
+ ignore = nx_can_ignore_ip(&ip, cf) || nx_can_ignore_cidr(&ip, cf);
+ }
+ } else
++#else
++ ngx_table_elt_t* xff;
++ if (r->headers_in.x_forwarded_for != NULL) {
++ xff = r->headers_in.x_forwarded_for;
++ NX_DEBUG(_debug_whitelist_ignore,
++ NGX_LOG_DEBUG_HTTP,
++ r->connection->log,
++ 0,
++ "XX- lookup ignore X-Forwarded-For: %s",
++ xff->value.data);
++ ngx_str_t ip;
++ ip.len = strlen((char*)xff->value.data);
++ ip.data = ngx_pcalloc(r->pool, ip.len + 1);
++ memcpy(ip.data, xff->value.data, ip.len);
++ ignore = nx_can_ignore_ip(&ip, cf) || nx_can_ignore_cidr(&ip, cf);
++ } else
++#endif
+ #endif
+ {
+ ngx_str_t* ip = &r->connection->addr_text;
diff --git a/main/nginx/naxsi~ff-header.patch b/main/nginx/naxsi~ff-header.patch
new file mode 100644
index 00000000000..b6ed47760d8
--- /dev/null
+++ b/main/nginx/naxsi~ff-header.patch
@@ -0,0 +1,62 @@
+Patch-Source: https://github.com/nbs-system/naxsi/commit/296583f06ba5c43cc859e01fd3c0ae1271eef0ce
+
+From 296583f06ba5c43cc859e01fd3c0ae1271eef0ce Mon Sep 17 00:00:00 2001
+From: Fabrice Fontaine <fontaine.fabrice@gmail.com>
+Date: Sat, 14 Aug 2021 12:57:28 +0200
+Subject: [PATCH] naxsi_src/naxsi_runtime.c: fix build without x_forwarded_for
+ (#568)
+
+x_forwarded_for is not available if realip, geo, geoip or proxy modules
+aren't enabled resulting in the following build failure since version
+1.1a and
+https://github.com/nbs-system/naxsi/commit/07a056ccd36bc3c5c40dc17991db226cb8cf6241:
+
+/home/buildroot/autobuild/instance-3/output-1/build/nginx-naxsi-1.3/naxsi_src/naxsi_runtime.c: In function 'ngx_http_naxsi_data_parse':
+/home/buildroot/autobuild/instance-3/output-1/build/nginx-naxsi-1.3/naxsi_src/naxsi_runtime.c:2846:20: error: 'ngx_http_headers_in_t' has no member named 'x_forwarded_for'
+ if (r->headers_in.x_forwarded_for.nelts >= 1) {
+ ^
+
+Fixes:
+ - http://autobuild.buildroot.org/results/cdbc1536f6b5de3d4c836efa2f0dcaf0cdbb1462
+
+Signed-off-by: Fabrice Fontaine <fontaine.fabrice@gmail.com>
+---
+ naxsi_src/naxsi_runtime.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/naxsi_src/naxsi_runtime.c b/naxsi_src/naxsi_runtime.c
+index 28e0b29d..6a723d24 100644
+--- a/naxsi_src/naxsi_runtime.c
++++ b/naxsi_src/naxsi_runtime.c
+@@ -2842,10 +2842,12 @@ ngx_http_naxsi_data_parse(ngx_http_request_ctx_t* ctx, ngx_http_request_t* r)
+ unsigned int n = 0;
+ ngx_table_elt_t** h = NULL;
+ ngx_array_t a;
++#if (NGX_HTTP_X_FORWARDED_FOR)
+ if (r->headers_in.x_forwarded_for.nelts >= 1) {
+ a = r->headers_in.x_forwarded_for;
+ n = a.nelts;
+ }
++#endif
+ if (n >= 1)
+ h = a.elts;
+ if (n >= 1) {
+@@ -2879,6 +2881,7 @@ ngx_http_naxsi_update_current_ctx_status(ngx_http_request_ctx_t* ctx,
+
+ /*cr, sc, cf, ctx*/
+ if (cf->check_rules && ctx->special_scores) {
++#if (NGX_HTTP_X_FORWARDED_FOR)
+ if (r->headers_in.x_forwarded_for.nelts >= 1) {
+ a = r->headers_in.x_forwarded_for;
+ n = a.nelts;
+@@ -2896,7 +2899,9 @@ ngx_http_naxsi_update_current_ctx_status(ngx_http_request_ctx_t* ctx,
+ memcpy(ip.data, h[0]->value.data, ip.len);
+ ignore = nx_can_ignore_ip(&ip, cf) || nx_can_ignore_cidr(&ip, cf);
+ }
+- } else {
++ } else
++#endif
++ {
+ ngx_str_t* ip = &r->connection->addr_text;
+ NX_DEBUG(_debug_whitelist_ignore,
+ NGX_LOG_DEBUG_HTTP,
diff --git a/main/nginx/nchan~dont-fail-redis-cluster-before-consensus.patch b/main/nginx/nchan~dont-fail-redis-cluster-before-consensus.patch
new file mode 100644
index 00000000000..114ff925b97
--- /dev/null
+++ b/main/nginx/nchan~dont-fail-redis-cluster-before-consensus.patch
@@ -0,0 +1,49 @@
+Patch-Source: https://github.com/slact/nchan/commit/ed27e02adcac66ce73f5db387596fa063362ac6e
+--
+From ed27e02adcac66ce73f5db387596fa063362ac6e Mon Sep 17 00:00:00 2001
+From: Fabio Urquiza <fabiorush@gmail.com>
+Date: Wed, 1 Feb 2023 14:48:47 +0000
+Subject: [PATCH] Don't fail redis cluster nodes before consensus is reached
+
+diff --git a/src/store/redis/redis_nodeset.c b/src/store/redis/redis_nodeset.c
+index 39fdd396..2c4646c4 100644
+--- a/src/store/redis/redis_nodeset.c
++++ b/src/store/redis/redis_nodeset.c
+@@ -1052,6 +1052,9 @@ static void nodeset_cluster_check_event_callback(redisAsyncContext *ac, void *re
+
+ for(i=0; i<n; i++) {
+ l = &lines[i];
++ if(l->maybe_failed) {
++ nodeset_log_warning(ns, "Ignoring 'fail?' state reported by %V:%d for node %V", &node->connect_params.hostname, node->connect_params.port, &l->address);
++ }
+ if(l->failed && nodeset_node_remove_failed(ns, &l->id)) {
+ failed_nodes++;
+ continue;
+diff --git a/src/store/redis/redis_nodeset_parser.c b/src/store/redis/redis_nodeset_parser.c
+index 7ce0037b..e3052dc2 100644
+--- a/src/store/redis/redis_nodeset_parser.c
++++ b/src/store/redis/redis_nodeset_parser.c
+@@ -132,7 +132,10 @@ static char *nodeset_parser_scan_cluster_nodes_line(const char *line, cluster_no
+ l->slot_ranges_count = 0;
+ l->master = 0;
+ }
+- l->failed = nchan_ngx_str_substr((&l->flags), "fail");
++ l->maybe_failed = nchan_ngx_str_substr((&l->flags), "fail?");
++ if(!l->maybe_failed)
++ l->failed = nchan_ngx_str_substr((&l->flags), "fail");
++
+ l->self = nchan_ngx_str_substr((&l->flags), "myself");
+ l->noaddr = nchan_ngx_str_substr((&l->flags), "noaddr");
+ l->handshake = nchan_ngx_str_substr((&l->flags), "handshake");
+diff --git a/src/store/redis/redis_nodeset_parser.h b/src/store/redis/redis_nodeset_parser.h
+index 5d564b62..a14ae146 100644
+--- a/src/store/redis/redis_nodeset_parser.h
++++ b/src/store/redis/redis_nodeset_parser.h
+@@ -28,6 +28,7 @@ typedef struct {
+ unsigned master:1;
+ unsigned noaddr:1;
+ unsigned failed:1;
++ unsigned maybe_failed:1;
+ unsigned handshake:1;
+ unsigned self:1;
+ } cluster_nodes_line_t;
diff --git a/main/nginx/nchan~fix-redis-race-condition.patch b/main/nginx/nchan~fix-redis-race-condition.patch
new file mode 100644
index 00000000000..75d5b83a050
--- /dev/null
+++ b/main/nginx/nchan~fix-redis-race-condition.patch
@@ -0,0 +1,270 @@
+Patch-Source: https://github.com/slact/nchan/commit/cc705a948cf6797f669b64649605f007f6f26a42
+--
+From cc705a948cf6797f669b64649605f007f6f26a42 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?F=C3=A1bio=20Urquiza?= <fabiorush@gmail.com>
+Date: Mon, 20 Mar 2023 10:31:33 -0300
+Subject: [PATCH] Fix redis connection race condition on many workers (#666)
+
+diff --git a/src/nchan_module.c b/src/nchan_module.c
+index ad6f3534..95b51521 100644
+--- a/src/nchan_module.c
++++ b/src/nchan_module.c
+@@ -39,7 +39,6 @@ int nchan_redis_stats_enabled = 0;
+
+
+ static void nchan_publisher_body_handler(ngx_http_request_t *r);
+-static void nchan_publisher_unavailable_body_handler(ngx_http_request_t *r);
+
+ //#define DEBUG_LEVEL NGX_LOG_WARN
+ //#define DEBUG_LEVEL NGX_LOG_DEBUG
+@@ -746,18 +745,6 @@ ngx_int_t nchan_pubsub_handler(ngx_http_request_t *r) {
+ return NGX_OK;
+ }
+
+- if(cf->redis.enabled && !nchan_store_redis_ready(cf)) {
+- //using redis, and it's not ready yet
+- if(r->method == NGX_HTTP_POST || r->method == NGX_HTTP_PUT) {
+- //discard request body before responding
+- nchan_http_publisher_handler(r, nchan_publisher_unavailable_body_handler);
+- }
+- else {
+- nchan_respond_status(r, NGX_HTTP_SERVICE_UNAVAILABLE, NULL, NULL, 0);
+- }
+- return NGX_OK;
+- }
+-
+ if(cf->pub.websocket || cf->pub.http) {
+ char *err;
+ if(!nchan_parse_message_buffer_config(r, cf, &err)) {
+@@ -841,6 +828,13 @@ ngx_int_t nchan_pubsub_handler(ngx_http_request_t *r) {
+ #if FAKESHARD
+ memstore_sub_debug_start();
+ #endif
++
++ if(cf->redis.enabled && ngx_process_slot == memstore_channel_owner(channel_id) && !nchan_store_redis_ready(cf)) {
++ //using redis, and it's not ready yet
++ nchan_respond_status(r, NGX_HTTP_SERVICE_UNAVAILABLE, NULL, NULL, 0);
++ return NGX_OK;
++ }
++
+ if((msg_id = nchan_subscriber_get_msg_id(r)) == NULL) {
+ goto bad_msgid;
+ }
+@@ -1249,11 +1243,6 @@ static ngx_int_t nchan_publisher_body_authorize_handler(ngx_http_request_t *r, v
+ return NGX_OK;
+ }
+
+-static void nchan_publisher_unavailable_body_handler(ngx_http_request_t *r) {
+- nchan_http_finalize_request(r, NGX_HTTP_SERVICE_UNAVAILABLE);
+- return;
+-}
+-
+ static void nchan_publisher_body_handler(ngx_http_request_t *r) {
+ ngx_str_t *channel_id;
+ nchan_loc_conf_t *cf = ngx_http_get_module_loc_conf(r, ngx_nchan_module);
+diff --git a/src/store/memory/ipc-handlers.c b/src/store/memory/ipc-handlers.c
+index 55df2fd3..bee7c1d9 100644
+--- a/src/store/memory/ipc-handlers.c
++++ b/src/store/memory/ipc-handlers.c
+@@ -47,6 +47,8 @@
+ L(benchmark_finish_reply) \
+ L(redis_stats_request) \
+ L(redis_stats_reply) \
++ L(redis_conn_ready) \
++ L(redis_conn_ready_reply) \
+
+
+
+@@ -1205,6 +1207,35 @@ static void receive_redis_stats_reply(ngx_int_t sender, redis_stats_request_data
+ shm_free(nchan_store_memory_shmem, data->stats);
+ }
+
++////////// REDIS CONN READY DATA ////////////////
++typedef struct {
++ ngx_int_t ready;
++ nchan_loc_conf_t *cf;
++ callback_pt callback;
++ void *privdata;
++} redis_conn_ready_data_t;
++
++ngx_int_t memstore_ipc_send_redis_conn_ready(ngx_int_t dst, nchan_loc_conf_t *cf, callback_pt callback, void* privdata) {
++ DBG("send redis_conn_ready to %i", dst);
++ redis_conn_ready_data_t data;
++ DEBUG_MEMZERO(&data);
++ data.ready = 0;
++ data.cf = cf;
++ data.callback = callback;
++ data.privdata = privdata;
++
++ return ipc_cmd(redis_conn_ready, dst, &data);
++}
++
++static void receive_redis_conn_ready(ngx_int_t sender, redis_conn_ready_data_t *d) {
++ DBG("received redis_conn_ready request for privdata %p", d->privdata);
++ d->ready = nchan_store_redis_ready(d->cf);
++ ipc_cmd(redis_conn_ready_reply, sender, d);
++}
++
++static void receive_redis_conn_ready_reply(ngx_int_t sender, redis_conn_ready_data_t *d) {
++ d->callback(d->ready, NULL, d->privdata);
++}
+
+ #define MAKE_ipc_cmd_handler(val) [offsetof(ipc_handlers_t, val)/sizeof(ipc_handler_pt)] = (ipc_handler_pt )receive_ ## val,
+ static ipc_handler_pt ipc_cmd_handler[] = {
+diff --git a/src/store/memory/ipc-handlers.h b/src/store/memory/ipc-handlers.h
+index e22c4a0d..7fd9c19c 100644
+--- a/src/store/memory/ipc-handlers.h
++++ b/src/store/memory/ipc-handlers.h
+@@ -26,3 +26,5 @@ ngx_int_t memstore_ipc_broadcast_benchmark_finish(void);
+ ngx_int_t memstore_ipc_broadcast_benchmark_abort(void);
+
+ ngx_int_t memstore_ipc_broadcast_redis_stats_request(void *nodeset, callback_pt cb, void *pd);
++
++ngx_int_t memstore_ipc_send_redis_conn_ready(ngx_int_t dst, nchan_loc_conf_t *cf, callback_pt callback, void* privdata);
+\ No newline at end of file
+diff --git a/src/store/memory/memstore.c b/src/store/memory/memstore.c
+index f8b4ee8b..e1e1c7a8 100755
+--- a/src/store/memory/memstore.c
++++ b/src/store/memory/memstore.c
+@@ -2079,12 +2079,13 @@ static void subscribe_data_free(subscribe_data_t *d) {
+ #define SUB_CHANNEL_NOTSURE 2
+
+ static ngx_int_t nchan_store_subscribe_channel_existence_check_callback(ngx_int_t channel_status, void* _, subscribe_data_t *d);
+-static ngx_int_t nchan_store_subscribe_continued(ngx_int_t channel_status, void* _, subscribe_data_t *d);
++static ngx_int_t nchan_store_subscribe_stage2(ngx_int_t continue_subscription, void* _, subscribe_data_t *d);
++static ngx_int_t nchan_store_subscribe_stage3(ngx_int_t channel_status, void* _, subscribe_data_t *d);
+
+ static ngx_int_t nchan_store_subscribe(ngx_str_t *channel_id, subscriber_t *sub) {
+ ngx_int_t owner = memstore_channel_owner(channel_id);
+ subscribe_data_t *d = subscribe_data_alloc(sub->cf->redis.enabled ? -1 : owner);
+-
++
+ assert(d != NULL);
+
+ d->channel_owner = owner;
+@@ -2095,24 +2096,51 @@ static ngx_int_t nchan_store_subscribe(ngx_str_t *channel_id, subscriber_t *sub)
+ d->channel_exists = 0;
+ d->group_channel_limit_pass = 0;
+ d->msg_id = sub->last_msgid;
+-
+- if(sub->cf->subscribe_only_existing_channel || sub->cf->max_channel_subscribers > 0) {
++
++ if(sub->cf->redis.enabled && memstore_slot() != owner) {
++ ngx_int_t rc;
+ sub->fn->reserve(sub);
+ d->reserved = 1;
+- if(memstore_slot() != owner) {
+- ngx_int_t rc;
+- rc = memstore_ipc_send_channel_existence_check(owner, channel_id, sub->cf, (callback_pt )nchan_store_subscribe_channel_existence_check_callback, d);
+- if(rc == NGX_DECLINED) { // out of memory
+- nchan_store_subscribe_channel_existence_check_callback(SUB_CHANNEL_UNAUTHORIZED, NULL, d);
+- return NGX_ERROR;
++ rc = memstore_ipc_send_redis_conn_ready(d->channel_owner, sub->cf, (callback_pt)nchan_store_subscribe_stage2, d);
++ if(rc == NGX_DECLINED) { // out of memory
++ nchan_store_subscribe_stage2(0, NULL, d);
++ return NGX_ERROR;
++ }
++ } else {
++ return nchan_store_subscribe_stage2(1, NULL, d);
++ }
++ return NGX_OK;
++}
++
++static ngx_int_t nchan_store_subscribe_stage2(ngx_int_t continue_subscription, void* _, subscribe_data_t *d) {
++ if(continue_subscription) {
++ if(d->sub->cf->subscribe_only_existing_channel || d->sub->cf->max_channel_subscribers > 0) {
++ if(!d->reserved) {
++ d->sub->fn->reserve(d->sub);
++ d->reserved = 1;
++ }
++ if(memstore_slot() != d->channel_owner) {
++ ngx_int_t rc;
++ rc = memstore_ipc_send_channel_existence_check(d->channel_owner, d->channel_id, d->sub->cf, (callback_pt )nchan_store_subscribe_channel_existence_check_callback, d);
++ if(rc == NGX_DECLINED) { // out of memory
++ nchan_store_subscribe_channel_existence_check_callback(SUB_CHANNEL_UNAUTHORIZED, NULL, d);
++ return NGX_ERROR;
++ }
++ }
++ else {
++ return nchan_store_subscribe_stage3(SUB_CHANNEL_NOTSURE, NULL, d);
+ }
+ }
+ else {
+- return nchan_store_subscribe_continued(SUB_CHANNEL_NOTSURE, NULL, d);
++ return nchan_store_subscribe_stage3(SUB_CHANNEL_AUTHORIZED, NULL, d);
+ }
+- }
+- else {
+- return nchan_store_subscribe_continued(SUB_CHANNEL_AUTHORIZED, NULL, d);
++ } else {
++ //using redis, and it's not ready yet
++ if(d->sub->fn->release(d->sub, 0) == NGX_OK) {
++ d->reserved = 0;
++ nchan_respond_status(d->sub->request, NGX_HTTP_SERVICE_UNAVAILABLE, NULL, NULL, 0);
++ }
++ subscribe_data_free(d);
+ }
+ return NGX_OK;
+ }
+@@ -2120,7 +2148,7 @@ static ngx_int_t nchan_store_subscribe(ngx_str_t *channel_id, subscriber_t *sub)
+ static ngx_int_t nchan_store_subscribe_channel_existence_check_callback(ngx_int_t channel_status, void* _, subscribe_data_t *d) {
+ if(d->sub->fn->release(d->sub, 0) == NGX_OK) {
+ d->reserved = 0;
+- return nchan_store_subscribe_continued(channel_status, _, d);
++ return nchan_store_subscribe_stage3(channel_status, _, d);
+ }
+ else {//don't go any further, the sub has been deleted
+ subscribe_data_free(d);
+@@ -2143,7 +2171,7 @@ static ngx_int_t redis_subscribe_channel_existence_callback(ngx_int_t status, vo
+ /*
+ else if (cf->max_channel_subscribers > 0) {
+ // don't check this anymore -- a total subscribers count check is less
+- // useful as a per-instance check, which is handled in nchan_store_subscribe_continued
++ // useful as a per-instance check, which is handled in nchan_store_subscribe_stage3
+ // shared total subscriber count check can be re-enabled with another config setting
+ channel_status = channel->subscribers >= cf->max_channel_subscribers ? SUB_CHANNEL_UNAUTHORIZED : SUB_CHANNEL_AUTHORIZED;
+ }
+@@ -2152,7 +2180,7 @@ static ngx_int_t redis_subscribe_channel_existence_callback(ngx_int_t status, vo
+ channel_status = SUB_CHANNEL_AUTHORIZED;
+
+ }
+- nchan_store_subscribe_continued(channel_status, NULL, data);
++ nchan_store_subscribe_stage3(channel_status, NULL, data);
+ }
+ else {
+ //error!!
+@@ -2196,7 +2224,7 @@ static ngx_int_t group_subscribe_channel_limit_reached(ngx_int_t rc, nchan_chann
+ if(d->sub->status != DEAD) {
+ if(chaninfo) {
+ //ok, channel already exists.
+- nchan_store_subscribe_continued(SUB_CHANNEL_AUTHORIZED, NULL, d);
++ nchan_store_subscribe_stage3(SUB_CHANNEL_AUTHORIZED, NULL, d);
+ }
+ else {
+ //nope. no channel, no subscribing.
+@@ -2219,14 +2247,14 @@ static ngx_int_t group_subscribe_channel_limit_check(ngx_int_t _, nchan_group_t
+ if(shm_group) {
+ if(!shm_group->limit.channels || (shm_group->channels < shm_group->limit.channels)) {
+ d->group_channel_limit_pass = 1;
+- rc = nchan_store_subscribe_continued(SUB_CHANNEL_AUTHORIZED, NULL, d);
++ rc = nchan_store_subscribe_stage3(SUB_CHANNEL_AUTHORIZED, NULL, d);
+ }
+ else if (shm_group->limit.channels && shm_group->channels == shm_group->limit.channels){
+ //no new channels!
+ rc = nchan_store_find_channel(d->channel_id, d->sub->cf, (callback_pt )group_subscribe_channel_limit_reached, d);
+ }
+ else {
+- rc = nchan_store_subscribe_continued(SUB_CHANNEL_UNAUTHORIZED, NULL, d);
++ rc = nchan_store_subscribe_stage3(SUB_CHANNEL_UNAUTHORIZED, NULL, d);
+ }
+
+ }
+@@ -2246,7 +2274,7 @@ static ngx_int_t group_subscribe_channel_limit_check(ngx_int_t _, nchan_group_t
+ return rc;
+ }
+
+-static ngx_int_t nchan_store_subscribe_continued(ngx_int_t channel_status, void* _, subscribe_data_t *d) {
++static ngx_int_t nchan_store_subscribe_stage3(ngx_int_t channel_status, void* _, subscribe_data_t *d) {
+ memstore_channel_head_t *chanhead = NULL;
+ int retry_null_chanhead = 1;
+ //store_message_t *chmsg;
diff --git a/main/nginx/nginx-module-vts~cast-key-length-to-correct-type.patch b/main/nginx/nginx-module-vts~cast-key-length-to-correct-type.patch
deleted file mode 100644
index e29d52ffd44..00000000000
--- a/main/nginx/nginx-module-vts~cast-key-length-to-correct-type.patch
+++ /dev/null
@@ -1,24 +0,0 @@
-From 63b917ff8b6755bc6b7e30d4f61daad4b7817372 Mon Sep 17 00:00:00 2001
-From: Jonathan Giddy <jgiddy@mesosphere.com>
-Date: Fri, 22 Mar 2019 21:59:57 +0000
-Subject: [PATCH] Cast key length to correct type
-
----
- src/ngx_http_vhost_traffic_status_shm.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-Patch-Source: https://github.com/vozlt/nginx-module-vts/pull/161
-
-diff --git a/src/ngx_http_vhost_traffic_status_shm.c b/src/ngx_http_vhost_traffic_status_shm.c
-index 8066fc0..d87336f 100644
---- a/src/ngx_http_vhost_traffic_status_shm.c
-+++ b/src/ngx_http_vhost_traffic_status_shm.c
-@@ -147,7 +147,7 @@ ngx_http_vhost_traffic_status_shm_add_node(ngx_http_request_t *r,
- vtsn = (ngx_http_vhost_traffic_status_node_t *) &node->color;
-
- node->key = hash;
-- vtsn->len = (u_char) key->len;
-+ vtsn->len = (u_short) key->len;
- ngx_http_vhost_traffic_status_node_init(r, vtsn);
- vtsn->stat_upstream.type = type;
- ngx_memcpy(vtsn->data, key->data, key->len);
diff --git a/main/nginx/nginx-module-vts~fix-uri-overflow.patch b/main/nginx/nginx-module-vts~fix-uri-overflow.patch
deleted file mode 100644
index 840b5bc0805..00000000000
--- a/main/nginx/nginx-module-vts~fix-uri-overflow.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From 5c58aaaa0e3ade270ef0d0534def769a4b3a8b26 Mon Sep 17 00:00:00 2001
-From: spacewander <spacewanderlzx@gmail.com>
-Date: Thu, 20 Aug 2020 16:34:58 +0800
-Subject: [PATCH] fix: limit the r->uri search scope to avoid overflow
-
-r->uri doesn't end with '\0'.
-
----
- src/ngx_http_vhost_traffic_status_display.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
-Patch-Source: https://github.com/vozlt/nginx-module-vts/pull/188
-
-diff --git a/src/ngx_http_vhost_traffic_status_display.c b/src/ngx_http_vhost_traffic_status_display.c
-index c0d106a..10b5a62 100644
---- a/src/ngx_http_vhost_traffic_status_display.c
-+++ b/src/ngx_http_vhost_traffic_status_display.c
-@@ -38,10 +38,10 @@ ngx_http_vhost_traffic_status_display_handler(ngx_http_request_t *r)
-
- len = 0;
-
-- p = (u_char *) ngx_strchr(r->uri.data, '/');
-+ p = (u_char *) ngx_strlchr(r->uri.data, r->uri.data + r->uri.len, '/');
-
- if (p) {
-- p = (u_char *) ngx_strchr(p + 1, '/');
-+ p = (u_char *) ngx_strlchr(p + 1, r->uri.data + r->uri.len, '/');
- len = r->uri.len - (p - r->uri.data);
- }
-
diff --git a/main/nginx/nginx-module-vts~set-histogram-buckets-on-first-request.patch b/main/nginx/nginx-module-vts~set-histogram-buckets-on-first-request.patch
deleted file mode 100644
index c15d0a30d79..00000000000
--- a/main/nginx/nginx-module-vts~set-histogram-buckets-on-first-request.patch
+++ /dev/null
@@ -1,147 +0,0 @@
-From 25cba1362d42f483f797651609100e732f53cb37 Mon Sep 17 00:00:00 2001
-From: Jonathan Giddy <jgiddy@mesosphere.com>
-Date: Fri, 29 Mar 2019 17:00:19 +0000
-Subject: [PATCH] Set histogram buckets on first request
-
-The `ngx_http_vhost_traffic_status_node_init` function initializes
-the data structures and processes the first request. However it
-was not updating the histogram buckets. Refactor the common code
-from this function and `ngx_http_vhost_traffic_status_node_set`
-into a common `ngx_http_vhost_traffic_status_node_update` function
-to fix this and to reduce the chance of similar problems.
----
- src/ngx_http_vhost_traffic_status_node.c | 59 +++++++++++-------------
- src/ngx_http_vhost_traffic_status_node.h | 2 +
- 2 files changed, 30 insertions(+), 31 deletions(-)
-
-Patch-Source: https://github.com/vozlt/nginx-module-vts/pull/163
-
-diff --git a/src/ngx_http_vhost_traffic_status_node.c b/src/ngx_http_vhost_traffic_status_node.c
-index 1688bee..b91f2ce 100644
---- a/src/ngx_http_vhost_traffic_status_node.c
-+++ b/src/ngx_http_vhost_traffic_status_node.c
-@@ -312,12 +312,15 @@ ngx_http_vhost_traffic_status_node_zero(ngx_http_vhost_traffic_status_node_t *vt
-
- }
-
--
-+/*
-+ Initialize the node and update it with the first request.
-+ Set the `stat_request_time` to the time of the first request.
-+*/
- void
- ngx_http_vhost_traffic_status_node_init(ngx_http_request_t *r,
- ngx_http_vhost_traffic_status_node_t *vtsn)
- {
-- ngx_uint_t status = r->headers_out.status;
-+ ngx_msec_int_t ms;
-
- /* init serverZone */
- ngx_http_vhost_traffic_status_node_zero(vtsn);
-@@ -333,49 +336,50 @@ ngx_http_vhost_traffic_status_node_init(ngx_http_request_t *r,
- &vtsn->stat_upstream.response_buckets);
-
- /* set serverZone */
-- vtsn->stat_request_counter = 1;
-- vtsn->stat_in_bytes = (ngx_atomic_uint_t) r->request_length;
-- vtsn->stat_out_bytes = (ngx_atomic_uint_t) r->connection->sent;
--
-- ngx_http_vhost_traffic_status_add_rc(status, vtsn);
--
-- vtsn->stat_request_time = (ngx_msec_t) ngx_http_vhost_traffic_status_request_time(r);
-- vtsn->stat_request_time_counter = (ngx_atomic_uint_t) vtsn->stat_request_time;
--
-- ngx_http_vhost_traffic_status_node_time_queue_insert(&vtsn->stat_request_times,
-- vtsn->stat_request_time);
--
--#if (NGX_HTTP_CACHE)
-- if (r->upstream != NULL && r->upstream->cache_status != 0) {
-- ngx_http_vhost_traffic_status_add_cc(r->upstream->cache_status, vtsn);
-- }
--#endif
-+ ms = ngx_http_vhost_traffic_status_request_time(r);
-+ vtsn->stat_request_time = (ngx_msec_t) ms;
-
-+ ngx_http_vhost_traffic_status_node_update(r, vtsn, ms);
- }
-
--
-+/*
-+ Update the node from a subsequent request. Now there is more than one request,
-+ calculate the average request time.
-+*/
- void
- ngx_http_vhost_traffic_status_node_set(ngx_http_request_t *r,
- ngx_http_vhost_traffic_status_node_t *vtsn)
- {
-- ngx_uint_t status;
- ngx_msec_int_t ms;
- ngx_http_vhost_traffic_status_node_t ovtsn;
- ngx_http_vhost_traffic_status_loc_conf_t *vtscf;
-
- vtscf = ngx_http_get_module_loc_conf(r, ngx_http_vhost_traffic_status_module);
-
-- status = r->headers_out.status;
- ovtsn = *vtsn;
-
-+ ms = ngx_http_vhost_traffic_status_request_time(r);
-+ ngx_http_vhost_traffic_status_node_update(r, vtsn, ms);
-+
-+ vtsn->stat_request_time = ngx_http_vhost_traffic_status_node_time_queue_average(
-+ &vtsn->stat_request_times, vtscf->average_method,
-+ vtscf->average_period);
-+
-+ ngx_http_vhost_traffic_status_add_oc((&ovtsn), vtsn);
-+}
-+
-+void
-+ngx_http_vhost_traffic_status_node_update(ngx_http_request_t *r,
-+ ngx_http_vhost_traffic_status_node_t *vtsn, ngx_msec_int_t ms)
-+{
-+ ngx_uint_t status = r->headers_out.status;
-+
- vtsn->stat_request_counter++;
- vtsn->stat_in_bytes += (ngx_atomic_uint_t) r->request_length;
- vtsn->stat_out_bytes += (ngx_atomic_uint_t) r->connection->sent;
-
- ngx_http_vhost_traffic_status_add_rc(status, vtsn);
-
-- ms = ngx_http_vhost_traffic_status_request_time(r);
--
- vtsn->stat_request_time_counter += (ngx_atomic_uint_t) ms;
-
- ngx_http_vhost_traffic_status_node_time_queue_insert(&vtsn->stat_request_times,
-@@ -384,20 +388,13 @@ ngx_http_vhost_traffic_status_node_set(ngx_http_request_t *r,
- ngx_http_vhost_traffic_status_node_histogram_observe(&vtsn->stat_request_buckets,
- ms);
-
-- vtsn->stat_request_time = ngx_http_vhost_traffic_status_node_time_queue_average(
-- &vtsn->stat_request_times, vtscf->average_method,
-- vtscf->average_period);
--
- #if (NGX_HTTP_CACHE)
- if (r->upstream != NULL && r->upstream->cache_status != 0) {
- ngx_http_vhost_traffic_status_add_cc(r->upstream->cache_status, vtsn);
- }
- #endif
--
-- ngx_http_vhost_traffic_status_add_oc((&ovtsn), vtsn);
- }
-
--
- void
- ngx_http_vhost_traffic_status_node_time_queue_zero(
- ngx_http_vhost_traffic_status_node_time_queue_t *q)
-diff --git a/src/ngx_http_vhost_traffic_status_node.h b/src/ngx_http_vhost_traffic_status_node.h
-index 9ea6f23..3bbb53e 100644
---- a/src/ngx_http_vhost_traffic_status_node.h
-+++ b/src/ngx_http_vhost_traffic_status_node.h
-@@ -118,6 +118,8 @@ void ngx_http_vhost_traffic_status_node_init(ngx_http_request_t *r,
- ngx_http_vhost_traffic_status_node_t *vtsn);
- void ngx_http_vhost_traffic_status_node_set(ngx_http_request_t *r,
- ngx_http_vhost_traffic_status_node_t *vtsn);
-+void ngx_http_vhost_traffic_status_node_update(ngx_http_request_t *r,
-+ ngx_http_vhost_traffic_status_node_t *vtsn, ngx_msec_int_t ms);
-
- void ngx_http_vhost_traffic_status_node_time_queue_zero(
- ngx_http_vhost_traffic_status_node_time_queue_t *q);
diff --git a/main/nginx/nginx-upload-module~fix-nginx-compat.patch b/main/nginx/nginx-upload-module~fix-nginx-compat.patch
new file mode 100644
index 00000000000..474a84fec4b
--- /dev/null
+++ b/main/nginx/nginx-upload-module~fix-nginx-compat.patch
@@ -0,0 +1,40 @@
+Patch-Source: https://github.com/fdintino/nginx-upload-module/commit/96e64603dc5a588a2d1ae59a62b0019d6b41070c
+--
+From 96e64603dc5a588a2d1ae59a62b0019d6b41070c Mon Sep 17 00:00:00 2001
+From: Karthikdasari0423 <92445174+Karthikdasari0423@users.noreply.github.com>
+Date: Thu, 22 Jun 2023 01:40:07 +0530
+Subject: [PATCH] Update ngx_http_upload_module.c (#147)
+
+* Update ngx_http_upload_module.c
+
+* Fix whitespace
+
+---------
+
+Co-authored-by: Frankie Dintino <fdintino@gmail.com>
+---
+ ngx_http_upload_module.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/ngx_http_upload_module.c b/ngx_http_upload_module.c
+index c51429f..66150f0 100644
+--- a/ngx_http_upload_module.c
++++ b/ngx_http_upload_module.c
+@@ -12,7 +12,7 @@
+
+ #include <ngx_md5.h>
+
+-typedef ngx_md5_t MD5_CTX;
++typedef ngx_md5_t MD5_CTX1;
+
+ #define MD5Init ngx_md5_init
+ #define MD5Update ngx_md5_update
+@@ -189,7 +189,7 @@ typedef struct {
+ } ngx_http_upload_loc_conf_t;
+
+ typedef struct ngx_http_upload_md5_ctx_s {
+- MD5_CTX md5;
++ MD5_CTX1 md5;
+ u_char md5_digest[MD5_DIGEST_LENGTH * 2];
+ } ngx_http_upload_md5_ctx_t;
+
diff --git a/main/nginx/nginx-upload-module~fixes.patch b/main/nginx/nginx-upload-module~fixes.patch
new file mode 100644
index 00000000000..423647d8089
--- /dev/null
+++ b/main/nginx/nginx-upload-module~fixes.patch
@@ -0,0 +1,620 @@
+git diff 2.3.0..643b4c1fa6993da6bc1f82e7121ca62a7696ee6b ngx_http_upload_module.c
+--
+commit 643b4c1fa6993da6bc1f82e7121ca62a7696ee6b
+Author: Frankie Dintino <fdintino@gmail.com>
+Date: Sun Jun 21 17:09:17 2020 -0400
+
+ Fix bug caused by uploading a single byte range
+
+ fixes #115
+
+commit 1ac57ac4d37bfb0c09337f2eef3fab5a1c1e9a38
+Author: Romain Pomier <romain@cardiologs.com>
+Date: Wed Apr 8 18:42:38 2020 +0200
+
+ Handle quotes problems in Content-Type and Content-Disposition
+
+commit 1b0c530a3abf5c8782feabcfa2e89a312687f968
+Author: Frankie Dintino <fdintino@gmail.com>
+Date: Mon Feb 10 12:48:52 2020 -0500
+
+ Fix issue where upload headers were only added to final request
+
+ fixes #124
+
+commit a350ce9d6814438db56428ad6365db994dbd27f6
+Author: Valery Kholodkov <valery@coldrift.com>
+Date: Mon Nov 18 18:04:55 2019 +0100
+
+ Update read handler
+
+commit 8d50edd32ae788c3e0c12fe1940007e9faa3f15d
+Author: Demid Rudak <demid.r@didww.com>
+Date: Mon Apr 1 15:37:52 2019 +0300
+
+ Fixed upload_aggregate_form_field 'upload_file_md5' calculation
+
+commit 666428bf8ea3ee3e5bd40aaa693624234feb6da3
+Author: Frankie Dintino <fdintino@gmail.com>
+Date: Fri Aug 10 11:39:01 2018 -0400
+
+ Fix and add tests for upload_add_header
+
+commit e8d93f8f37db62f2588c7b3a20c873514fce4f5d
+Author: Frankie Dintino <fdintino@gmail.com>
+Date: Fri Aug 10 11:35:16 2018 -0400
+
+ Remove unnecessary ngx_http_upload_variable_set function
+
+commit 9c58c8ae9b3f4d44a28eebdffbdc1ab4224e3f90
+Author: Frankie Dintino <fdintino@gmail.com>
+Date: Mon Aug 6 09:38:52 2018 -0400
+
+ Fix bug when uc and lc hash aggregate fields present in the same request
+--
+diff --git a/ngx_http_upload_module.c b/ngx_http_upload_module.c
+index 3ac3279..c51429f 100644
+--- a/ngx_http_upload_module.c
++++ b/ngx_http_upload_module.c
+@@ -55,8 +55,8 @@ typedef ngx_md5_t MD5_CTX;
+ #define X_SESSION_ID_STRING "X-Session-ID:"
+ #define FORM_DATA_STRING "form-data"
+ #define ATTACHMENT_STRING "attachment"
+-#define FILENAME_STRING "filename=\""
+-#define FIELDNAME_STRING "name=\""
++#define FILENAME_STRING "filename="
++#define FIELDNAME_STRING "name="
+ #define BYTES_UNIT_STRING "bytes "
+
+ #define NGX_UPLOAD_MALFORMED -11
+@@ -302,8 +302,6 @@ static void *ngx_http_upload_create_loc_conf(ngx_conf_t *cf);
+ static char *ngx_http_upload_merge_loc_conf(ngx_conf_t *cf,
+ void *parent, void *child);
+ static ngx_int_t ngx_http_upload_add_variables(ngx_conf_t *cf);
+-static void ngx_http_upload_variable_set(ngx_http_request_t *r,
+- ngx_http_variable_value_t *v, uintptr_t data);
+ static ngx_int_t ngx_http_upload_variable(ngx_http_request_t *r,
+ ngx_http_variable_value_t *v, uintptr_t data);
+ static ngx_int_t ngx_http_upload_md5_variable(ngx_http_request_t *r,
+@@ -326,6 +324,10 @@ static ngx_int_t ngx_http_upload_uint_variable(ngx_http_request_t *r,
+ ngx_http_variable_value_t *v, uintptr_t data);
+ static char *ngx_http_upload_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
+
++static ngx_int_t
++ngx_http_upload_process_field_templates(ngx_http_request_t *r,
++ ngx_http_upload_field_template_t *t, ngx_str_t *field_name, ngx_str_t *field_value);
++
+ static ngx_int_t ngx_http_upload_start_handler(ngx_http_upload_ctx_t *u);
+ static void ngx_http_upload_finish_handler(ngx_http_upload_ctx_t *u);
+ static void ngx_http_upload_abort_handler(ngx_http_upload_ctx_t *u);
+@@ -345,9 +347,7 @@ static ngx_int_t ngx_http_read_upload_client_request_body(ngx_http_request_t *r)
+
+ static char *ngx_http_upload_set_form_field(ngx_conf_t *cf, ngx_command_t *cmd,
+ void *conf);
+-static char *ngx_http_upload_add_header(ngx_conf_t *cf, ngx_command_t *cmd,
+- void *conf);
+-static ngx_int_t ngx_http_upload_eval_path(ngx_http_request_t *r);
++ static ngx_int_t ngx_http_upload_eval_path(ngx_http_request_t *r);
+ static ngx_int_t ngx_http_upload_eval_state_path(ngx_http_request_t *r);
+ static char *ngx_http_upload_pass_form_field(ngx_conf_t *cf, ngx_command_t *cmd,
+ void *conf);
+@@ -666,7 +666,7 @@ static ngx_command_t ngx_http_upload_commands[] = { /* {{{ */
+ { ngx_string("upload_add_header"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LMT_CONF|NGX_HTTP_LIF_CONF
+ |NGX_CONF_TAKE2,
+- ngx_http_upload_add_header,
++ ngx_http_upload_set_form_field,
+ NGX_HTTP_LOC_CONF_OFFSET,
+ offsetof(ngx_http_upload_loc_conf_t, header_templates),
+ NULL},
+@@ -710,7 +710,7 @@ static ngx_http_variable_t ngx_http_upload_variables[] = { /* {{{ */
+ NGX_HTTP_VAR_CHANGEABLE|NGX_HTTP_VAR_NOCACHEABLE|NGX_HTTP_VAR_NOHASH, 0 },
+
+ { ngx_string("upload_content_type"),
+- ngx_http_upload_variable_set,
++ NULL,
+ ngx_http_upload_variable,
+ (uintptr_t) offsetof(ngx_http_upload_ctx_t, content_type),
+ NGX_HTTP_VAR_CHANGEABLE|NGX_HTTP_VAR_NOCACHEABLE|NGX_HTTP_VAR_NOHASH, 0 },
+@@ -1052,18 +1052,14 @@ err:
+ static ngx_int_t ngx_http_upload_add_headers(ngx_http_request_t *r, ngx_http_upload_loc_conf_t *ulcf) { /* {{{ */
+ ngx_str_t name;
+ ngx_str_t value;
+- ngx_http_upload_header_template_t *t;
++ ngx_http_upload_field_template_t *t;
+ ngx_table_elt_t *h;
+ ngx_uint_t i;
+
+- if(ulcf->header_templates != NULL) {
++ if (ulcf->header_templates != NULL) {
+ t = ulcf->header_templates->elts;
+- for(i = 0; i < ulcf->header_templates->nelts; i++) {
+- if(ngx_http_complex_value(r, t->name, &name) != NGX_OK) {
+- return NGX_ERROR;
+- }
+-
+- if(ngx_http_complex_value(r, t->value, &value) != NGX_OK) {
++ for (i = 0; i < ulcf->header_templates->nelts; i++) {
++ if (ngx_http_upload_process_field_templates(r, &t[i], &name, &value) != NGX_OK) {
+ return NGX_ERROR;
+ }
+
+@@ -1079,8 +1075,6 @@ static ngx_int_t ngx_http_upload_add_headers(ngx_http_request_t *r, ngx_http_upl
+ h->value.len = value.len;
+ h->value.data = value.data;
+ }
+-
+- t++;
+ }
+ }
+
+@@ -1180,10 +1174,6 @@ static ngx_int_t ngx_http_upload_body_handler(ngx_http_request_t *r) { /* {{{ */
+ ngx_str_t dummy = ngx_string("<ngx_upload_module_dummy>");
+ ngx_table_elt_t *h;
+
+- if(ngx_http_upload_add_headers(r, ulcf) != NGX_OK) {
+- return NGX_HTTP_INTERNAL_SERVER_ERROR;
+- }
+-
+ if(ctx->prevent_output) {
+ r->headers_out.status = NGX_HTTP_CREATED;
+
+@@ -1360,6 +1350,27 @@ static ngx_int_t ngx_http_upload_body_handler(ngx_http_request_t *r) { /* {{{ */
+ return rc;
+ } /* }}} */
+
++static ngx_int_t
++ngx_http_upload_process_field_templates(
++ ngx_http_request_t *r, ngx_http_upload_field_template_t *t,
++ ngx_str_t *name, ngx_str_t *value)
++{
++ if (t->field_lengths == NULL) {
++ *name = t->value.key;
++ } else if (ngx_http_script_run(r, name, t->field_lengths->elts, 0,
++ t->field_values->elts) == NULL) {
++ return NGX_UPLOAD_SCRIPTERROR;
++ }
++
++ if (t->value_lengths == NULL) {
++ *value = t->value.value;
++ } else if (ngx_http_script_run(r, value, t->value_lengths->elts, 0,
++ t->value_values->elts) == NULL) {
++ return NGX_UPLOAD_SCRIPTERROR;
++ }
++ return NGX_OK;
++}
++
+ static ngx_int_t ngx_http_upload_start_handler(ngx_http_upload_ctx_t *u) { /* {{{ */
+ ngx_http_request_t *r = u->request;
+ ngx_http_upload_loc_conf_t *ulcf = ngx_http_get_module_loc_conf(r, ngx_http_upload_module);
+@@ -1495,28 +1506,10 @@ static ngx_int_t ngx_http_upload_start_handler(ngx_http_upload_ctx_t *u) { /* {{
+
+ t = ulcf->field_templates->elts;
+ for (i = 0; i < ulcf->field_templates->nelts; i++) {
++ rc = ngx_http_upload_process_field_templates(r, &t[i], &field_name, &field_value);
+
+- if (t[i].field_lengths == NULL) {
+- field_name = t[i].value.key;
+- }else{
+- if (ngx_http_script_run(r, &field_name, t[i].field_lengths->elts, 0,
+- t[i].field_values->elts) == NULL)
+- {
+- rc = NGX_UPLOAD_SCRIPTERROR;
+- goto cleanup_file;
+- }
+- }
+-
+- if (t[i].value_lengths == NULL) {
+- field_value = t[i].value.value;
+- }else{
+- if (ngx_http_script_run(r, &field_value, t[i].value_lengths->elts, 0,
+- t[i].value_values->elts) == NULL)
+- {
+- rc = NGX_UPLOAD_SCRIPTERROR;
+- goto cleanup_file;
+- }
+- }
++ if(rc != NGX_OK)
++ goto cleanup_file;
+
+ rc = ngx_http_upload_append_field(u, &field_name, &field_value);
+
+@@ -1603,6 +1596,11 @@ static ngx_int_t ngx_http_upload_start_handler(ngx_http_upload_ctx_t *u) { /* {{
+ u->discard_data = 1;
+ }
+
++
++ if(ngx_http_upload_add_headers(r, ulcf) != NGX_OK) {
++ return NGX_HTTP_INTERNAL_SERVER_ERROR;
++ }
++
+ return NGX_OK;
+
+ cleanup_file:
+@@ -1697,25 +1695,10 @@ static void ngx_http_upload_finish_handler(ngx_http_upload_ctx_t *u) { /* {{{ */
+ if(ulcf->aggregate_field_templates) {
+ af = ulcf->aggregate_field_templates->elts;
+ for (i = 0; i < ulcf->aggregate_field_templates->nelts; i++) {
+-
+- if (af[i].field_lengths == NULL) {
+- aggregate_field_name = af[i].value.key;
+- }else{
+- if (ngx_http_script_run(r, &aggregate_field_name, af[i].field_lengths->elts, 0,
+- af[i].field_values->elts) == NULL)
+- {
+- goto rollback;
+- }
+- }
+-
+- if (af[i].value_lengths == NULL) {
+- aggregate_field_value = af[i].value.value;
+- }else{
+- if (ngx_http_script_run(r, &aggregate_field_value, af[i].value_lengths->elts, 0,
+- af[i].value_values->elts) == NULL)
+- {
+- goto rollback;
+- }
++ rc = ngx_http_upload_process_field_templates(r, &af[i], &aggregate_field_name,
++ &aggregate_field_value);
++ if (rc != NGX_OK) {
++ goto rollback;
+ }
+
+ rc = ngx_http_upload_append_field(u, &aggregate_field_name, &aggregate_field_value);
+@@ -2001,7 +1984,7 @@ ngx_http_upload_buf_merge_range(ngx_http_upload_merger_state_t *ms, ngx_http_upl
+ return NGX_ERROR;
+ }
+
+- if(ms->current_range_n.start >= ms->current_range_n.end || ms->current_range_n.start >= ms->current_range_n.total
++ if(ms->current_range_n.start > ms->current_range_n.end || ms->current_range_n.start > ms->current_range_n.total
+ || ms->current_range_n.end > ms->current_range_n.total)
+ {
+ ngx_log_debug3(NGX_LOG_DEBUG_CORE, ms->log, 0,
+@@ -2398,21 +2381,6 @@ ngx_http_upload_add_variables(ngx_conf_t *cf)
+ return NGX_OK;
+ } /* }}} */
+
+-static void /* {{{ ngx_http_upload_variable_set */
+-ngx_http_upload_variable_set(ngx_http_request_t *r,
+- ngx_http_variable_value_t *v, uintptr_t data)
+-{
+- ngx_str_t *s;
+- ngx_http_upload_ctx_t *u;
+-
+- u = ngx_http_get_module_ctx(r, ngx_http_upload_module);
+-
+- s = (ngx_str_t *) ((char *) u + data);
+-
+- s->len = v->len;
+- s->data = v->data;
+-} /* }}} */
+-
+ static ngx_int_t /* {{{ ngx_http_upload_variable */
+ ngx_http_upload_variable(ngx_http_request_t *r,
+ ngx_http_variable_value_t *v, uintptr_t data)
+@@ -2434,88 +2402,78 @@ ngx_http_upload_variable(ngx_http_request_t *r,
+ return NGX_OK;
+ } /* }}} */
+
+-static ngx_int_t /* {{{ ngx_http_upload_md5_variable */
+-ngx_http_upload_md5_variable(ngx_http_request_t *r,
+- ngx_http_variable_value_t *v, uintptr_t data)
++static ngx_int_t
++ngx_http_upload_hash_variable(ngx_http_request_t *r,
++ ngx_http_variable_value_t *v, uintptr_t data, u_char *digest,
++ ngx_uint_t digest_len)
+ {
+ ngx_uint_t i;
+- ngx_http_upload_ctx_t *u;
+ u_char *c;
++ u_char *p;
+ u_char *hex_table;
+
+- u = ngx_http_get_module_ctx(r, ngx_http_upload_module);
+-
+- if(u->md5_ctx == NULL || u->partial_content) {
+- v->not_found = 1;
+- return NGX_OK;
+- }
+-
+ v->valid = 1;
+ v->no_cacheable = 0;
+ v->not_found = 0;
+
+ hex_table = (u_char*)data;
+- c = u->md5_ctx->md5_digest + MD5_DIGEST_LENGTH * 2;
+
+- i = MD5_DIGEST_LENGTH;
++ p = ngx_palloc(r->pool, digest_len * 2);
++ if (p == NULL) {
++ return NGX_ERROR;
++ }
++
++ c = p + digest_len * 2;
++ i = digest_len;
+
+ do{
+ i--;
+- *--c = hex_table[u->md5_ctx->md5_digest[i] & 0xf];
+- *--c = hex_table[u->md5_ctx->md5_digest[i] >> 4];
++ *--c = hex_table[digest[i] & 0xf];
++ *--c = hex_table[digest[i] >> 4];
+ }while(i != 0);
+
+- v->data = u->md5_ctx->md5_digest;
+- v->len = MD5_DIGEST_LENGTH * 2;
++ v->data = c;
++ v->len = digest_len * 2;
+
+ return NGX_OK;
+ } /* }}} */
+
+-static ngx_int_t /* {{{ ngx_http_upload_sha1_variable */
+-ngx_http_upload_sha1_variable(ngx_http_request_t *r,
++static ngx_int_t /* {{{ ngx_http_upload_md5_variable */
++ngx_http_upload_md5_variable(ngx_http_request_t *r,
+ ngx_http_variable_value_t *v, uintptr_t data)
+ {
+- ngx_uint_t i;
+ ngx_http_upload_ctx_t *u;
+- u_char *c;
+- u_char *hex_table;
+
+ u = ngx_http_get_module_ctx(r, ngx_http_upload_module);
+
+- if(u->sha1_ctx == NULL || u->partial_content) {
++ if(u->md5_ctx == NULL || u->partial_content) {
+ v->not_found = 1;
+ return NGX_OK;
+ }
++ return ngx_http_upload_hash_variable(r, v, data, u->md5_ctx->md5_digest, MD5_DIGEST_LENGTH);
++} /* }}} */
+
+- v->valid = 1;
+- v->no_cacheable = 0;
+- v->not_found = 0;
+-
+- hex_table = (u_char*)data;
+- c = u->sha1_ctx->sha1_digest + SHA_DIGEST_LENGTH * 2;
+-
+- i = SHA_DIGEST_LENGTH;
++static ngx_int_t /* {{{ ngx_http_upload_sha1_variable */
++ngx_http_upload_sha1_variable(ngx_http_request_t *r,
++ ngx_http_variable_value_t *v, uintptr_t data)
++{
++ ngx_http_upload_ctx_t *u;
+
+- do{
+- i--;
+- *--c = hex_table[u->sha1_ctx->sha1_digest[i] & 0xf];
+- *--c = hex_table[u->sha1_ctx->sha1_digest[i] >> 4];
+- }while(i != 0);
++ u = ngx_http_get_module_ctx(r, ngx_http_upload_module);
+
+- v->data = u->sha1_ctx->sha1_digest;
+- v->len = SHA_DIGEST_LENGTH * 2;
++ if(u->sha1_ctx == NULL || u->partial_content) {
++ v->not_found = 1;
++ return NGX_OK;
++ }
+
+- return NGX_OK;
++ return ngx_http_upload_hash_variable(r, v, data, u->sha1_ctx->sha1_digest, SHA_DIGEST_LENGTH);
+ } /* }}} */
+
+ static ngx_int_t /* {{{ ngx_http_upload_sha256_variable */
+ ngx_http_upload_sha256_variable(ngx_http_request_t *r,
+ ngx_http_variable_value_t *v, uintptr_t data)
+ {
+- ngx_uint_t i;
+ ngx_http_upload_ctx_t *u;
+- u_char *c;
+- u_char *hex_table;
+
+ u = ngx_http_get_module_ctx(r, ngx_http_upload_module);
+
+@@ -2524,35 +2482,14 @@ ngx_http_upload_sha256_variable(ngx_http_request_t *r,
+ return NGX_OK;
+ }
+
+- v->valid = 1;
+- v->no_cacheable = 0;
+- v->not_found = 0;
+-
+- hex_table = (u_char*)data;
+- c = u->sha256_ctx->sha256_digest + SHA256_DIGEST_LENGTH * 2;
+-
+- i = SHA256_DIGEST_LENGTH;
+-
+- do{
+- i--;
+- *--c = hex_table[u->sha256_ctx->sha256_digest[i] & 0xf];
+- *--c = hex_table[u->sha256_ctx->sha256_digest[i] >> 4];
+- }while(i != 0);
+-
+- v->data = u->sha256_ctx->sha256_digest;
+- v->len = SHA256_DIGEST_LENGTH * 2;
+-
+- return NGX_OK;
++ return ngx_http_upload_hash_variable(r, v, data, u->sha256_ctx->sha256_digest, SHA256_DIGEST_LENGTH);
+ } /* }}} */
+
+ static ngx_int_t /* {{{ ngx_http_upload_sha512_variable */
+ ngx_http_upload_sha512_variable(ngx_http_request_t *r,
+ ngx_http_variable_value_t *v, uintptr_t data)
+ {
+- ngx_uint_t i;
+ ngx_http_upload_ctx_t *u;
+- u_char *c;
+- u_char *hex_table;
+
+ u = ngx_http_get_module_ctx(r, ngx_http_upload_module);
+
+@@ -2561,25 +2498,7 @@ ngx_http_upload_sha512_variable(ngx_http_request_t *r,
+ return NGX_OK;
+ }
+
+- v->valid = 1;
+- v->no_cacheable = 0;
+- v->not_found = 0;
+-
+- hex_table = (u_char*)data;
+- c = u->sha512_ctx->sha512_digest + SHA512_DIGEST_LENGTH * 2;
+-
+- i = SHA512_DIGEST_LENGTH;
+-
+- do{
+- i--;
+- *--c = hex_table[u->sha512_ctx->sha512_digest[i] & 0xf];
+- *--c = hex_table[u->sha512_ctx->sha512_digest[i] >> 4];
+- }while(i != 0);
+-
+- v->data = u->sha512_ctx->sha512_digest;
+- v->len = SHA512_DIGEST_LENGTH * 2;
+-
+- return NGX_OK;
++ return ngx_http_upload_hash_variable(r, v, data, u->sha512_ctx->sha512_digest, SHA512_DIGEST_LENGTH);
+ } /* }}} */
+
+ static ngx_int_t /* {{{ ngx_http_upload_crc32_variable */
+@@ -2922,73 +2841,6 @@ ngx_http_upload_pass_form_field(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
+ return NGX_CONF_OK;
+ } /* }}} */
+
+-static char * /* {{{ ngx_http_upload_add_header */
+-ngx_http_upload_add_header(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
+-{
+- ngx_str_t *value;
+- ngx_http_upload_header_template_t *h;
+- ngx_array_t **field;
+- ngx_http_compile_complex_value_t ccv;
+-
+- field = (ngx_array_t**) (((u_char*)conf) + cmd->offset);
+-
+- value = cf->args->elts;
+-
+- /*
+- * Add new entry to header template list
+- */
+- if (*field == NULL) {
+- *field = ngx_array_create(cf->pool, 1,
+- sizeof(ngx_http_upload_header_template_t));
+- if (*field == NULL) {
+- return NGX_CONF_ERROR;
+- }
+- }
+-
+- h = ngx_array_push(*field);
+- if (h == NULL) {
+- return NGX_CONF_ERROR;
+- }
+-
+- /*
+- * Compile header name
+- */
+- h->name = ngx_palloc(cf->pool, sizeof(ngx_http_complex_value_t));
+- if(h->name == NULL) {
+- return NGX_CONF_ERROR;
+- }
+-
+- ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
+-
+- ccv.cf = cf;
+- ccv.value = &value[1];
+- ccv.complex_value = h->name;
+-
+- if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
+- return NGX_CONF_ERROR;
+- }
+-
+- /*
+- * Compile header value
+- */
+- h->value = ngx_palloc(cf->pool, sizeof(ngx_http_complex_value_t));
+- if(h->value == NULL) {
+- return NGX_CONF_ERROR;
+- }
+-
+- ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
+-
+- ccv.cf = cf;
+- ccv.value = &value[2];
+- ccv.complex_value = h->value;
+-
+- if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
+- return NGX_CONF_ERROR;
+- }
+-
+- return NGX_CONF_OK;
+-} /* }}} */
+-
+ static char * /* {{{ ngx_http_upload_cleanup */
+ ngx_http_upload_cleanup(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
+ {
+@@ -3599,6 +3451,8 @@ ngx_http_do_read_upload_client_request_body(ngx_http_request_t *r)
+ ngx_del_timer(c->read);
+ }
+
++ r->read_event_handler = ngx_http_block_reading;
++
+ rc = ngx_http_process_request_body(r, u->to_write);
+
+ switch(rc) {
+@@ -3667,16 +3521,14 @@ static ngx_int_t upload_parse_content_disposition(ngx_http_upload_ctx_t *upload_
+
+ if(filename_start != 0) {
+
+- filename_start += sizeof(FILENAME_STRING)-1;
+-
+- filename_end = filename_start + strcspn(filename_start, "\"");
++ filename_start += sizeof(FILENAME_STRING) - 1;
+
+- if(*filename_end != '\"') {
+- ngx_log_debug0(NGX_LOG_DEBUG_CORE, upload_ctx->log, 0,
+- "malformed filename in part header");
+- return NGX_UPLOAD_MALFORMED;
++ if (*filename_start == '\"') {
++ filename_start++;
+ }
+
++ filename_end = filename_start + strcspn(filename_start, "\";");
++
+ /*
+ * IE sends full path, strip path from filename
+ * Also strip all UNIX path references
+@@ -3703,16 +3555,14 @@ static ngx_int_t upload_parse_content_disposition(ngx_http_upload_ctx_t *upload_
+ // }while((fieldname_start != 0) && (fieldname_start + sizeof(FIELDNAME_STRING) - 1 == filename_start));
+
+ if(fieldname_start != 0) {
+- fieldname_start += sizeof(FIELDNAME_STRING)-1;
++ fieldname_start += sizeof(FIELDNAME_STRING) - 1;
+
+- if(fieldname_start != filename_start) {
+- fieldname_end = fieldname_start + strcspn(fieldname_start, "\"");
++ if (*fieldname_start == '\"') {
++ fieldname_start++;
++ }
+
+- if(*fieldname_end != '\"') {
+- ngx_log_error(NGX_LOG_ERR, upload_ctx->log, 0,
+- "malformed fieldname in part header");
+- return NGX_UPLOAD_MALFORMED;
+- }
++ if(fieldname_start != filename_start) {
++ fieldname_end = fieldname_start + strcspn(fieldname_start, "\";");
+
+ upload_ctx->field_name.len = fieldname_end - fieldname_start;
+ upload_ctx->field_name.data = ngx_pcalloc(upload_ctx->request->pool, upload_ctx->field_name.len + 1);
+@@ -4087,6 +3937,12 @@ static ngx_int_t upload_parse_request_headers(ngx_http_upload_ctx_t *upload_ctx,
+ boundary_start_ptr += sizeof(BOUNDARY_STRING) - 1;
+ boundary_end_ptr = boundary_start_ptr + strcspn((char*)boundary_start_ptr, " ;\n\r");
+
++ // Handle quoted boundaries
++ if ((boundary_end_ptr - boundary_start_ptr) >= 2 && boundary_start_ptr[0] == '"' && *(boundary_end_ptr - 1) == '"') {
++ boundary_start_ptr++;
++ boundary_end_ptr--;
++ }
++
+ if(boundary_end_ptr == boundary_start_ptr) {
+ ngx_log_debug0(NGX_LOG_DEBUG_CORE, upload_ctx->log, 0,
+ "boundary is empty");
diff --git a/main/nginx/nginx-upload-progress-module~fix-http2.patch b/main/nginx/nginx-upload-progress-module~fix-http2.patch
new file mode 100644
index 00000000000..9886e1d7f09
--- /dev/null
+++ b/main/nginx/nginx-upload-progress-module~fix-http2.patch
@@ -0,0 +1,44 @@
+Patch-Source: https://github.com/masterzen/nginx-upload-progress-module/pull/57
+--
+From 594f1233c3c622ad51a2bde0c3289747af20e245 Mon Sep 17 00:00:00 2001
+From: Allan Jude <allanjude@freebsd.org>
+Date: Sat, 26 Nov 2022 20:28:10 +0000
+Subject: [PATCH] Restore functionality of upload-progress for HTTP2
+
+The upload-progress module was only getting notified of the first
+block of uploaded data, because r->read_event_handler was being
+reset by ngx_http_v2_read_request_body() and
+ngx_http_v2_process_request_body()
+
+The patch detects that situation, updates module_ctx to call the
+new function, then reinserts itself as the read_event_handler so
+we continue to be notified about uploaded data.
+
+Introduced in nginx/nginx@67d160bf25e02ba6679bb6c3b9cbdfeb29b759de
+
+Sponsored-by: ScaleEngine Inc.
+---
+ ngx_http_uploadprogress_module.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/ngx_http_uploadprogress_module.c b/ngx_http_uploadprogress_module.c
+index 33bdaf7..f17ad92 100644
+--- a/ngx_http_uploadprogress_module.c
++++ b/ngx_http_uploadprogress_module.c
+@@ -489,6 +489,16 @@ static void ngx_http_uploadprogress_event_handler(ngx_http_request_t *r)
+ module_ctx = ngx_http_get_module_ctx(r, ngx_http_uploadprogress_module);
+ if (module_ctx != NULL ) {
+ module_ctx->read_event_handler(r);
++ /*
++ * Both ngx_http_v2_read_request_body() and
++ * ngx_http_v2_process_request_body() modify read_event_handler,
++ * we respect the change, but re-interpose our function so we still get
++ * future events, otherwise we miss all upload progress.
++ */
++ if (r->read_event_handler != ngx_http_uploadprogress_event_handler) {
++ module_ctx->read_event_handler = r->read_event_handler;
++ r->read_event_handler = ngx_http_uploadprogress_event_handler;
++ }
+ }
+
+ /* at this stage, r is not anymore safe to use */
diff --git a/main/nginx/nginx-upload-progress-module~fix.patch b/main/nginx/nginx-upload-progress-module~fix.patch
new file mode 100644
index 00000000000..7d5fd1bde6d
--- /dev/null
+++ b/main/nginx/nginx-upload-progress-module~fix.patch
@@ -0,0 +1,937 @@
+Patch-Source: https://github.com/masterzen/nginx-upload-progress-module/compare/master...msva:nginx-upload-progress-module:master
+
+Ref https://github.com/masterzen/nginx-upload-progress-module/issues/56
+
+diff --git a/ngx_http_uploadprogress_module.c b/ngx_http_uploadprogress_module.c
+index 33bdaf7..577c146 100644
+--- a/ngx_http_uploadprogress_module.c
++++ b/ngx_http_uploadprogress_module.c
+@@ -8,6 +8,7 @@
+ #include <ngx_core.h>
+ #include <ngx_http.h>
+
++
+ #define TIMER_FREQUENCY 15 * 1000
+
+ typedef enum {
+@@ -31,6 +32,8 @@ struct ngx_http_uploadprogress_node_s {
+ off_t rest;
+ off_t length;
+ ngx_uint_t done;
++ ngx_uint_t sequence;
++ ngx_uint_t sent_portion;
+ time_t timeout;
+ struct ngx_http_uploadprogress_node_s *prev;
+ struct ngx_http_uploadprogress_node_s *next;
+@@ -65,7 +68,13 @@ typedef struct {
+ ngx_str_t content_type;
+ ngx_array_t templates;
+ ngx_str_t header;
++ ngx_str_t header_mul;
++
++ ngx_addr_t progress_server;
++ int udp_socket;
++
+ ngx_str_t jsonp_parameter;
++ ngx_int_t json_multiple:1;
+ } ngx_http_uploadprogress_conf_t;
+
+ typedef struct {
+@@ -87,6 +96,8 @@ static ngx_int_t ngx_http_uploadprogress_offset_variable(ngx_http_request_t *r,
+ ngx_http_variable_value_t *v, uintptr_t data);
+ static ngx_int_t ngx_http_uploadprogress_status_variable(ngx_http_request_t *r,
+ ngx_http_variable_value_t *v, uintptr_t data);
++static ngx_int_t ngx_http_uploadprogress_id_variable(ngx_http_request_t *r,
++ ngx_http_variable_value_t *v, uintptr_t data);
+ static ngx_int_t ngx_http_uploadprogress_callback_variable(ngx_http_request_t *r,
+ ngx_http_variable_value_t *v, uintptr_t data);
+ static char* ngx_http_upload_progress_set_template(ngx_conf_t * cf, ngx_http_uploadprogress_template_t *t, ngx_str_t *source);
+@@ -97,6 +108,8 @@ static char* ngx_http_upload_progress_template(ngx_conf_t * cf, ngx_command_t *
+ static char* ngx_http_upload_progress_java_output(ngx_conf_t * cf, ngx_command_t * cmd, void *conf);
+ static char* ngx_http_upload_progress_json_output(ngx_conf_t * cf, ngx_command_t * cmd, void *conf);
+ static char* ngx_http_upload_progress_jsonp_output(ngx_conf_t * cf, ngx_command_t * cmd, void *conf);
++static char* ngx_http_upload_progress_json_multiple_output(ngx_conf_t * cf, ngx_command_t * cmd, void *conf);
++static char* ngx_http_upload_progress_jsonp_multiple_output(ngx_conf_t * cf, ngx_command_t * cmd, void *conf);
+ static void ngx_clean_old_connections(ngx_event_t * ev);
+ static ngx_int_t ngx_http_uploadprogress_content_handler(ngx_http_request_t *r);
+
+@@ -112,7 +125,7 @@ static ngx_command_t ngx_http_uploadprogress_commands[] = {
+ NULL},
+
+ {ngx_string("track_uploads"),
+- NGX_HTTP_MAIN_CONF | NGX_HTTP_SRV_CONF | NGX_HTTP_LOC_CONF | NGX_CONF_TAKE2,
++ NGX_HTTP_MAIN_CONF | NGX_HTTP_SRV_CONF | NGX_HTTP_LOC_CONF | NGX_CONF_TAKE2 | NGX_CONF_TAKE3,
+ ngx_http_track_uploads,
+ NGX_HTTP_LOC_CONF_OFFSET,
+ 0,
+@@ -160,6 +173,20 @@ static ngx_command_t ngx_http_uploadprogress_commands[] = {
+ 0,
+ NULL},
+
++ {ngx_string("upload_progress_json_multiple_output"),
++ NGX_HTTP_MAIN_CONF | NGX_HTTP_SRV_CONF | NGX_HTTP_LOC_CONF | NGX_CONF_NOARGS,
++ ngx_http_upload_progress_json_multiple_output,
++ NGX_HTTP_LOC_CONF_OFFSET,
++ 0,
++ NULL},
++
++ {ngx_string("upload_progress_jsonp_multiple_output"),
++ NGX_HTTP_MAIN_CONF | NGX_HTTP_SRV_CONF | NGX_HTTP_LOC_CONF | NGX_CONF_NOARGS,
++ ngx_http_upload_progress_jsonp_multiple_output,
++ NGX_HTTP_LOC_CONF_OFFSET,
++ 0,
++ NULL},
++
+ {ngx_string("upload_progress_header"),
+ NGX_HTTP_MAIN_CONF | NGX_HTTP_SRV_CONF | NGX_HTTP_LOC_CONF | NGX_CONF_TAKE1,
+ ngx_conf_set_str_slot,
+@@ -167,6 +194,13 @@ static ngx_command_t ngx_http_uploadprogress_commands[] = {
+ offsetof(ngx_http_uploadprogress_conf_t, header),
+ NULL},
+
++ {ngx_string("upload_progress_header_mul"),
++ NGX_HTTP_MAIN_CONF | NGX_HTTP_SRV_CONF | NGX_HTTP_LOC_CONF | NGX_CONF_TAKE1,
++ ngx_conf_set_str_slot,
++ NGX_HTTP_LOC_CONF_OFFSET,
++ offsetof(ngx_http_uploadprogress_conf_t, header_mul),
++ NULL},
++
+ {ngx_string("upload_progress_jsonp_parameter"),
+ NGX_HTTP_MAIN_CONF | NGX_HTTP_SRV_CONF | NGX_HTTP_LOC_CONF | NGX_CONF_TAKE1,
+ ngx_conf_set_str_slot,
+@@ -195,6 +229,10 @@ static ngx_http_variable_t ngx_http_uploadprogress_variables[] = {
+ (uintptr_t) offsetof(ngx_http_uploadprogress_node_t, err_status),
+ NGX_HTTP_VAR_CHANGEABLE|NGX_HTTP_VAR_NOCACHEABLE|NGX_HTTP_VAR_NOHASH, 0 },
+
++ { ngx_string("uploadprogress_id"), NULL, ngx_http_uploadprogress_id_variable,
++ (uintptr_t) offsetof(ngx_http_uploadprogress_node_t, err_status),
++ NGX_HTTP_VAR_CHANGEABLE|NGX_HTTP_VAR_NOCACHEABLE|NGX_HTTP_VAR_NOHASH, 0 },
++
+ { ngx_string("uploadprogress_callback"), NULL, ngx_http_uploadprogress_callback_variable,
+ (uintptr_t) NULL,
+ NGX_HTTP_VAR_CHANGEABLE|NGX_HTTP_VAR_NOCACHEABLE|NGX_HTTP_VAR_NOHASH, 0 },
+@@ -261,9 +299,24 @@ static ngx_str_t ngx_http_uploadprogress_jsonp_defaults[] = {
+ ngx_string("$uploadprogress_callback({ \"state\" : \"uploading\", \"received\" : $uploadprogress_received, \"size\" : $uploadprogress_length });\r\n")
+ };
+
++static ngx_str_t ngx_http_uploadprogress_json_multiple_defaults[] = {
++ ngx_string("{ \"id\" : $uploadprogress_id, \"state\" : \"starting\" }"),
++ ngx_string("{ \"id\" : $uploadprogress_id, \"state\" : \"error\", \"status\" : $uploadprogress_status }"),
++ ngx_string("{ \"id\" : $uploadprogress_id, \"state\" : \"done\" }"),
++ ngx_string("{ \"id\" : $uploadprogress_id, \"state\" : \"uploading\", \"received\" : $uploadprogress_received, \"size\" : $uploadprogress_length }")
++};
++
++static ngx_str_t ngx_http_uploadprogress_jsonp_multiple_defaults[] = {
++ ngx_string("$uploadprogress_callback({ \"id\" : $uploadprogress_id, \"state\" : \"starting\" });\r\n"),
++ ngx_string("$uploadprogress_callback({ \"id\" : $uploadprogress_id, \"state\" : \"error\", \"status\" : $uploadprogress_status });\r\n"),
++ ngx_string("$uploadprogress_callback({ \"id\" : $uploadprogress_id, \"state\" : \"done\" });\r\n"),
++ ngx_string("$uploadprogress_callback({ \"id\" : $uploadprogress_id, \"state\" : \"uploading\", \"received\" : $uploadprogress_received, \"size\" : $uploadprogress_length });\r\n")
++};
++
+
+ static ngx_array_t ngx_http_uploadprogress_global_templates;
+
++
+ static ngx_str_t*
+ get_tracking_id(ngx_http_request_t * r)
+ {
+@@ -328,7 +381,7 @@ get_tracking_id(ngx_http_request_t * r)
+ i = 1;
+ break;
+ }
+- if (len<=0)
++ else if (!len)
+ break;
+ }
+ while(p++);
+@@ -355,6 +408,97 @@ get_tracking_id(ngx_http_request_t * r)
+ return NULL;
+ }
+
++static ngx_str_t*
++get_tracking_ids_mul(ngx_http_request_t * r)
++{
++ u_char *p, *start_p;
++ ngx_uint_t i;
++ ngx_list_part_t *part;
++ ngx_table_elt_t *header;
++ ngx_str_t *ret, args;
++ ngx_http_uploadprogress_conf_t *upcf;
++
++ upcf = ngx_http_get_module_loc_conf(r, ngx_http_uploadprogress_module);
++
++ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "upload-progress: get_tracking_ids");
++
++ part = &r->headers_in.headers.part;
++ header = part->elts;
++
++ for (i = 0; /* void */ ; i++) {
++
++ if (i >= part->nelts) {
++ if (part->next == NULL) {
++ break;
++ }
++
++ part = part->next;
++ header = part->elts;
++ i = 0;
++ }
++
++ if (header[i].key.len == upcf->header_mul.len
++ && ngx_strncasecmp(header[i].key.data, upcf->header_mul.data,
++ header[i].key.len) == 0) {
++ ret = ngx_calloc(sizeof(ngx_str_t), r->connection->log );
++ ret->data = header[i].value.data;
++ ret->len = header[i].value.len;
++ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
++ "upload-progress: get_tracking_ids found header: %V", ret);
++ return ret;
++ }
++ }
++
++ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
++ "upload-progress: get_tracking_ids no header found");
++
++ /* not found, check as a request arg */
++ /* it is possible the request args have not been yet created (or already released) */
++ /* so let's try harder first from the request line */
++ args.len = r->args.len;
++ args.data = r->args.data;
++
++ if (args.len && args.data) {
++ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
++ "upload-progress: get_tracking_id no header found, args found");
++ i = 0;
++ p = args.data;
++ do {
++ ngx_uint_t len = args.len - (p - args.data);
++ if (len >= (upcf->header_mul.len + 1) && ngx_strncasecmp(p, upcf->header_mul.data, upcf->header_mul.len) == 0
++ && p[upcf->header_mul.len] == '=') {
++ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
++ "upload-progress: get_tracking_id found args: %s",p);
++ i = 1;
++ break;
++ }
++ else if (!len)
++ break;
++ }
++ while(p++);
++
++ if (i) {
++ start_p = p += upcf->header_mul.len + 1;
++ while (p < args.data + args.len) {
++ if (*((p++) + 1) == '&') {
++ break;
++ }
++ }
++
++ ret = ngx_calloc(sizeof(ngx_str_t), r->connection->log);
++ ret->data = start_p;
++ ret->len = p - start_p;
++ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
++ "upload-progress: get_tracking_id found args: %V",ret);
++ return ret;
++ }
++ }
++
++ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
++ "upload-progress: get_tracking_id no id found");
++ return NULL;
++}
++
+ static ngx_http_uploadprogress_node_t *
+ find_node(ngx_str_t * id, ngx_http_uploadprogress_ctx_t * ctx, ngx_log_t * log)
+ {
+@@ -540,6 +684,27 @@ static void ngx_http_uploadprogress_event_handler(ngx_http_request_t *r)
+
+ if(up->length == 0)
+ up->length = r->headers_in.content_length_n;
++ if(upcf->udp_socket != -1 && upcf->progress_server.socklen != 0)
++ {
++ u_char datagram_buf[1024];
++ u_char * end;
++ off_t uploaded;
++ ngx_uint_t portion;
++
++ uploaded = up->length - up->rest;
++ if(up->length)
++ portion = 100 * uploaded / up->length;
++ else
++ portion = 100;
++ if(portion > up->sent_portion)
++ {
++ end = ngx_snprintf(datagram_buf, sizeof(datagram_buf), "{\"id\" : \"%V\", \"sequence\" : %d, \"size\" : %uO, \"uploaded\" : %uO }",
++ id, up->sequence, up->length, uploaded);
++ sendto(upcf->udp_socket, datagram_buf, end - datagram_buf, 0, (struct sockaddr*)upcf->progress_server.sockaddr, upcf->progress_server.socklen);
++ up->sent_portion = portion;
++ ++up->sequence;
++ }
++ }
+ ngx_log_debug3(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
+ "upload-progress: read_event_handler storing rest %uO/%uO for %V", up->rest, up->length, id);
+ } else {
+@@ -559,12 +724,12 @@ ngx_http_reportuploads_handler(ngx_http_request_t * r)
+ ngx_chain_t out;
+ ngx_int_t rc, found=0, done=0, err_status=0;
+ off_t rest=0, length=0;
+- ngx_uint_t len, i;
++ ngx_uint_t len;
+ ngx_slab_pool_t *shpool;
+ ngx_http_uploadprogress_conf_t *upcf;
+ ngx_http_uploadprogress_ctx_t *ctx;
+ ngx_http_uploadprogress_node_t *up;
+- ngx_table_elt_t *expires, *cc, **ccp;
++ ngx_table_elt_t *expires, *cc;
+ ngx_http_uploadprogress_state_t state;
+ ngx_http_uploadprogress_template_t *t;
+
+@@ -578,9 +743,13 @@ ngx_http_reportuploads_handler(ngx_http_request_t * r)
+ return rc;
+ }
+
+- /* get the tracking id if any */
+- id = get_tracking_id(r);
++ upcf = ngx_http_get_module_loc_conf(r, ngx_http_uploadprogress_module);
+
++ /* get the tracking id if any */
++ if(upcf->json_multiple)
++ id = get_tracking_ids_mul(r);
++ else
++ id = get_tracking_id(r);
+
+ if (id == NULL) {
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+@@ -591,8 +760,6 @@ ngx_http_reportuploads_handler(ngx_http_request_t * r)
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+ "reportuploads handler found id: %V", id);
+
+- upcf = ngx_http_get_module_loc_conf(r, ngx_http_uploadprogress_module);
+-
+ if (upcf->shm_zone == NULL) {
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+ "reportuploads no shm_zone for id: %V", id);
+@@ -600,32 +767,6 @@ ngx_http_reportuploads_handler(ngx_http_request_t * r)
+ return NGX_DECLINED;
+ }
+
+- ctx = upcf->shm_zone->data;
+-
+- /* get the original connection of the upload */
+- shpool = (ngx_slab_pool_t *) upcf->shm_zone->shm.addr;
+-
+- ngx_shmtx_lock(&shpool->mutex);
+-
+- up = find_node(id, ctx, r->connection->log);
+- if (up != NULL) {
+- ngx_log_debug5(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+- "reportuploads found node: %V (rest: %uO, length: %uO, done: %ui, err_status: %ui)", id, up->rest, up->length, up->done, up->err_status);
+- rest = up->rest;
+- length = up->length;
+- done = up->done;
+- err_status = up->err_status;
+- found = 1;
+- } else {
+- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+- "reportuploads not found: %V", id);
+- }
+- ngx_shmtx_unlock(&shpool->mutex);
+- ngx_free(id);
+-
+- /* send the output */
+- r->headers_out.content_type = upcf->content_type;
+-
+ /* force no-cache */
+ expires = r->headers_out.expires;
+
+@@ -637,6 +778,7 @@ ngx_http_reportuploads_handler(ngx_http_request_t * r)
+ }
+
+ r->headers_out.expires = expires;
++ expires->next = NULL;
+
+ expires->hash = 1;
+ expires->key.len = sizeof("Expires") - 1;
+@@ -646,37 +788,28 @@ ngx_http_reportuploads_handler(ngx_http_request_t * r)
+ len = sizeof("Mon, 28 Sep 1970 06:00:00 GMT");
+ expires->value.len = len - 1;
+
+- ccp = r->headers_out.cache_control.elts;
+- if (ccp == NULL) {
+-
+- if (ngx_array_init(&r->headers_out.cache_control, r->pool,
+- 1, sizeof(ngx_table_elt_t *))
+- != NGX_OK) {
+- return NGX_HTTP_INTERNAL_SERVER_ERROR;
+- }
+-
+- ccp = ngx_array_push(&r->headers_out.cache_control);
+- if (ccp == NULL) {
+- return NGX_HTTP_INTERNAL_SERVER_ERROR;
+- }
+-
++ cc = r->headers_out.cache_control;
++ if (cc == NULL) {
+ cc = ngx_list_push(&r->headers_out.headers);
+ if (cc == NULL) {
++ expires->hash = 0;
+ return NGX_HTTP_INTERNAL_SERVER_ERROR;
+ }
+
++ r->headers_out.cache_control = cc;
++ cc->next = NULL;
++
+ cc->hash = 1;
+ cc->key.len = sizeof("Cache-Control") - 1;
+ cc->key.data = (u_char *) "Cache-Control";
+
+- *ccp = cc;
+-
+ } else {
+- for (i = 1; i < r->headers_out.cache_control.nelts; i++) {
+- ccp[i]->hash = 0;
++ for (cc = cc->next; cc; cc = cc->next) {
++ cc->hash = 0;
+ }
+
+- cc = ccp[0];
++ cc = r->headers_out.cache_control;
++ cc->next = NULL;
+ }
+
+ expires->value.data = (u_char *) "Thu, 01 Jan 1970 00:00:01 GMT";
+@@ -695,59 +828,282 @@ ngx_http_reportuploads_handler(ngx_http_request_t * r)
+ }
+ }
+
+- ngx_http_set_ctx(r, up, ngx_http_uploadprogress_module);
++ ctx = upcf->shm_zone->data;
+
+-/*
++ /* get the original connection of the upload */
++ shpool = (ngx_slab_pool_t *) upcf->shm_zone->shm.addr;
++
++ if(upcf->json_multiple)
++ {
++ ngx_chain_t * p_chain_end = 0;
++ ngx_chain_t * p_chain_start = 0;
++ size_t offs = 0;
++ u_char * p1 = id->data, * p2;
++ r->headers_out.content_length_n = 0;
++ while(offs < id->len)
++ {
++ p2 = memchr((char *)id->data + offs, ';', id->len - offs);
++ if(!p2) p2 = id->data + id->len;
++ size_t len = p2 - p1;
++ if(len)
++ {
++ ngx_str_t sub_id;
++ sub_id.data = p1;
++ sub_id.len = len;
++
++ // ---->
++
++ ngx_shmtx_lock(&shpool->mutex);
++
++ up = find_node(&sub_id, ctx, r->connection->log);
++ if (up != NULL) {
++ ngx_log_debug5(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
++ "reportuploads found node: %V (rest: %uO, length: %uO, done: %ui, err_status: %ui)", &sub_id, up->rest, up->length, up->done, up->err_status);
++ rest = up->rest;
++ length = up->length;
++ done = up->done;
++ err_status = up->err_status;
++ found = 1;
++ } else {
++ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
++ "reportuploads not found: %V", &sub_id);
++ }
++ ngx_shmtx_unlock(&shpool->mutex);
++
++ /* send the output */
++ r->headers_out.content_type = upcf->content_type;
++
++ if(up == NULL)
++ {
++ // For current id
++ ngx_http_uploadprogress_node_t * tmp_node = ngx_pcalloc(r->pool, sizeof(ngx_http_uploadprogress_node_t) + sub_id.len);
++ tmp_node->len = sub_id.len;
++ ngx_memcpy(tmp_node->data, sub_id.data, sub_id.len);
++ ngx_http_set_ctx(r, tmp_node, ngx_http_uploadprogress_module);
++ }
++ else
++ ngx_http_set_ctx(r, up, ngx_http_uploadprogress_module);
++
++
++ if (!found) {
++ state = uploadprogress_state_starting;
++ } else if (err_status >= NGX_HTTP_BAD_REQUEST) {
++ state = uploadprogress_state_error;
++ } else if (done) {
++ state = uploadprogress_state_done;
++ } else if ( length == 0 && rest == 0 ) {
++ state = uploadprogress_state_starting;
++ } else {
++ state = uploadprogress_state_uploading;
++ }
++
++ t = upcf->templates.elts;
++
++ if (ngx_http_script_run(r, &response, t[(ngx_uint_t)state].lengths->elts, 0,
++ t[(ngx_uint_t)state].values->elts) == NULL)
++ {
++ ngx_free(id);
++ return NGX_HTTP_INTERNAL_SERVER_ERROR;
++ }
++
++ ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
++ "upload progress: state=%d, err_status=%ui, remaining=%uO, length=%uO",
++ state, err_status, (length - rest), length);
++
++ if(p_chain_end)
++ {
++ p_chain_end->next = ngx_palloc(r->pool, sizeof(ngx_chain_t));
++ if (p_chain_end->next == NULL) {
++ ngx_free(id);
++ return NGX_HTTP_INTERNAL_SERVER_ERROR;
++ }
++ p_chain_end = p_chain_end->next;
++
++ // Insert comma
++ b = ngx_calloc_buf(r->pool);
++ if (b == NULL) {
++ ngx_free(id);
++ return NGX_HTTP_INTERNAL_SERVER_ERROR;
++ }
++
++ b->pos = b->start = ngx_palloc(r->pool, 2);
++ if (b->pos == NULL) {
++ ngx_free(id);
++ return NGX_HTTP_INTERNAL_SERVER_ERROR;
++ }
++ b->last = b->end = b->pos + 2;
++ ngx_memcpy(b->pos, ", ", 2);
++ b->temporary = 1;
++ b->memory = 1;
++
++ p_chain_end->buf = b;
++ p_chain_end->next = ngx_palloc(r->pool, sizeof(ngx_chain_t));
++ if (p_chain_end->next == NULL) {
++ ngx_free(id);
++ return NGX_HTTP_INTERNAL_SERVER_ERROR;
++ }
++ p_chain_end = p_chain_end->next;
++ }
++ else
++ {
++ p_chain_start = p_chain_end = ngx_palloc(r->pool, sizeof(ngx_chain_t));
++ }
++
++ b = ngx_calloc_buf(r->pool);
++ if (b == NULL) {
++ ngx_free(id);
++ return NGX_HTTP_INTERNAL_SERVER_ERROR;
++ }
++
++ b->pos = b->start = response.data;
++ b->last = b->end = response.data + response.len;
++
++ b->temporary = 1;
++ b->memory = 1;
++
++ p_chain_end->buf = b;
++ p_chain_end->next = NULL;
++
++ // ---->
++
++ r->headers_out.content_length_n += b->last - b->pos;
++
++ p1 = p2 + 1;
++ }
++ offs += len + 1;
++ }
++ ngx_free(id);
++ if(!p_chain_end) // Malformed id
++ {
++ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
++ "reportuploads malformed multiple id");
++ return NGX_DECLINED;
++ }
++ // Prepend brace
++ b = ngx_calloc_buf(r->pool);
++ if (b == NULL) {
++ ngx_free(id);
++ return NGX_HTTP_INTERNAL_SERVER_ERROR;
++ }
++ b->pos = b->start = ngx_palloc(r->pool, 2);
++ if (b->pos == NULL) {
++ return NGX_HTTP_INTERNAL_SERVER_ERROR;
++ }
++ b->last = b->end = b->pos + 2;
++ ngx_memcpy(b->pos, "[ ", 2);
++ b->temporary = 1;
++ b->memory = 1;
++ r->headers_out.content_length_n += 2;
++
++ out.buf = b;
++ out.next = p_chain_start;
++
++ // Append brace
++ p_chain_end->next = ngx_palloc(r->pool, sizeof(ngx_chain_t));
++ if (p_chain_end->next == NULL) {
++ return NGX_HTTP_INTERNAL_SERVER_ERROR;
++ }
++ p_chain_end = p_chain_end->next;
++
++ b = ngx_calloc_buf(r->pool);
++ if (b == NULL) {
++ return NGX_HTTP_INTERNAL_SERVER_ERROR;
++ }
++
++ b->pos = b->start = ngx_palloc(r->pool, 2);
++ if (b->pos == NULL) {
++ return NGX_HTTP_INTERNAL_SERVER_ERROR;
++ }
++ b->last = b->end = b->pos + 4;
++ ngx_memcpy(b->pos, " ]\r\n", 4);
++ b->temporary = 1;
++ b->memory = 1;
++ r->headers_out.content_length_n += 4;
++
++ p_chain_end->buf = b;
++ p_chain_end->next = NULL;
++
++ r->headers_out.status = NGX_HTTP_OK;
++ p_chain_end->buf->last_buf = 1;
++ }
++ else
++ {
++ ngx_shmtx_lock(&shpool->mutex);
++
++ up = find_node(id, ctx, r->connection->log);
++ if (up != NULL) {
++ ngx_log_debug5(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
++ "reportuploads found node: %V (rest: %uO, length: %uO, done: %ui, err_status: %ui)", id, up->rest, up->length, up->done, up->err_status);
++ rest = up->rest;
++ length = up->length;
++ done = up->done;
++ err_status = up->err_status;
++ found = 1;
++ } else {
++ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
++ "reportuploads not found: %V", id);
++ }
++ ngx_shmtx_unlock(&shpool->mutex);
++ ngx_free(id);
++
++ /* send the output */
++ r->headers_out.content_type = upcf->content_type;
++
++ ngx_http_set_ctx(r, up, ngx_http_uploadprogress_module);
++
++ /*
+ There are 4 possibilities
+ * request not yet started: found = false
+ * request in error: err_status >= NGX_HTTP_BAD_REQUEST
+ * request finished: done = true
+ * request not yet started but registered: length==0 && rest ==0
+- * reauest in progress: rest > 0
++ * reauest in progress: rest > 0
+ */
+
+- if (!found) {
+- state = uploadprogress_state_starting;
+- } else if (err_status >= NGX_HTTP_BAD_REQUEST) {
+- state = uploadprogress_state_error;
+- } else if (done) {
+- state = uploadprogress_state_done;
+- } else if ( length == 0 && rest == 0 ) {
+- state = uploadprogress_state_starting;
+- } else {
+- state = uploadprogress_state_uploading;
+- }
++ if (!found) {
++ state = uploadprogress_state_starting;
++ } else if (err_status >= NGX_HTTP_BAD_REQUEST) {
++ state = uploadprogress_state_error;
++ } else if (done) {
++ state = uploadprogress_state_done;
++ } else if ( length == 0 && rest == 0 ) {
++ state = uploadprogress_state_starting;
++ } else {
++ state = uploadprogress_state_uploading;
++ }
+
+- t = upcf->templates.elts;
++ t = upcf->templates.elts;
+
+- if (ngx_http_script_run(r, &response, t[(ngx_uint_t)state].lengths->elts, 0,
+- t[(ngx_uint_t)state].values->elts) == NULL)
+- {
+- return NGX_HTTP_INTERNAL_SERVER_ERROR;
+- }
++ if (ngx_http_script_run(r, &response, t[(ngx_uint_t)state].lengths->elts, 0,
++ t[(ngx_uint_t)state].values->elts) == NULL)
++ {
++ return NGX_HTTP_INTERNAL_SERVER_ERROR;
++ }
+
+- ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+- "upload progress: state=%d, err_status=%ui, remaining=%uO, length=%uO",
+- state, err_status, (length - rest), length);
++ ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
++ "upload progress: state=%d, err_status=%ui, remaining=%uO, length=%uO",
++ state, err_status, (length - rest), length);
+
+- b = ngx_calloc_buf(r->pool);
+- if (b == NULL) {
+- return NGX_HTTP_INTERNAL_SERVER_ERROR;
+- }
++ b = ngx_calloc_buf(r->pool);
++ if (b == NULL) {
++ return NGX_HTTP_INTERNAL_SERVER_ERROR;
++ }
+
+- b->pos = b->start = response.data;
+- b->last = b->end = response.data + response.len;
++ b->pos = b->start = response.data;
++ b->last = b->end = response.data + response.len;
+
+- b->temporary = 1;
+- b->memory = 1;
++ b->temporary = 1;
++ b->memory = 1;
+
+- out.buf = b;
+- out.next = NULL;
++ out.buf = b;
++ out.next = NULL;
+
+- r->headers_out.status = NGX_HTTP_OK;
+- r->headers_out.content_length_n = b->last - b->pos;
++ r->headers_out.status = NGX_HTTP_OK;
++ r->headers_out.content_length_n = b->last - b->pos;
++
++ b->last_buf = 1;
++ }
+
+- b->last_buf = 1;
+ rc = ngx_http_send_header(r);
+
+ if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {
+@@ -774,8 +1130,8 @@ ngx_http_uploadprogress_handler(ngx_http_request_t * r)
+ ngx_http_uploadprogress_cleanup_t *upcln;
+ ngx_pool_cleanup_t *cln;
+
+- /* Is it a POST connection */
+- if (r->method != NGX_HTTP_POST) {
++ /* Only look for progress IDs on POST, PUT and PATCH */
++ if (!(r->method & (NGX_HTTP_POST | NGX_HTTP_PUT | NGX_HTTP_PATCH))) {
+ return NGX_DECLINED;
+ }
+
+@@ -852,6 +1208,8 @@ ngx_http_uploadprogress_handler(ngx_http_request_t * r)
+ up->rest = 0;
+ up->length = 0;
+ up->timeout = 0;
++ up->sequence = 0;
++ up->sent_portion = 0;
+
+ /* Properly handles small files where no read events happen after the */
+ /* request is first handled (apparently this can happen on linux with epoll) */
+@@ -859,6 +1217,8 @@ ngx_http_uploadprogress_handler(ngx_http_request_t * r)
+ up->length = r->headers_in.content_length_n;
+ if (r->request_body) {
+ up->rest = r->request_body->rest;
++ } else {
++ up->rest = up->length;
+ }
+ }
+
+@@ -1197,6 +1557,8 @@ ngx_http_uploadprogress_errortracker(ngx_http_request_t * r)
+ up->rest = 0;
+ up->length = 0;
+ up->timeout = 0;
++ up->sequence = 0;
++ up->sent_portion = 0;
+
+ ngx_memcpy(up->data, id->data, id->len);
+
+@@ -1288,6 +1650,7 @@ ngx_http_uploadprogress_create_loc_conf(ngx_conf_t * cf)
+ elt->values = NULL;
+ elt->lengths = NULL;
+ }
++ conf->udp_socket = -1;
+
+ return conf;
+ }
+@@ -1329,6 +1692,7 @@ ngx_http_uploadprogress_merge_loc_conf(ngx_conf_t * cf, void *parent, void *chil
+ }
+
+ ngx_conf_merge_str_value(conf->header, prev->header, "X-Progress-ID");
++ ngx_conf_merge_str_value(conf->header_mul, prev->header_mul, "X-ProgressMultiple-ID");
+ ngx_conf_merge_str_value(conf->jsonp_parameter, prev->jsonp_parameter, "callback");
+
+ return NGX_CONF_OK;
+@@ -1447,6 +1811,7 @@ ngx_http_track_uploads(ngx_conf_t * cf, ngx_command_t * cmd, void *conf)
+ ngx_http_core_loc_conf_t *clcf;
+ ngx_http_uploadprogress_conf_t *lzcf = conf;
+ ngx_str_t *value;
++ ngx_url_t url;
+
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, cf->log, 0, "ngx_track_uploads in");
+
+@@ -1471,10 +1836,27 @@ ngx_http_track_uploads(ngx_conf_t * cf, ngx_command_t * cmd, void *conf)
+ lzcf->timeout = ngx_parse_time(&value[2], 1);
+ if (lzcf->timeout == NGX_ERROR) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+- "track_uploads \"%V\" timeout value invalid", &value[1]);
++ "track_uploads \"%V\" timeout value invalid", &value[2]);
+ return NGX_CONF_ERROR;
+ }
+
++ if(cf->args->nelts > 3)
++ {
++ ngx_memzero(&url, sizeof(ngx_url_t));
++ url.url = value[3];
++ url.default_port = 80;
++ url.no_resolve = 0;
++
++ if(ngx_parse_url(cf->pool, &url) != NGX_OK)
++ {
++ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "Invalid graphite server %V: %s", &url.host, url.err);
++ return NGX_CONF_ERROR;
++ }
++ lzcf->progress_server = url.addrs[0];
++ if(lzcf->udp_socket == -1)
++ lzcf->udp_socket = ngx_socket(PF_INET, SOCK_DGRAM, 0);
++ }
++
+ clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
+ lzcf->handler = clcf->handler;
+ if ( lzcf->handler == NULL )
+@@ -1555,6 +1937,8 @@ ngx_http_upload_progress_template(ngx_conf_t * cf, ngx_command_t * cmd, void *co
+ ngx_http_uploadprogress_state_map_t *m = ngx_http_uploadprogress_state_map;
+ ngx_http_uploadprogress_template_t *t;
+
++ upcf->json_multiple = 0;
++
+ value = cf->args->elts;
+
+ while(m->name.data != NULL) {
+@@ -1584,6 +1968,8 @@ ngx_http_upload_progress_java_output(ngx_conf_t * cf, ngx_command_t * cmd, void
+ ngx_uint_t i;
+ char* rc;
+
++ upcf->json_multiple = 0;
++
+ t = (ngx_http_uploadprogress_template_t*)upcf->templates.elts;
+
+ for(i = 0;i < upcf->templates.nelts;i++) {
+@@ -1608,6 +1994,8 @@ ngx_http_upload_progress_json_output(ngx_conf_t * cf, ngx_command_t * cmd, void
+ ngx_uint_t i;
+ char* rc;
+
++ upcf->json_multiple = 0;
++
+ t = (ngx_http_uploadprogress_template_t*)upcf->templates.elts;
+
+ for(i = 0;i < upcf->templates.nelts;i++) {
+@@ -1632,6 +2020,8 @@ ngx_http_upload_progress_jsonp_output(ngx_conf_t * cf, ngx_command_t * cmd, void
+ ngx_uint_t i;
+ char* rc;
+
++ upcf->json_multiple = 0;
++
+ t = (ngx_http_uploadprogress_template_t*)upcf->templates.elts;
+
+ for(i = 0;i < upcf->templates.nelts;i++) {
+@@ -1648,6 +2038,58 @@ ngx_http_upload_progress_jsonp_output(ngx_conf_t * cf, ngx_command_t * cmd, void
+ return NGX_CONF_OK;
+ }
+
++static char*
++ngx_http_upload_progress_json_multiple_output(ngx_conf_t * cf, ngx_command_t * cmd, void *conf)
++{
++ ngx_http_uploadprogress_conf_t *upcf = conf;
++ ngx_http_uploadprogress_template_t *t;
++ ngx_uint_t i;
++ char* rc;
++
++ upcf->json_multiple = 1;
++
++ t = (ngx_http_uploadprogress_template_t*)upcf->templates.elts;
++
++ for(i = 0;i < upcf->templates.nelts;i++) {
++ rc = ngx_http_upload_progress_set_template(cf, t + i, ngx_http_uploadprogress_json_multiple_defaults + i);
++
++ if(rc != NGX_CONF_OK) {
++ return rc;
++ }
++ }
++
++ upcf->content_type.data = (u_char*)"application/json";
++ upcf->content_type.len = sizeof("application/json") - 1;
++
++ return NGX_CONF_OK;
++}
++
++static char*
++ngx_http_upload_progress_jsonp_multiple_output(ngx_conf_t * cf, ngx_command_t * cmd, void *conf)
++{
++ ngx_http_uploadprogress_conf_t *upcf = conf;
++ ngx_http_uploadprogress_template_t *t;
++ ngx_uint_t i;
++ char* rc;
++
++ upcf->json_multiple = 1;
++
++ t = (ngx_http_uploadprogress_template_t*)upcf->templates.elts;
++
++ for(i = 0;i < upcf->templates.nelts;i++) {
++ rc = ngx_http_upload_progress_set_template(cf, t + i, ngx_http_uploadprogress_jsonp_multiple_defaults + i);
++
++ if(rc != NGX_CONF_OK) {
++ return rc;
++ }
++ }
++
++ upcf->content_type.data = (u_char*)"application/json";
++ upcf->content_type.len = sizeof("application/json") - 1;
++
++ return NGX_CONF_OK;
++}
++
+ static ngx_int_t ngx_http_uploadprogress_received_variable(ngx_http_request_t *r,
+ ngx_http_variable_value_t *v, uintptr_t data)
+ {
+@@ -1724,6 +2166,30 @@ ngx_http_uploadprogress_status_variable(ngx_http_request_t *r,
+ return NGX_OK;
+ }
+
++static ngx_int_t
++ngx_http_uploadprogress_id_variable(ngx_http_request_t *r,
++ ngx_http_variable_value_t *v, uintptr_t data)
++{
++ ngx_http_uploadprogress_node_t *up;
++ u_char *p;
++
++ up = ngx_http_get_module_ctx(r, ngx_http_uploadprogress_module);
++
++ p = ngx_palloc(r->pool, up->len);
++ if (p == NULL) {
++ return NGX_ERROR;
++ }
++
++ v->len = up->len;
++ v->data = p;
++ ngx_memcpy(v->data, up->data, up->len);
++ v->valid = 1;
++ v->no_cacheable = 0;
++ v->not_found = 0;
++
++ return NGX_OK;
++}
++
+ static ngx_int_t
+ ngx_http_uploadprogress_callback_variable(ngx_http_request_t *r,
+ ngx_http_variable_value_t *v, uintptr_t data)
diff --git a/main/nginx/nginx.conf b/main/nginx/nginx.conf
index bc784a31879..89fa9854bf6 100644
--- a/main/nginx/nginx.conf
+++ b/main/nginx/nginx.conf
@@ -14,9 +14,8 @@ error_log /var/log/nginx/error.log warn;
# Includes files with directives to load dynamic modules.
include /etc/nginx/modules/*.conf;
-# Uncomment to include files with config snippets into the root context.
-# NOTE: This will be enabled by default in Alpine 3.15.
-#include /etc/nginx/conf.d/*.conf;
+# Include files with config snippets into the root context.
+include /etc/nginx/conf.d/*.conf;
events {
# The maximum number of simultaneous connections that can be opened by
@@ -32,7 +31,7 @@ http {
# Name servers used to resolve names of upstream servers into addresses.
# It's also needed when using tcpsocket and udpsocket in Lua modules.
- #resolver 1.1.1.1 1.0.0.1 2606:4700:4700::1111 2606:4700:4700::1001;
+ #resolver 1.1.1.1 1.0.0.1 [2606:4700:4700::1111] [2606:4700:4700::1001];
# Don't tell nginx version to the clients. Default is 'on'.
server_tokens off;
@@ -102,6 +101,3 @@ http {
# Includes virtual hosts configs.
include /etc/nginx/http.d/*.conf;
}
-
-# TIP: Uncomment if you use stream module.
-#include /etc/nginx/stream.conf;
diff --git a/main/nginx/nginx.post-upgrade b/main/nginx/nginx.post-upgrade
index 58e8e1baed6..3062f98223f 100644
--- a/main/nginx/nginx.post-upgrade
+++ b/main/nginx/nginx.post-upgrade
@@ -22,38 +22,25 @@ fi
# Handle transition from /etc/nginx/conf.d to /etc/nginx/http.d.
if [ "$(apk version -t "$ver_old" '1.18.0-r13')" = '<' ]; then
- default_conf='/usr/share/nginx/http-default_server.conf'
-
- if [ -z "$(ls -A /etc/nginx/conf.d 2>/dev/null)" ]; then
- # conf.d dir doesn't exist or is empty, so the user doesn't use it.
- # Thus we can install default.conf to the new directory.
- install -m644 "$default_conf" /etc/nginx/http.d/default.conf
-
- else
- if ! [ -e /etc/nginx/conf.d/default.conf ]; then
- # conf.d dir exists and is not empty, but there's no default.conf
- # file, so the user probably did not modify it and apk has removed
- # it during this upgrade. Prior this version, the default.conf
- # would be installed, so install it now for backward compatibility.
- install -m644 "$default_conf" /etc/nginx/conf.d/default.conf
- fi
- if ! [ -e /etc/nginx/nginx.conf.apk-new ]; then
- # There's no updated nginx.conf, so the user didn't modify this
- # config and apk replaced it during this upgrade. However, the
- # user has some vhost configs in the old directory, so we have
- # to revert the include back to the legacy path.
- sed -i 's|include /etc/nginx/http\.d|# WARNING: Do not use this directory for virtual hosts anymore, use directory http.d!\n\tinclude /etc/nginx/conf.d|' \
- /etc/nginx/nginx.conf
- fi
+ if ! [ -e /etc/nginx/http.d/default.conf ]; then
+ install -D -m644 /usr/share/nginx/http-default_server.conf \
+ /etc/nginx/http.d/default.conf
fi
+fi
- cat >&2 <<-EOF
- *
- * The default and preferred location for nginx vhost configs has been changed
- * from /etc/nginx/conf.d to /etc/nginx/http.d. Although we did our best to not
- * break existing setups by this upgrade, we strongly recommend to verify it.
- *
- EOF
+# Handle transition from /etc/nginx/conf.d to /etc/nginx/http.d.
+if [ "$(apk version -t "$ver_old" '1.22.0-r7')" = '<' ]; then
+ if sed -En '/^http\s*\{/,/^\}/{ /^\s*include\s+\/etc\/nginx\/conf.d\/.*;/p }' /etc/nginx/nginx.conf | grep -q .; then
+ cat >&2 <<-EOF
+ !!
+ !! Found 'include /etc/nginx/conf.d/*.conf' in the 'http' section!
+ !! The default and preferred location for nginx http configs has been changed
+ !! from /etc/nginx/conf.d to /etc/nginx/http.d. The former is now used for
+ !! configs to be included in the root context. Move your vhost configs from
+ !! /etc/nginx/conf.d/ to /etc/nginx/http.d/ and update /etc/nginx/nginx.conf.
+ !!
+ EOF
+ fi
fi
# Handle trasition from /var/tmp/nginx to /var/lib/nginx/tmp
diff --git a/main/nginx/ngx-fancyindex~fix-404-on-fs-root.patch b/main/nginx/ngx-fancyindex~fix-404-on-fs-root.patch
new file mode 100644
index 00000000000..1c0df2bf257
--- /dev/null
+++ b/main/nginx/ngx-fancyindex~fix-404-on-fs-root.patch
@@ -0,0 +1,27 @@
+Patch-Source: https://github.com/aperezdc/ngx-fancyindex/commit/83bef5c8a633ebbf96576eeb596a972a5816e057
+--
+From 83bef5c8a633ebbf96576eeb596a972a5816e057 Mon Sep 17 00:00:00 2001
+From: Ryan Schmidt <git@ryandesign.com>
+Date: Fri, 13 May 2022 00:16:09 -0500
+Subject: [PATCH] Fix 404 not found when indexing filesystem root
+
+Backport of https://github.com/nginx/nginx/commit/4c89c09ad8e574509446efab0347b124372bc53a
+
+Fixes #107
+
+diff --git a/ngx_http_fancyindex_module.c b/ngx_http_fancyindex_module.c
+index e6928dd..dd721d0 100644
+--- a/ngx_http_fancyindex_module.c
++++ b/ngx_http_fancyindex_module.c
+@@ -684,7 +684,10 @@ make_content_buf(
+ return NGX_HTTP_INTERNAL_SERVER_ERROR;
+
+ allocated = path.len;
+- path.len = last - path.data - 1;
++ path.len = last - path.data;
++ if (path.len > 1) {
++ path.len--;
++ }
+ path.data[path.len] = '\0';
+
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
diff --git a/main/nginx/ngx-fancyindex~fix-missing-saturday.patch b/main/nginx/ngx-fancyindex~fix-missing-saturday.patch
new file mode 100644
index 00000000000..b34f3e5d361
--- /dev/null
+++ b/main/nginx/ngx-fancyindex~fix-missing-saturday.patch
@@ -0,0 +1,25 @@
+Patch-Source: https://github.com/aperezdc/ngx-fancyindex/commit/674e99547d21b8bd9a36dc5d8689d08632d3a34d
+--
+From 674e99547d21b8bd9a36dc5d8689d08632d3a34d Mon Sep 17 00:00:00 2001
+From: Adrian Perez de Castro <aperez@igalia.com>
+Date: Thu, 19 Jan 2023 20:51:08 +0200
+Subject: [PATCH] Add missing entry in long weekday names array
+
+The entry for Saturday was missing, as pointed out in the bug report.
+While at it, add a test case.
+
+Fixes #157
+
+diff --git a/ngx_http_fancyindex_module.c b/ngx_http_fancyindex_module.c
+index bfccdc8..ed349d5 100644
+--- a/ngx_http_fancyindex_module.c
++++ b/ngx_http_fancyindex_module.c
+@@ -37,7 +37,7 @@ static const char *short_weekday[] = {
+ "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun",
+ };
+ static const char *long_weekday[] = {
+- "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Sunday",
++ "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday",
+ };
+ static const char *short_month[] = {
+ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
diff --git a/main/nginx/njs~nginx-1.20.x-compat.patch b/main/nginx/njs~nginx-1.20.x-compat.patch
deleted file mode 100644
index c24a12a59b0..00000000000
--- a/main/nginx/njs~nginx-1.20.x-compat.patch
+++ /dev/null
@@ -1,15 +0,0 @@
-Fix compatibility with nginx 1.20.x.
-
-See-Also: https://github.com/nginx/njs/issues/18
-
---- a/nginx/config.make
-+++ b/nginx/config.make
-@@ -3,7 +3,7 @@
- $ngx_addon_dir/../build/libnjs.a: $NGX_MAKEFILE
- cd $ngx_addon_dir/.. \\
- && if [ -f build/Makefile ]; then \$(MAKE) clean; fi \\
-- && CFLAGS="\$(CFLAGS)" CC="\$(CC)" ./configure --no-openssl --no-pcre \\
-+ && CFLAGS="\$(CFLAGS)" CC="\$(CC)" ./configure \\
- && \$(MAKE) libnjs
-
- END
diff --git a/main/nginx/no-werror.patch b/main/nginx/no-werror.patch
new file mode 100644
index 00000000000..58ab7f48537
--- /dev/null
+++ b/main/nginx/no-werror.patch
@@ -0,0 +1,11 @@
+--- a/auto/cc/gcc
++++ b/auto/cc/gcc
+@@ -166,7 +166,7 @@
+
+
+ # stop on warning
+-CFLAGS="$CFLAGS -Werror"
++CFLAGS="$CFLAGS"
+
+ # debug
+ CFLAGS="$CFLAGS -g"
diff --git a/main/nginx/stream.conf b/main/nginx/stream.conf
index 24387445497..4b7177de0c3 100644
--- a/main/nginx/stream.conf
+++ b/main/nginx/stream.conf
@@ -1,4 +1,4 @@
-# /etc/nginx/stream.conf
+# /etc/nginx/conf.d/stream.conf
stream {
# Specifies the main log format.
diff --git a/main/nginx/traffic-accounting-nginx-module~fix-memory-leak.patch b/main/nginx/traffic-accounting-nginx-module~fix-memory-leak.patch
new file mode 100644
index 00000000000..4822d25b656
--- /dev/null
+++ b/main/nginx/traffic-accounting-nginx-module~fix-memory-leak.patch
@@ -0,0 +1,253 @@
+Patch-Source: https://github.com/Lax/traffic-accounting-nginx-module/commit/900fceedcb00a840510d547a5b1e135b4f340745
+Patch-Source: https://github.com/Lax/traffic-accounting-nginx-module/commit/c0667a81a3ab3f62f30e9051179dc705261ec556
+--
+From 900fceedcb00a840510d547a5b1e135b4f340745 Mon Sep 17 00:00:00 2001
+From: Tony Liu <Tony.Liu@harmonicinc.com>
+Date: Thu, 19 Aug 2021 08:03:47 +0000
+Subject: [PATCH] use ngx_calloc to replace ngx_pcalloc to avoid memory leak
+ https://github.com/Lax/traffic-accounting-nginx-module/issues/53
+
+---
+ src/http/ngx_http_accounting_module.c | 8 +++----
+ src/ngx_traffic_accounting.h | 8 +++----
+ src/ngx_traffic_accounting_module.c | 11 +++++-----
+ src/ngx_traffic_accounting_module.h | 4 ++--
+ src/ngx_traffic_accounting_period_metrics.c | 24 ++++++++++-----------
+ src/stream/ngx_stream_accounting_module.c | 8 +++----
+ 6 files changed, 30 insertions(+), 33 deletions(-)
+
+diff --git a/src/http/ngx_http_accounting_module.c b/src/http/ngx_http_accounting_module.c
+index 63eccf0..23a5fc3 100644
+--- a/src/http/ngx_http_accounting_module.c
++++ b/src/http/ngx_http_accounting_module.c
+@@ -139,7 +139,7 @@ ngx_http_accounting_process_init(ngx_cycle_t *cycle)
+ }
+
+ if (amcf->current == NULL) {
+- if (ngx_traffic_accounting_period_create(cycle->pool, amcf) != NGX_OK)
++ if (ngx_traffic_accounting_period_create(amcf) != NGX_OK)
+ return NGX_ERROR;
+ }
+
+@@ -206,7 +206,7 @@ worker_process_alarm_handler(ngx_event_t *ev)
+
+ amcf = ngx_http_cycle_get_module_main_conf(ngx_cycle, ngx_http_accounting_module);
+
+- ngx_traffic_accounting_period_rotate(amcf->current->pool, amcf);
++ ngx_traffic_accounting_period_rotate(amcf);
+ ngx_traffic_accounting_period_rbtree_iterate(amcf->previous,
+ worker_process_export_metrics,
+ amcf->previous->created_at,
+@@ -243,10 +243,10 @@ ngx_http_accounting_request_handler(ngx_http_request_t *r)
+
+ amcf = ngx_http_get_module_main_conf(r, ngx_http_accounting_module);
+
+- metrics = ngx_traffic_accounting_period_fetch_metrics(amcf->current, accounting_id);
++ metrics = ngx_traffic_accounting_period_fetch_metrics(amcf->current, accounting_id, amcf->log);
+ if (metrics == NULL) { return NGX_ERROR; }
+
+- if (ngx_traffic_accounting_metrics_init(metrics, amcf->current->pool, ngx_http_statuses_len) == NGX_ERROR)
++ if (ngx_traffic_accounting_metrics_init(metrics, ngx_http_statuses_len, amcf->log) == NGX_ERROR)
+ return NGX_ERROR;
+
+ amcf->current->updated_at = ngx_timeofday();
+diff --git a/src/ngx_traffic_accounting.h b/src/ngx_traffic_accounting.h
+index 1812927..462becf 100644
+--- a/src/ngx_traffic_accounting.h
++++ b/src/ngx_traffic_accounting.h
+@@ -38,21 +38,19 @@ typedef struct {
+ ngx_rbtree_t rbtree;
+ ngx_rbtree_node_t sentinel;
+
+- ngx_pool_t *pool;
+-
+ ngx_time_t *created_at;
+ ngx_time_t *updated_at;
+ } ngx_traffic_accounting_period_t;
+
+-ngx_int_t ngx_traffic_accounting_metrics_init(ngx_traffic_accounting_metrics_t *metrics, ngx_pool_t *pool, size_t len);
++ngx_int_t ngx_traffic_accounting_metrics_init(ngx_traffic_accounting_metrics_t *metrics, size_t len, ngx_log_t *log);
+
+ ngx_int_t ngx_traffic_accounting_period_init(ngx_traffic_accounting_period_t *period);
+-void ngx_traffic_accounting_period_insert(ngx_traffic_accounting_period_t *period, ngx_str_t *name);
++void ngx_traffic_accounting_period_insert(ngx_traffic_accounting_period_t *period, ngx_str_t *name, ngx_log_t *log);
+ void ngx_traffic_accounting_period_insert_metrics(ngx_traffic_accounting_period_t *period, ngx_traffic_accounting_metrics_t *metrics);
+ void ngx_traffic_accounting_period_delete(ngx_traffic_accounting_period_t *period, ngx_str_t *name);
+ void ngx_traffic_accounting_period_delete_metrics(ngx_traffic_accounting_period_t *period, ngx_traffic_accounting_metrics_t *metrics);
+ ngx_traffic_accounting_metrics_t * ngx_traffic_accounting_period_lookup_metrics(ngx_traffic_accounting_period_t *period, ngx_str_t *name);
+-ngx_traffic_accounting_metrics_t * ngx_traffic_accounting_period_fetch_metrics(ngx_traffic_accounting_period_t *period, ngx_str_t *name);
++ngx_traffic_accounting_metrics_t * ngx_traffic_accounting_period_fetch_metrics(ngx_traffic_accounting_period_t *period, ngx_str_t *name, ngx_log_t *log);
+
+ typedef ngx_int_t (*ngx_traffic_accounting_period_iterate_func)(void *val, void *para1, void *para2);
+
+diff --git a/src/ngx_traffic_accounting_module.c b/src/ngx_traffic_accounting_module.c
+index ebc877a..2291db7 100644
+--- a/src/ngx_traffic_accounting_module.c
++++ b/src/ngx_traffic_accounting_module.c
+@@ -9,15 +9,14 @@
+
+
+ ngx_int_t
+-ngx_traffic_accounting_period_create(ngx_pool_t *pool, ngx_traffic_accounting_main_conf_t *amcf)
++ngx_traffic_accounting_period_create(ngx_traffic_accounting_main_conf_t *amcf)
+ {
+ ngx_traffic_accounting_period_t *period;
+
+- period = ngx_pcalloc(pool, sizeof(ngx_traffic_accounting_period_t));
++ period = ngx_calloc(sizeof(ngx_traffic_accounting_period_t), amcf->log);
+ if (period == NULL)
+ return NGX_ERROR;
+
+- period->pool = pool;
+ ngx_traffic_accounting_period_init(period);
+
+ period->created_at = ngx_timeofday();
+@@ -28,11 +27,11 @@ ngx_traffic_accounting_period_create(ngx_pool_t *pool, ngx_traffic_accounting_ma
+ }
+
+ ngx_int_t
+-ngx_traffic_accounting_period_rotate(ngx_pool_t *pool, ngx_traffic_accounting_main_conf_t *amcf)
++ngx_traffic_accounting_period_rotate(ngx_traffic_accounting_main_conf_t *amcf)
+ {
+- ngx_pfree(pool, amcf->previous);
++ ngx_free(amcf->previous);
+
+ amcf->previous = amcf->current;
+
+- return ngx_traffic_accounting_period_create(pool, amcf);
++ return ngx_traffic_accounting_period_create(amcf);
+ }
+diff --git a/src/ngx_traffic_accounting_module.h b/src/ngx_traffic_accounting_module.h
+index 08881f1..adfccec 100644
+--- a/src/ngx_traffic_accounting_module.h
++++ b/src/ngx_traffic_accounting_module.h
+@@ -46,8 +46,8 @@ ngx_str_t * ngx_traffic_accounting_get_accounting_id(void *entry, ngx_get_loc_co
+ ngx_get_indexed_variable_pt get_indexed_variable);
+
+
+-ngx_int_t ngx_traffic_accounting_period_create(ngx_pool_t *pool, ngx_traffic_accounting_main_conf_t *amcf);
+-ngx_int_t ngx_traffic_accounting_period_rotate(ngx_pool_t *pool, ngx_traffic_accounting_main_conf_t *amcf);
++ngx_int_t ngx_traffic_accounting_period_create(ngx_traffic_accounting_main_conf_t *amcf);
++ngx_int_t ngx_traffic_accounting_period_rotate(ngx_traffic_accounting_main_conf_t *amcf);
+
+
+ #endif /* _NGX_TRAFFIC_ACCOUNTING_MODULE_H_INCLUDED_ */
+diff --git a/src/ngx_traffic_accounting_period_metrics.c b/src/ngx_traffic_accounting_period_metrics.c
+index b6b7055..302bd84 100644
+--- a/src/ngx_traffic_accounting_period_metrics.c
++++ b/src/ngx_traffic_accounting_period_metrics.c
+@@ -10,17 +10,17 @@
+ static void ngx_traffic_accounting_period_insert_value(ngx_rbtree_node_t *temp, ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel);
+
+ ngx_int_t
+-ngx_traffic_accounting_metrics_init(ngx_traffic_accounting_metrics_t *metrics, ngx_pool_t *pool, size_t len)
++ngx_traffic_accounting_metrics_init(ngx_traffic_accounting_metrics_t *metrics, size_t len, ngx_log_t *log)
+ {
+ if (metrics->nr_status == NULL) {
+- metrics->nr_status = ngx_pcalloc(pool, sizeof(ngx_uint_t) * len);
++ metrics->nr_status = ngx_calloc(sizeof(ngx_uint_t) * len, log);
+
+ if (metrics->nr_status == NULL)
+ return NGX_ERROR;
+ }
+
+ if (metrics->nr_upstream_status == NULL) {
+- metrics->nr_upstream_status = ngx_pcalloc(pool, sizeof(ngx_uint_t) * len);
++ metrics->nr_upstream_status = ngx_calloc(sizeof(ngx_uint_t) * len, log);
+
+ if (metrics->nr_upstream_status == NULL)
+ return NGX_ERROR;
+@@ -39,14 +39,14 @@ ngx_traffic_accounting_period_init(ngx_traffic_accounting_period_t *period)
+ }
+
+ void
+-ngx_traffic_accounting_period_insert(ngx_traffic_accounting_period_t *period, ngx_str_t *name)
++ngx_traffic_accounting_period_insert(ngx_traffic_accounting_period_t *period, ngx_str_t *name, ngx_log_t *log)
+ {
+ ngx_traffic_accounting_metrics_t *metrics;
+
+- metrics = ngx_pcalloc(period->pool, sizeof(ngx_traffic_accounting_metrics_t));
++ metrics = ngx_calloc(sizeof(ngx_traffic_accounting_metrics_t), log);
+
+ void *data;
+- data = ngx_pcalloc(period->pool, name->len+1);
++ data = ngx_calloc(name->len+1, log);
+ ngx_memcpy(data, name->data, name->len);
+
+ metrics->name.data = data;
+@@ -82,7 +82,7 @@ void
+ ngx_traffic_accounting_period_delete_metrics(ngx_traffic_accounting_period_t *period, ngx_traffic_accounting_metrics_t *metrics)
+ {
+ ngx_rbtree_delete(&period->rbtree, &metrics->rbnode);
+- ngx_pfree(period->pool, metrics);
++ ngx_free(metrics);
+ }
+
+ ngx_traffic_accounting_metrics_t *
+@@ -124,7 +124,7 @@ ngx_traffic_accounting_period_lookup_metrics(ngx_traffic_accounting_period_t *pe
+ }
+
+ ngx_traffic_accounting_metrics_t *
+-ngx_traffic_accounting_period_fetch_metrics(ngx_traffic_accounting_period_t *period, ngx_str_t *name)
++ngx_traffic_accounting_period_fetch_metrics(ngx_traffic_accounting_period_t *period, ngx_str_t *name, ngx_log_t *log)
+ {
+ ngx_traffic_accounting_metrics_t *n;
+
+@@ -132,7 +132,7 @@ ngx_traffic_accounting_period_fetch_metrics(ngx_traffic_accounting_period_t *per
+ if (n != NULL)
+ return n;
+
+- ngx_traffic_accounting_period_insert(period, name);
++ ngx_traffic_accounting_period_insert(period, name, log);
+
+ return ngx_traffic_accounting_period_lookup_metrics(period, name);
+ }
+@@ -158,9 +158,10 @@ ngx_traffic_accounting_period_rbtree_iterate(ngx_traffic_accounting_period_t *pe
+ if (rc == NGX_DONE) {
+ /* NGX_DONE -> destroy node */
+ ngx_rbtree_delete(rbtree, node);
+- ngx_pfree(period->pool, n->nr_status);
+- ngx_pfree(period->pool, n->nr_upstream_status);
+- ngx_pfree(period->pool, n);
++ ngx_free(n->nr_status);
++ ngx_free(n->nr_upstream_status);
++ ngx_free(n->name.data);
++ ngx_free(n);
+
+ goto done;
+ }
+diff --git a/src/stream/ngx_stream_accounting_module.c b/src/stream/ngx_stream_accounting_module.c
+index b1839d1..3db787d 100644
+--- a/src/stream/ngx_stream_accounting_module.c
++++ b/src/stream/ngx_stream_accounting_module.c
+@@ -136,7 +136,7 @@ ngx_stream_accounting_process_init(ngx_cycle_t *cycle)
+ }
+
+ if (amcf->current == NULL) {
+- if (ngx_traffic_accounting_period_create(cycle->pool, amcf) != NGX_OK)
++ if (ngx_traffic_accounting_period_create(amcf) != NGX_OK)
+ return NGX_ERROR;
+ }
+
+@@ -203,7 +203,7 @@ worker_process_alarm_handler(ngx_event_t *ev)
+
+ amcf = ngx_stream_cycle_get_module_main_conf(ngx_cycle, ngx_stream_accounting_module);
+
+- ngx_traffic_accounting_period_rotate(amcf->current->pool, amcf);
++ ngx_traffic_accounting_period_rotate(amcf);
+ ngx_traffic_accounting_period_rbtree_iterate(amcf->previous,
+ worker_process_export_metrics,
+ amcf->previous->created_at,
+@@ -240,10 +240,10 @@ ngx_stream_accounting_session_handler(ngx_stream_session_t *s)
+
+ amcf = ngx_stream_get_module_main_conf(s, ngx_stream_accounting_module);
+
+- metrics = ngx_traffic_accounting_period_fetch_metrics(amcf->current, accounting_id);
++ metrics = ngx_traffic_accounting_period_fetch_metrics(amcf->current, accounting_id, amcf->log);
+ if (metrics == NULL) { return NGX_ERROR; }
+
+- if (ngx_traffic_accounting_metrics_init(metrics, amcf->current->pool, ngx_stream_statuses_len) == NGX_ERROR)
++ if (ngx_traffic_accounting_metrics_init(metrics, ngx_stream_statuses_len, amcf->log) == NGX_ERROR)
+ return NGX_ERROR;
+
+ amcf->current->updated_at = ngx_timeofday();
diff --git a/main/nginx/zstd-nginx-module~fix-infinite-loop.patch b/main/nginx/zstd-nginx-module~fix-infinite-loop.patch
new file mode 100644
index 00000000000..7f71271681a
--- /dev/null
+++ b/main/nginx/zstd-nginx-module~fix-infinite-loop.patch
@@ -0,0 +1,47 @@
+patch-source: https://github.com/tokers/zstd-nginx-module/pull/23
+
+From 7f86e5bbd7711b216688c418ffe2a64c9b25f319 Mon Sep 17 00:00:00 2001
+From: drawing <cppbreak@qq.com>
+Date: Mon, 12 Jun 2023 14:37:00 +0800
+Subject: [PATCH] bugfix: fix zstd module infinite loop when upstream return
+ content-length abnormal
+
+---
+ filter/ngx_http_zstd_filter_module.c | 10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+diff --git a/filter/ngx_http_zstd_filter_module.c b/filter/ngx_http_zstd_filter_module.c
+index d5784ba..cea386f 100644
+--- a/filter/ngx_http_zstd_filter_module.c
++++ b/filter/ngx_http_zstd_filter_module.c
+@@ -440,6 +440,8 @@ ngx_http_zstd_filter_compress(ngx_http_request_t *r, ngx_http_zstd_ctx_t *ctx)
+ ctx->out_buf->last += ctx->buffer_out.pos - pos_out;
+ ctx->redo = 0;
+
++ unsigned last_action = ctx->action;
++
+ if (rc > 0) {
+ if (ctx->action == NGX_HTTP_ZSTD_FILTER_COMPRESS) {
+ ctx->action = NGX_HTTP_ZSTD_FILTER_FLUSH;
+@@ -459,7 +461,7 @@ ngx_http_zstd_filter_compress(ngx_http_request_t *r, ngx_http_zstd_ctx_t *ctx)
+ ctx->action = NGX_HTTP_ZSTD_FILTER_COMPRESS; /* restore */
+ }
+
+- if (ngx_buf_size(ctx->out_buf) == 0) {
++ if (ngx_buf_size(ctx->out_buf) == 0 && last_action != NGX_HTTP_ZSTD_FILTER_FLUSH) {
+ return NGX_AGAIN;
+ }
+
+@@ -469,6 +471,12 @@ ngx_http_zstd_filter_compress(ngx_http_request_t *r, ngx_http_zstd_ctx_t *ctx)
+ }
+
+ b = ctx->out_buf;
++ if (ngx_buf_size(b) == 0) {
++ b = ngx_calloc_buf(ctx->request->pool);
++ if (b == NULL) {
++ return NGX_ERROR;
++ }
++ }
+
+ if (rc == 0 && (ctx->flush || ctx->last)) {
+ r->connection->buffered &= ~NGX_HTTP_GZIP_BUFFERED;