From a9f9450f804796ba404ed444ae5950bb77647400 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Gruszczy=C5=84ski?= Date: Tue, 6 Oct 2026 23:54:01 +0200 Subject: [PATCH] v0.26.7 --- CHANGELOG.md | 2 +- ROADMAP.md | 1 + SHA256SUMS | 30 +++++++++--------- docs/CACHE.md | 6 ++-- docs/SECURITY.md | 6 ++-- docs/TEST_REPORT.md | 2 +- docs/V0.26.7_IMPLEMENTATION.md | 9 ++++-- langs/en_US.json | 2 +- langs/pl_pl.json | 2 +- scripts/check_source.py | 13 ++++++-- src/admin/web/index.html | 6 ++-- src/admin/web/vhosts/core.js | 2 +- src/headers.rs | 51 +++++++++++++++++++++--------- src/headers/tests.rs | 58 ++++++++++++++++++++++++++++++++++ src/proxy/cache_helpers.rs | 14 ++++++++ src/proxy/upstream_helpers.rs | 14 ++++++++ 16 files changed, 171 insertions(+), 47 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2624ef0..056e8be 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,7 @@ ## 0.26.7 - Add HOT and COLD cache occupancy progress bars on `/cache` for configured object and byte limits, with explicit percentage/limit details. -- Verify cache `Age` progression on stored HITs, protect `Age` from custom response-header rules, and clarify that successful validator revalidation legitimately restarts the HTTP freshness age while `X-Cache-Resident-Age` continues to grow. +- Verify cache `Age` progression on stored HITs and retain 0.26.6 compatibility for existing custom `Age` rules. Response-side Age rules are deferred to the final wire stage so they cannot alter internal freshness/storage. Successful validator revalidation still legitimately restarts HTTP freshness age while `X-Cache-Resident-Age` continues to grow. - Restore downstream compression for cookie-bearing responses only when RustProxy is serving a shared-cache HIT already accepted by cache policy or a local static Web Server response; privacy-sensitive dynamic/cookie responses remain excluded. - Keep `Content-Encoding`/`Vary: Accept-Encoding` negotiation for gzip, Brotli, Zstandard and deflate, and make the bundled compression tester stop forcing `Cache-Control: no-cache` unless explicitly requested. - Preserve compatible backend upstream clients across unrelated active-snapshot rebuilds so generation age, generation request count and rotation totals do not reset spuriously. diff --git a/ROADMAP.md b/ROADMAP.md index 1e14af0..e1db541 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -9,6 +9,7 @@ Current direction: 0.26.6 -> 0.26.7 - [x] Keep request-count and age-based backend client recycling covered by tests and visible diagnostics. - [x] Refresh container documentation and include all supported Certbot DNS plugins in the shipped OCI image. - [x] Review current installation/cache/backend lifecycle documentation for stale behavior statements. +- [x] Keep existing 0.26.6 custom `Age` rules loadable while isolating response-side Age overrides from cache freshness/storage semantics. - [x] Keep SQLite schema 8 and saved proxy configuration compatibility with 0.26.6. - [ ] Run compiler-enabled `cargo fmt --all`, `cargo check --locked --all-targets` and `cargo test --locked --all-targets` on a Rust release host. diff --git a/SHA256SUMS b/SHA256SUMS index edb386a..d21a5bd 100644 --- a/SHA256SUMS +++ b/SHA256SUMS @@ -2,12 +2,12 @@ 4140a2956264b44f259e6a37fc00ba02097bbe68b09296e04d3d243c1287129b .env.example 9e6356475bf587091bab72246ec9e325b498f7e48a6220e9a18baa50d0a385a6 .gitignore c39fd74d633dc36cd7caa8d9b6785151b116752b79bd629d4d810cb03e1096cc AGENTS.md -abe0ebe15057929bec551cc1b92cfa25fb7aca616ba7e3bc8d23a4f02082a446 CHANGELOG.md +6308cefa554fa14a9e456eaeb5c98e329e4f8b922fc4b481062ac4323db8ac93 CHANGELOG.md 91e57afc931cf4cb929c85a5dca872ce1388f93d38645fbeb4bfd77ba89b2787 Cargo.lock bd39e691ce35a1677c6c8a540423f83e51351d7aa9bddd090c9a92408ec2fc20 Cargo.toml 239713948df0d54504989f1ab30f5bf0128b90b4e5ac45d50a132aa033323baf Dockerfile e88ff59b0e79d0c468178a4d9cbe6405175b61d7201112855c83b72b6e4f0fad README.md -f47bd96e96b4e87ab5fb7d319b96f3a57f9e24ce34ab9758aaaa17b255d74390 ROADMAP.md +340b8c205b773fbcfb096190bd854b320f05a0ac1e14a011ffb914f65dd87d70 ROADMAP.md da8311e3db945290666324a2f24bf4521b365272d7ac3f862ded1be993eea646 UPDATE_CHECK.toml 928ba6a504bc431ae100c6e587861e5088b28822d2cb19da5d437b39d26c864a build.rs 834e8de4387354b23a2cb8c2d484f0f641dfed09472a9db12efcd0e683969a06 debian/README.md @@ -42,7 +42,7 @@ ec15163f5f51c9212003b7edd1fc380321311c2496fbaa9b45c838281b9af475 docs/ACME_RFC2 d699f2261a0d7854e49e9b8bae44fa37008a7d2f6340a73cdc37e840722ea211 docs/API.md 96f0cdc4af8961b69c19d0f8204d467b2b70abf3882f1fe1a540c82cac9c063b docs/API_ACCESS.md 0f7f159ad5b4b5277f80c19f3c47f4e7823ea439ef02e5913e1391f1b34d129f docs/ARCHITECTURE.md -fec156479641ffa02c5702dd54f79de8efa1e9768557f2d38e44cd6868bba9e4 docs/CACHE.md +86469d17f9786c3e6f20c66791b47e10e11695d2f1a88c66c9ded157a585c85f docs/CACHE.md 6266163e17d2921468abdae92c1620266af8351321530e2c9b7dca6f3dd89c88 docs/CACHE_DIAGNOSTICS.md c6003dcbc0b95e2cfa9523b7017186cc8b4826248b588af77111ac5eb15174f9 docs/CHANGELOG_TECHNICAL_ARCHIVE.md d99fddfc982316c4e915cc6437fe339385350c49a2d06d570d42fd0100227e78 docs/CONTAINER.md @@ -68,11 +68,11 @@ e7516646dfb107d6240370f4e7460b1189f2eb21f398740381d5d102847bbfe6 docs/NOT_FOUND ce5afb4f531bb5fb4c453deb49f643f2a563f32f7908c995e5bc8e0d7de995b7 docs/RENEWAL.md 585ef0ac4492e03adca46949823e5a7538f56d9768090cd4dc080bfce4305b52 docs/ROADMAP_HISTORY.md 4bf7b3ea0bfe6c6b0ae0b7884b48b10ba29ff3a71611ec96957a3327d3c6ec88 docs/SECRET_STORE_BACKUP.md -63e033f08acafa0bb6ac3c6ff58ba56a185e34c9ad29f94725837aba4f36b2be docs/SECURITY.md +5dbdf45fddba198a28f511dbbd2f12bf7d2b88c41c3cbedbc20dfea3858779d3 docs/SECURITY.md 620b69e566d27af04f0604f4ca3f88cf95cdfea7fbc6ae9dd92446d2b2b5d9be docs/SECURITY_AUDIT.md 0c312c26930153a5e7ee77431d3df4d544b5aadbfcbbb1c8aba2a2d0a7d5e656 docs/SETTINGS.md 3611defd206cde107e75cac006159856d12cd8f15df7ae2eb9ec3592ed2b4abd docs/STREAMS.md -365d85700ce3672afd419f74f3dfbf774278a08fddfed34e43b35bc168a42eca docs/TEST_REPORT.md +007f768f6989e49ee90c6d3c51036630042bdad3bca69b44d453a3c7f11380e4 docs/TEST_REPORT.md cfb452d8496839e832b5fbacdd4e52525b0ecc3112fbb62340c1e580bd5c1717 docs/TODO.md 8ee6187a5460ca45643b7fd789e27bffd264449e3a92ff70e9359edee011bbbb docs/TRANSFORM.md a1e9c6d38d21067d1ce7115ca3395ae8ff1f6a4c40fb0ebf00a6940ef79df439 docs/TRANSPORT.md @@ -106,7 +106,7 @@ bf9b4cf4fec2c8ce287e1b3c2e7d4828e101dafe4d6c173f099819f22493d144 docs/V0.25.5_A da5ec87b9482f2fc506c4334d9365f3bfaec89254a14e5585dd6460326b20e10 docs/V0.26.4_IMPLEMENTATION.md 0ddf5215c40c8366844350bc6462d8013dba747b6f3e8fbf477985af215e5e8d docs/V0.26.5_IMPLEMENTATION.md dd9b5dcdbd53a04fd32458caaf03b56aa335f0153b1a0e332fdf230fec12680e docs/V0.26.6_IMPLEMENTATION.md -d21acc458442278628e524ba0b45eb7baa06a46633376a4abbcc35a8c34e5ff2 docs/V0.26.7_IMPLEMENTATION.md +f9667fe81b31762e64d36126a7e94b609316dfa856de8f8e3b96661dd2a918c6 docs/V0.26.7_IMPLEMENTATION.md 0f0e0e2920c76b2f82f38c6e60ed992a532c63851f593f2a1fa59e8d0014bb41 docs/VHOSTS.md 09b60fb7b40db4d0139fa2a9e69a2aa9f28d4e61b8643521cfc7e936d7df8774 docs/VHOST_ACCESS.md f0e76167944861517d1d42b9186ff0b2f184be0371b9e8597827e60895de4a76 docs/WEB_SERVER.md @@ -126,8 +126,8 @@ c294a5dcb94c1cf7edf72243bb533cc487a17452a7c0ac8c72f23cce0ec42fc6 grafana/rustpr 30763fc61c38992a44bc24ad6932b88fd3b322724fce799db1f17f9a747eb59a install-debian13.sh 858b39fa6886b71d20690bf369e76580922364b3cc7f0cf6ba9b040df9cd76e3 install.sh 29cada0936762f26495064d1524a668262ed729b21f20aebddc8b6e5cfea363b langs/README.md -5a36a455c9ed45749aca05fe28b3d3036e49cd748c6b89c2334973e7b070f2cb langs/en_US.json -ec860b4940fd237b8336154824b40b8f09fc009d3baa505771fc56c9ba2bda9e langs/pl_pl.json +9f367283c849d5217cb9386cf743221cc1d44ea4e76aa50a08234bbe71455837 langs/en_US.json +028c8d841c8cf246a021675054e638d6ab9f0c9785f823e2e4eec60a70fa8823 langs/pl_pl.json 8b258ac4654a046dc649c7fa8cef273c0f9431c9a12ea9b772dd0a1c95bb281f make_zip.py e830d37dd1f81a4b0aa7d535f5bba69e34e433b0fd99cc8ee0b296786c32379a migrations/0002_admin.sql 20112cc82192098b8d602f1c4f7ca08712e9e1366c845fabb92753187c370d35 migrations/0003_certificate_renewals.sql @@ -147,7 +147,7 @@ edb6ee1445b01cd6f3a74a3a607f39fb107d411b49df028d2e0f4679e093de31 scripts/acme_p e69813fb1d3a4cdcfb7243964cc323fc21a603087bf2e84188fa42b9d3cee4b5 scripts/acme_rfc2136.py a5b4451e45ce975685772aa8409b64a57a20a7548466584c3ea7fb975e64729c scripts/admin_audit.py 20e83f8b6347b819d1d1ea3de5c691c36f0816954a4210b0d3f39557fefe1931 scripts/backup.py -f79fa03aa2b5f0c04d37c108af55d8c43f9faf402f16553d5348c33a088e6108 scripts/check_source.py +1d88238e867dcc45c9666f765667674a7dce595a6db578dbfec15311b751f567 scripts/check_source.py 187ee92c8029cdd59e89b4447cf4d170e856017a2091ceb85ae7c22dd1a79c72 scripts/deploy.py fe28d6d580a53d95a0fc318ebc4da5bbc71a23781bb827158848934985477035 scripts/deploy_core.py f014472588e889488976970dbaa95a8745b6907516aa81a7cca21d0f81eaaad3 scripts/deploy_runtime.py @@ -235,7 +235,7 @@ e6c4d91d1542d0a5b47bb8736f9539d43a6713df5a473b635519d5b7eac2eb9c src/admin/web/ 0a5fff35555153f59d4346933030a67b6e1a8768cee7a47cfa2fcf1a2c564f63 src/admin/web/favicon.svg af6e7a2e890df2fb7385a374bcb3fba52fb5a53dbe18adc1fb7865660fcba842 src/admin/web/file-logs.js 631860ab3793ffd827c7cf19ddd049d14419509f2c2d8b27994b0e54baa0e32a src/admin/web/host404.js -1167c964000bb5dae1ba92b850ff76162570af340029d8788296160adc9f67b5 src/admin/web/index.html +4e8c9a1a1bd9870f0cd8aad5c9da80ff130497f11dbda116d79f91d9bfc129c6 src/admin/web/index.html 24db88842707f764064657712d3660c6ac129fbfb47d188c0903925cf8244ce5 src/admin/web/integrations.js cdab0c11a28deebdf401c0453fbc76b675e9e643722106fb20e812bb9648ccde src/admin/web/login-keys.json a253d202dc9a147f2add34c64e0f35c38fdc7f667f9908933ce5f959b1a92a2e src/admin/web/login.html @@ -247,7 +247,7 @@ f1ab20afa09f75f3635511756e36afea46a7917f04937d6f4e89c4e9f3f43204 src/admin/web/ f5831c2188233e425beecedc9e5e2829b620f80fc5326b73198024d27b81d1e7 src/admin/web/style.css a8a73a4fa849ae49391fcd6143e900c515c8b577f71b55cbae9701fa9f5bbe47 src/admin/web/traffic-panel.js e686d68fd6a368110a85dc4c5dc64e8093950d20d63e9aa44790c03dea6fc193 src/admin/web/transform-panel.js -106db335a6dd3e326955241e1d67caa5562a427b0356e7433cd0d92087342ce8 src/admin/web/vhosts/core.js +6856c230c4f6b18145e16efb6636433f8b21ce3ec5d34246d6561f0150ea0554 src/admin/web/vhosts/core.js 4d4ee863a3d77e5213ae4bdcad1f533a6222353b9c32e0b5f12f7ea60ab62bea src/admin/web/vhosts/editor.js e0011edc708d245cb514be170c1bbe846a0298b81d86276fe29af05010d215a4 src/admin/web/vhosts/render.js b3d8d3e22e4cbab10c5d588c268da6eb3075a9ec857728ce6b5d56e3ffd3c9a6 src/admin/web/web-server.js @@ -340,8 +340,8 @@ fe571c85a924c827097f4be01b3a827a16bc5dd17a55fbf991ee3ad016641305 src/docker/tes 057e652f216a1478638cbb53b1c64ac88c7f413a65825caacbf893c5af004a63 src/forwarding/tests.rs 72215ef6911893f55cc82278169268f03d869b94728f118bf007fc555d609fde src/geoip.rs e40171e72327bc4350ba95cedacde2f3c9148c26a5a232d9f790f4449f20a685 src/geoip/tests.rs -4e009ec10151a068fa83cf93cac78d2254d152e0386442586d6f5860ab2710b4 src/headers.rs -01cb98570ec388170420883e4ba18b2bf85ad1af97854dbc3a12b135db511c5c src/headers/tests.rs +13269be4ad8d3e4c91893753f654c3022e6f86d171c5d1ff21eda2d9185ec61f src/headers.rs +fbb6859780309f8cca1aeaba43fa67d13a1edf6f5a60c5c982d2067b71fb0846 src/headers/tests.rs d0cd8589321595309834690fa9ddb98488886bc98f34ea45aa0ccb3035412fb5 src/http3.rs 2165a0a4b27d621985e2030326ad52b8bbd59d7b9e4f092f72f7e92b4e58b497 src/http3/body.rs 68bc11160bc5275a904e48af8698b37433096fb6d592364d8281d59bb9e2b3f4 src/http3/tests.rs @@ -376,7 +376,7 @@ d3c6b08088df0003144544936a55e2a3661aac85292821b594f00adfd19a2951 src/prometheus e03f0d6b3f35dae6b98c394837aa0d17e4d73a8306767b4c607868bc00c30286 src/prometheus/vhosts_backends.rs b5856fd38a957b2ca9c7e3606d84d13d5cfcf3a45b487b15ae1d2dc248cbda57 src/proxy/body.rs 16b9d4db3b20b2ab14c47ac14fcd18d3d8ca77c3ad9a1f37866ebfa60f379862 src/proxy/body/tests.rs -00e50a914511754266b4eae2626244587174bfa71fff91509c530bcde7f0d397 src/proxy/cache_helpers.rs +f0cb26ed34c35bacc74b914457acac8a611390de14cf46e2e6d3bcc848e914e8 src/proxy/cache_helpers.rs cfb0910af8cd868bde3f6c9992319e46d5328d6d8f69c50701df0ea12bef2108 src/proxy/forward/cache_lookup.rs 212de22f407dd96800afcf65fd1fc7c40fede1b88f80d04850eb8d1227b08a5b src/proxy/forward/response.rs a74deecbdbc5953c46b885a4627b3d1e820752b03921b80406ae11080ea56cc4 src/proxy/forward/route_cache.rs @@ -389,7 +389,7 @@ c438066616527a3108f2ad53e3698ae9b2a80961714394cdd0a450c92f99d992 src/proxy/head f6aef54204b5bb9305dd1367818c7ffd3cb273008404c9fab0317af1d13ba7a6 src/proxy/mod.rs d75ff3e38affa49f9a8b9d6801454c1449458e5fbf07e08d51aa3f42abebafd5 src/proxy/tests/authority_tests.rs 622d44511b82883a34830d0ae3ea665fd40b58eaa85653f58588db92d55a17c3 src/proxy/types.rs -352260ef9e956534bc91b5cb888e3f8e881913c0bb988e6af95e49933d98814d src/proxy/upstream_helpers.rs +b09929990cd34db718c6bc82bd7ac9c711cea6dd52c1977febec6d800fbdd991 src/proxy/upstream_helpers.rs 69f775f6746b4c6d729dc10961dbef54168846f4ce9cf7fe453ab5a2b879c9b8 src/proxy/websocket.rs d05e655ba0b3b322c657aaa9c2cbe7a0181064a896026b5eeaca347c4a0b7831 src/proxy/websocket/handshake.rs b21dc9cf3817dd4e3273ce25887d63d7a772c477b86ca57f8d5b72b8154456e7 src/proxy/websocket/tests.rs diff --git a/docs/CACHE.md b/docs/CACHE.md index b424307..c572cce 100644 --- a/docs/CACHE.md +++ b/docs/CACHE.md @@ -284,8 +284,10 @@ Cache-Status: RustProxy; hit; ttl=556488; detail="cache_hit"; transformed Origin lookalike values (`Cache-Status`, `X-Cache-Status` and the other RustProxy cache diagnostics) are removed before RustProxy emits its own diagnostics. HTTP `Age` -remains present on reused cached responses because it is protocol freshness metadata, -not a debug header. The Cache dashboard also marks transformed objects explicitly. +is generated from cache freshness metadata on reused responses. For 0.26.6 configuration +compatibility an explicit response-header rule may set/append/remove `Age`, but that rule +runs only after cache lookup/revalidation/storage decisions and therefore cannot alter the +internal freshness clock. The Cache dashboard also marks transformed objects explicitly. ## Pool behavior diff --git a/docs/SECURITY.md b/docs/SECURITY.md index 41eab75..7365e79 100644 --- a/docs/SECURITY.md +++ b/docs/SECURITY.md @@ -121,8 +121,10 @@ update and purge paths. Purge is authenticated, CSRF-protected and audited, not public PURGE/BAN capability. Compression is opt-in, with authenticated/private/no-transform exclusions. Response -rules cannot overwrite protected framing/identity fields or the cache-controlled `Age` -header. Required Age remains on cache hits even when debug headers are disabled. Server hiding is cosmetic and +rules cannot overwrite protected framing/identity fields. For compatibility with 0.26.6, +custom `Age` rules remain accepted. Response-side `Age` is deferred to the final wire stage, +after RustProxy's cache freshness/revalidation logic, so it cannot alter stored age, TTL or +cache eligibility. Server hiding is cosmetic and must not be considered an access-control or vulnerability mitigation substitute. Standard public 80/443 ports are supported without globally forbidding remote diff --git a/docs/TEST_REPORT.md b/docs/TEST_REPORT.md index c8ba2a6..6e56345 100644 --- a/docs/TEST_REPORT.md +++ b/docs/TEST_REPORT.md @@ -12,7 +12,7 @@ Static source contracts require all four `/cache` occupancy meters (HOT objects, The existing upstream-client unit coverage retains age-triggered rotation without user traffic. A new pool regression, `compatible_pool_rebuild_reuses_upstream_clients`, verifies that a compatible rebuild reuses the previous compiled backend/client object so rotation state remains continuous. Source contracts also require the `reusable_with` compatibility check, maintenance calls for normal/WebSocket clients and backend reuse path. These Rust tests require a compiler-enabled release host. -Cache regressions now require a stored HIT/dashboard object to advance `Age`, while compression regressions require `Age` to survive encoding and require cookie-bearing compression to stay blocked unless the internal cache/static safety marker is present. Source contracts protect the `Age` header from custom response rules and require the bounded HIT/static cookie-compression exception. The bundled compression tester no longer forces `Cache-Control: no-cache` unless `--revalidate` is requested. +Cache regressions now require a stored HIT/dashboard object to advance `Age`, while compression regressions require `Age` to survive encoding and require cookie-bearing compression to stay blocked unless the internal cache/static safety marker is present. Existing 0.26.6 `Age` rules stay loadable; response-side Age is tagged as a late wire-only override so the generic response-rule pass cannot influence cache freshness/storage. The bundled compression tester no longer forces `Cache-Control: no-cache` unless `--revalidate` is requested. Documentation checks cover the 0.26.7 release note, Reader index, local Markdown links, cache diagnostics and container/ACME provider guidance. Packaging smoke tests verify the 0.26.7 release identity and deterministic source archive contract. diff --git a/docs/V0.26.7_IMPLEMENTATION.md b/docs/V0.26.7_IMPLEMENTATION.md index a02e84b..3afa505 100644 --- a/docs/V0.26.7_IMPLEMENTATION.md +++ b/docs/V0.26.7_IMPLEMENTATION.md @@ -36,9 +36,12 @@ Current cache, vhost/backend and installation documentation was reviewed alongsi The cache freshness clock remains RFC-oriented: ordinary stored HITs advance `Age` from `initial_age + resident elapsed time`, while a successful validator revalidation starts a new freshness calculation. `X-Cache-Resident-Age` remains the monotonic residency clock -across revalidation and tier movement. `Age` is now protected from generic response-header -rules, and regression coverage explicitly checks that both the wire HIT header and `/cache` -object age advance from the stored clock. +across revalidation and tier movement. Existing 0.26.6 custom `Age` rules remain accepted +for configuration compatibility. Response-side Age rules are isolated to the final wire +stage, so set/append/remove cannot feed back into stored freshness, TTL calculation or +validator revalidation. Regression coverage explicitly checks that both the wire HIT header +and `/cache` object age advance from the stored clock before any optional presentation +override. Compression still refuses Authorization, private/no-store/no-transform, Set-Cookie, ranges, SSE, upgrades and already encoded responses. Cookie-bearing requests now have one bounded diff --git a/langs/en_US.json b/langs/en_US.json index 42d858b..a82041a 100644 --- a/langs/en_US.json +++ b/langs/en_US.json @@ -270,7 +270,7 @@ "cacheDefaultTtl": "Fallback TTL for public responses (0 = off)", "bypassQuery": "Bypass URLs with a query string", "cachePrefixes": "Bypass path prefixes, one per line", - "cacheAgeHelp": "Age is always sent on cache hits. Counters remain available even when diagnostic headers are hidden. Only cache-affecting configuration changes invalidate incompatible objects; managed software updates hand hot objects to cold storage when the cold tier is enabled.", + "cacheAgeHelp": "Age is sent on cache hits unless an explicit response-header rule removes or replaces it. Such Age rules are wire-only and do not change cache freshness. Counters remain available even when diagnostic headers are hidden. Only cache-affecting configuration changes invalidate incompatible objects; managed software updates hand hot objects to cold storage when the cold tier is enabled.", "saveCache": "Apply cache policy", "purgeCache": "Purge all cache", "customHeaders": "Global custom headers", diff --git a/langs/pl_pl.json b/langs/pl_pl.json index 94a1f1f..264015e 100644 --- a/langs/pl_pl.json +++ b/langs/pl_pl.json @@ -270,7 +270,7 @@ "cacheDefaultTtl": "Zapasowy TTL odpowiedzi publicznych (0 = wył.)", "bypassQuery": "Pomijaj adresy z parametrami query", "cachePrefixes": "Pomijane prefiksy ścieżek, po jednym w wierszu", - "cacheAgeHelp": "Trafienia zawsze zawierają Age. Liczniki działają również przy ukrytych nagłówkach diagnostycznych. Tylko zmiany wpływające na cache unieważniają niezgodne obiekty; podczas zarządzanej aktualizacji hot cache jest przenoszony do cold storage, jeśli cold tier jest włączony.", + "cacheAgeHelp": "Trafienia zawierają Age, chyba że jawna reguła nagłówka odpowiedzi go usunie lub zastąpi. Takie reguły Age działają tylko na odpowiedzi wysyłanej do klienta i nie zmieniają świeżości cache. Liczniki działają również przy ukrytych nagłówkach diagnostycznych. Tylko zmiany wpływające na cache unieważniają niezgodne obiekty; podczas zarządzanej aktualizacji hot cache jest przenoszony do cold storage, jeśli cold tier jest włączony.", "saveCache": "Zastosuj ustawienia cache", "purgeCache": "Wyczyść cały cache", "customHeaders": "Globalne reguły nagłówków", diff --git a/scripts/check_source.py b/scripts/check_source.py index 56ca808..e940434 100755 --- a/scripts/check_source.py +++ b/scripts/check_source.py @@ -801,8 +801,17 @@ for marker in [ assert marker in compression_finalize_source, marker headers_source_0267 = rust_source(root, "src/headers.rs") vhost_core_0267 = (root / "src/admin/web/vhosts/core.js").read_text() -assert '| "age"' in headers_source_0267, "Age must be protected from generic response rules" -assert '["host", "age", "connection"' in vhost_core_0267, "UI must protect Age consistently" +for marker in [ + 'pub fn apply_wire_age', + 'wire_only: bool', + 'wire_only: direction == Direction::Response', + 'rule.name.eq_ignore_ascii_case("age")', + 'if !rule.wire_only', +]: + assert marker in headers_source_0267, marker +assert '["host", "connection", "content-length"' in vhost_core_0267, "UI protected header set must stay intact" +assert '["host", "age", "connection"' not in vhost_core_0267, "0.26.6 Age rules must remain UI-loadable" +assert 'apply_response_age_rules(' in compression_finalize_source, "Age wire rules must run in final response stage" compression_tester_0267 = (root / "scripts/test_compression.py").read_text() for marker in ["--revalidate", "if revalidate:", 'headers["Cache-Control"] = "no-cache"', "headers.get('Age', '-')"]: assert marker in compression_tester_0267, marker diff --git a/src/admin/web/index.html b/src/admin/web/index.html index e0008a9..d2eb1cc 100644 --- a/src/admin/web/index.html +++ b/src/admin/web/index.html @@ -2172,9 +2172,9 @@ type="checkbox" />Cache-Status (RFC 9211) -

Age is always sent on cache hits. Counters - remain available even when diagnostic headers are hidden. Every configuration - apply invalidates the cache.

+

Age is sent on cache hits unless an + explicit response-header rule removes or replaces it. Such Age rules are + wire-only and do not change cache freshness.