From e512a6be277a50e883d49794147bff14015a841b Mon Sep 17 00:00:00 2001 From: Jun Ouyang Date: Sat, 13 Jun 2026 19:16:41 +0800 Subject: [PATCH 1/2] tests: cover HTTP/2 slice cache wakeup --- t/189-http2-subreq-error-wakeup.t | 92 ++++++++++++++++++++++++++++++- util/build-with-dd.sh | 1 + util/build-without-ssl.sh | 1 + util/build.sh | 1 + 4 files changed, 94 insertions(+), 1 deletion(-) diff --git a/t/189-http2-subreq-error-wakeup.t b/t/189-http2-subreq-error-wakeup.t index 2b6adb6e19..f836b231d3 100644 --- a/t/189-http2-subreq-error-wakeup.t +++ b/t/189-http2-subreq-error-wakeup.t @@ -16,7 +16,7 @@ log_level('info'); repeat_each(2); -plan tests => repeat_each() * (blocks() * 9 + 2); +plan tests => repeat_each() * 44; #no_diff(); no_long_string(); @@ -218,3 +218,93 @@ Fast parent completed --- no_error_log [alert] [crit] +[emerg] +[error] +--- no_shutdown_error_log +[alert] +[crit] +[emerg] +[error] + + + +=== TEST 5: HTTP/2 slow client with slice cache subrequests +--- http_config + send_timeout 1s; + proxy_cache_path conf/slice-cache levels=1:2 keys_zone=SLICES:10m inactive=10m max_size=20m; + +--- user_files +>>> curl-slow.conf +limit-rate = "1k" +output = "/dev/null" + +--- config + location = /slice { + slice 1k; + proxy_cache SLICES; + proxy_cache_key "$uri $slice_range"; + proxy_set_header Range $slice_range; + proxy_cache_valid 200 206 1h; + proxy_pass http://127.0.0.1:$TEST_NGINX_SERVER_PORT/origin_slice; + } + + location = /origin_slice { + content_by_lua_block { + local total = 8 * 1024 * 1024 + local range = ngx.var.http_range + local first, last = 0, total - 1 + + if range then + local m, err = ngx.re.match(range, [[bytes=(\d+)-(\d*)]], "jo") + if not m then + ngx.log(ngx.ERR, "bad range header: ", range, ", err: ", err) + ngx.status = 416 + return + end + + first = tonumber(m[1]) + if m[2] and m[2] ~= "" then + last = tonumber(m[2]) + end + end + + if first >= total then + ngx.status = 416 + return + end + + if last >= total then + last = total - 1 + end + + local len = last - first + 1 + if range then + ngx.status = ngx.HTTP_PARTIAL_CONTENT + ngx.header["Content-Range"] = + string.format("bytes %d-%d/%d", first, last, total) + end + + ngx.header["Accept-Ranges"] = "bytes" + ngx.header["Content-Length"] = len + ngx.print(string.rep("x", len)) + } + } + +--- http2 +--- request +GET /slice +--- timeout: 4 +--- abort +--- ignore_response +--- curl_options: --config=t/servroot/html/curl-slow.conf +--- curl_error: (28) Operation timed out +--- no_error_log +[alert] +[crit] +[emerg] +[error] +--- no_shutdown_error_log +[alert] +[crit] +[emerg] +[error] diff --git a/util/build-with-dd.sh b/util/build-with-dd.sh index 4f4e785f53..c13c2f75c1 100755 --- a/util/build-with-dd.sh +++ b/util/build-with-dd.sh @@ -19,6 +19,7 @@ time ngx-build $force $version \ --with-cc-opt="-DNGX_LUA_USE_ASSERT -I$PCRE2_INC -I$OPENSSL_INC -DDDEBUG=1" \ --with-http_v2_module \ --with-http_v3_module \ + --with-http_slice_module \ --with-http_realip_module \ --with-http_ssl_module \ --add-module=$root/../ndk-nginx-module \ diff --git a/util/build-without-ssl.sh b/util/build-without-ssl.sh index 022d9617e2..715e740b9d 100755 --- a/util/build-without-ssl.sh +++ b/util/build-without-ssl.sh @@ -19,6 +19,7 @@ time ngx-build $force $version \ --with-ipv6 \ --with-cc-opt="-DNGX_LUA_USE_ASSERT -I$PCRE2_INC" \ --with-http_v2_module \ + --with-http_slice_module \ --with-http_realip_module \ --add-module=$root/../ndk-nginx-module \ --add-module=$root/../set-misc-nginx-module \ diff --git a/util/build.sh b/util/build.sh index cd4eaa45f4..39aa7d688c 100755 --- a/util/build.sh +++ b/util/build.sh @@ -33,6 +33,7 @@ time ngx-build $force $version \ --with-cc-opt="-DNGX_LUA_USE_ASSERT -I$PCRE2_INC -I$OPENSSL_INC" \ --with-http_v2_module \ --with-http_v3_module \ + --with-http_slice_module \ --with-http_realip_module \ --with-http_ssl_module \ --add-module=$root/../ndk-nginx-module \ From 55c306ebc16366d833958197381131d184b6f464 Mon Sep 17 00:00:00 2001 From: Jun Ouyang Date: Sat, 13 Jun 2026 19:59:27 +0800 Subject: [PATCH 2/2] tests: refine HTTP/2 slice cache wakeup case --- t/189-http2-subreq-error-wakeup.t | 126 +++++++++++++++++------------- 1 file changed, 71 insertions(+), 55 deletions(-) diff --git a/t/189-http2-subreq-error-wakeup.t b/t/189-http2-subreq-error-wakeup.t index f836b231d3..b24a15f989 100644 --- a/t/189-http2-subreq-error-wakeup.t +++ b/t/189-http2-subreq-error-wakeup.t @@ -11,15 +11,26 @@ use Test::Nginx::Socket::Lua; use Cwd qw(abs_path realpath); use File::Basename; +use File::Path qw(rmtree); log_level('info'); +my $nginx = $ENV{TEST_NGINX_BINARY} || 'nginx'; +my $nginx_v = eval { `$nginx -V 2>&1` } // ''; +our $HasHttpSlice = $nginx_v =~ /--with-http_slice_module/; + repeat_each(2); -plan tests => repeat_each() * 44; +plan tests => repeat_each() * 48; #no_diff(); +no_shuffle(); no_long_string(); + +my $slice_cache_dir = "/tmp/lua-nginx-module-slice-cache-" . server_port(); +rmtree($slice_cache_dir); +add_cleanup_handler(sub { rmtree($slice_cache_dir) }); + run_tests(); __DATA__ @@ -228,76 +239,81 @@ Fast parent completed -=== TEST 5: HTTP/2 slow client with slice cache subrequests +=== TEST 5: warm slice cache for HTTP/2 slow client +--- skip_eval: 4: !$::HasHttpSlice --- http_config - send_timeout 1s; - proxy_cache_path conf/slice-cache levels=1:2 keys_zone=SLICES:10m inactive=10m max_size=20m; + send_timeout 5s; + proxy_cache_path /tmp/lua-nginx-module-slice-cache-$TEST_NGINX_SERVER_PORT levels=1:2 keys_zone=SLICES:10m inactive=10m max_size=20m; ---- user_files ->>> curl-slow.conf -limit-rate = "1k" -output = "/dev/null" +--- user_files eval +">>> origin/big.bin\n" . ("x" x (10 * 1024 * 1024)) --- config - location = /slice { - slice 1k; + location = /slice-big.bin { + slice 1m; proxy_cache SLICES; proxy_cache_key "$uri $slice_range"; proxy_set_header Range $slice_range; proxy_cache_valid 200 206 1h; - proxy_pass http://127.0.0.1:$TEST_NGINX_SERVER_PORT/origin_slice; + proxy_pass http://127.0.0.1:$TEST_NGINX_SERVER_PORT/origin/big.bin; } - location = /origin_slice { - content_by_lua_block { - local total = 8 * 1024 * 1024 - local range = ngx.var.http_range - local first, last = 0, total - 1 - - if range then - local m, err = ngx.re.match(range, [[bytes=(\d+)-(\d*)]], "jo") - if not m then - ngx.log(ngx.ERR, "bad range header: ", range, ", err: ", err) - ngx.status = 416 - return - end - - first = tonumber(m[1]) - if m[2] and m[2] ~= "" then - last = tonumber(m[2]) - end - end - - if first >= total then - ngx.status = 416 - return - end - - if last >= total then - last = total - 1 - end - - local len = last - first + 1 - if range then - ngx.status = ngx.HTTP_PARTIAL_CONTENT - ngx.header["Content-Range"] = - string.format("bytes %d-%d/%d", first, last, total) - end - - ngx.header["Accept-Ranges"] = "bytes" - ngx.header["Content-Length"] = len - ngx.print(string.rep("x", len)) - } + location /origin/ { + root $TEST_NGINX_SERVER_ROOT/html; } --- http2 --- request -GET /slice ---- timeout: 4 ---- abort +GET /slice-big.bin +--- ignore_response +--- no_error_log +[alert] +[crit] +[emerg] +[error] +--- no_shutdown_error_log +[alert] +[crit] +[emerg] +[error] + + + +=== TEST 6: HTTP/2 slow client with warmed slice cache +--- skip_eval: 4: !$::HasHttpSlice +--- http_config + send_timeout 5s; + proxy_cache_path /tmp/lua-nginx-module-slice-cache-$TEST_NGINX_SERVER_PORT levels=1:2 keys_zone=SLICES:10m inactive=10m max_size=20m; + +--- user_files eval +">>> origin/big.bin\n" . ("x" x (10 * 1024 * 1024)) . "\n" . +">>> curl-slow.conf\n" . +"limit-rate = \"50k\"\n" . +"max-time = 8\n" . +"output = \"/dev/null\"\n" + +--- config + location = /slice-big.bin { + slice 1m; + proxy_cache SLICES; + proxy_cache_key "$uri $slice_range"; + proxy_set_header Range $slice_range; + proxy_cache_valid 200 206 1h; + proxy_pass http://127.0.0.1:$TEST_NGINX_SERVER_PORT/origin/big.bin; + } + + location /origin/ { + root $TEST_NGINX_SERVER_ROOT/html; + } + +--- http2 +--- request +GET /slice-big.bin +--- timeout: 12 --- ignore_response --- curl_options: --config=t/servroot/html/curl-slow.conf ---- curl_error: (28) Operation timed out +--- curl_error eval: qr/\((28|92)\)/ +--- wait: 6 --- no_error_log [alert] [crit]