diff --git a/AGENTS.md b/AGENTS.md
index f76f70f..2c299ad 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -1,6 +1,6 @@
# RustProxy source and documentation maintenance
-Current source version: **0.34.6**. The Cargo package and binary are named `rust-proxy`.
+Current source version: **0.34.7**. The Cargo package and binary are named `rust-proxy`.
Before editing, read [README.md](README.md), [ROADMAP.md](ROADMAP.md), the relevant [documentation guide](docs/README.md) and the actual code and tests. Historical release experiments are not current specifications. Use the bundled `src/admin/openapi.json` for API routes and payloads; the source implementation is authoritative for runtime behavior.
diff --git a/CHANGELOG.md b/CHANGELOG.md
index a629f6d..e78c70a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,7 +6,15 @@
# Changelog
-Release history focused on **features, settings, default behavior, compatibility and fixes**. Changes to internal code structure and preliminary performance experiments are intentionally omitted. Historical descriptions reflect their respective releases; consult the current documentation for the settings available in 0.34.6.
+Release history focused on **features, settings, default behavior, compatibility and fixes**. Changes to internal code structure and preliminary performance experiments are intentionally omitted. Historical descriptions reflect their respective releases; consult the current documentation for the settings available in 0.34.7.
+
+## 0.34.7 — Varnish-compatible cache lookup (source candidate)
+
+- **Settings → Cache → Varnish-compatible cache policy (`varnish_compatible`): ON by default**, including for existing configurations without the new field. OFF preserves the legacy stricter interpretation of incoming `Cache-Control` and `Pragma`; the toggle is applied live (no service restart), invalidates existing cache entries for storage-policy safety, and affects both reverse-proxy and embedded Web Server cache, HOT and COLD.
+- Varnish-style lookup ignores client `no-cache`, `no-store`, `max-age`, `min-fresh`, `max-stale`, `only-if-cached` and `Pragma` **only as cache control signals**; it does not remove request headers from forwarding, Vary keying, downstream conditions or user identity. Hard reloads of a fresh asset remain `HIT`, retaining `Age` and counters instead of refetching without origin validators.
+- For **origin responses**, default-compatible mode rejects `Cache-Control: no-cache`, `Surrogate-Control: no-store`, and responses with no remaining TTL. Previously protected `private`, `no-store`, `Set-Cookie`, Authorization, Vary and all explicit RustProxy cookie exceptions remain intact; an eligible stale object may be served during up to 10 seconds of background-refresh grace unless RustProxy's stronger revalidation restrictions apply.
+- Scope deliberately excludes full Varnish/VCL or hit-for-miss emulation and the 120-second implicit origin TTL default; RustProxy keeps its configured default TTL and existing safety limits. To compare live behavior, enable diagnostic headers and inspect `Age`, `X-Cache`, `X-Cache-Hits` and `X-Cache-Reason` before/after hard reload.
+- **Delivery:** source candidate, requiring native Rust compilation, integration and production acceptance tests before deployment. No binary release is claimed.
## 0.34.6 — Docker live logs, neutral Publish switch and Vhost Content-Type rules (source candidate)
diff --git a/Cargo.lock b/Cargo.lock
index 30a8781..4423d1e 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1881,7 +1881,7 @@ dependencies = [
[[package]]
name = "rust-proxy"
-version = "0.34.6"
+version = "0.34.7"
dependencies = [
"anyhow",
"arc-swap",
diff --git a/Cargo.toml b/Cargo.toml
index d370e88..d5ce055 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "rust-proxy"
-version = "0.34.6"
+version = "0.34.7"
edition = "2021"
rust-version = "1.99"
description = "RustProxy - independent reverse proxy with local administration"
diff --git a/README.md b/README.md
index 277ee03..a2ec2f6 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-# RustProxy 0.34.6
+# RustProxy 0.34.7
RustProxy combines a reverse proxy, static/PHP web server, certificate management and traffic monitoring in one service with a browser administration panel. It supports several domains and backends without requiring a separate proxy configuration language.
@@ -16,6 +16,10 @@ RustProxy combines a reverse proxy, static/PHP web server, certificate managemen
Features and default settings vary by component; configure only the capabilities you need. The [documentation index](docs/README.md) covers each workflow, including prerequisites, security boundaries, troubleshooting and API access.
+## 0.34.7
+
+- **Settings → Cache:** Varnish-compatible cache policy (on by default), with legacy strict semantics when disabled. Prevents client hard-reloads from needlessly refilling still-fresh HOT/COLD objects; respects origin cache privacy and preserves RustProxy static-cookie handling. See [Cache](docs/CACHE.md) for the scope and important exceptions.
+
## 0.34.6
- **Docker vhosts:** **Live logs** beside **Open app** opens the existing HTTP access-log viewer, filtered to the selected generated Docker vhost and its aliases. These are RustProxy request logs, not container stdout/stderr. Open app honors HTTPS and nonstandard listener ports.
@@ -95,4 +99,4 @@ The authenticated **`/docs`** page includes the guides and a separate interactiv
## Status of this source archive
-Version **0.34.6** is provided as a **source release candidate**. Configuration, ACL and TLS changes require native compilation and integration testing on the target systems before a production deployment is declared. See [Installation](docs/INSTALL.md) and [Roadmap](ROADMAP.md).
+Version **0.34.7** is provided as a **source release candidate**. Configuration, ACL and TLS changes require native compilation and integration testing on the target systems before a production deployment is declared. See [Installation](docs/INSTALL.md) and [Roadmap](ROADMAP.md).
diff --git a/SHA256SUMS b/SHA256SUMS
index bf61241..9330110 100644
--- a/SHA256SUMS
+++ b/SHA256SUMS
@@ -1,12 +1,12 @@
61bf40a0572889dc8b0dda9eae4e93e44b0de9364b3c798106c85700ffb37c23 .dockerignore
4140a2956264b44f259e6a37fc00ba02097bbe68b09296e04d3d243c1287129b .env.example
9e6356475bf587091bab72246ec9e325b498f7e48a6220e9a18baa50d0a385a6 .gitignore
-893ba606f52309e31b3d0612350a9cdeb36d0414325bc06e71e2f7ce15e755cb AGENTS.md
-72dc91c90b524db7571a8916a4409d0faad41fafc4da14987eecc396adc63290 CHANGELOG.md
-4865f5f0a9cbc64899b70acc0f6ad328bbfa40560a78d39874e4b9563d2f56b9 Cargo.lock
-fbba365b98bfc31b891d8ef240270b76987d67778b4d795552069e6b94f3f9ea Cargo.toml
+10e5382f535df61cc2e5905d83a61d40ac3e60572e7ff8e05bad6271d871b6c5 AGENTS.md
+d88bcb686fed1626510867d9b44a9db4e6020a65e9c2369ced781e5744f64022 CHANGELOG.md
+32a192c94173ec66cce81890c71f235febeda7cf59bc8581fc982e1a0759b296 Cargo.lock
+82922877469166aff8eec6805e56f9c7f07b95dba2dc02d17c9c9fd5f39747fa Cargo.toml
25c7f3c8162cbf5cc156439774118a81dae9fdc52b611ec7e40c230fc99a772c Dockerfile
-fcd1ace66c47e43e13b8cfadd76a9ae02ad545af944fa684c489034227776432 README.md
+626f18ec4028ae66ec4b65eb8dab83405e568d64396a3e58d25a247851fecb90 README.md
ae6d14ada6fde7d0b8514840b821678418cf5b1816c18434e3b7fb2ae27a0b21 ROADMAP.md
da8311e3db945290666324a2f24bf4521b365272d7ac3f862ded1be993eea646 UPDATE_CHECK.toml
7309cfaa188c7a1fcf30be1b8313ee99c00b7fe5d6d626ddefcc7345fa066112 build.rs
@@ -32,8 +32,8 @@ e52b31d0abf65ae3034f6cb367cca113633014ce8d1d799ad4dd5624d2c7b8bb docker-agent/n
9268ab7fe86683dacd64bafbd9e0edc8956ce9b9ef6277cc6ada61c3fcb84746 docs/API.md
2362ab34020d4e0dcd70e280e9539ef7764b63212856ee08a3a55906c48f6421 docs/API_ACCESS.md
728b15b9825f547f34c4121219784798dd046fbbdd72ece8906d0cd77e8efc64 docs/BACKUP.md
-0305f4e464cae51d50ed6a171571515505aab3bc3aacdcfaa632f252460cd4a8 docs/CACHE.md
-c81c6ee84e6af6507926144f8caf1e94daf497a8a0159449a3808088a11ea045 docs/CONFIGURATION.md
+e072271ddba43e3759b9ea7702c41a8357d13008f8b664c62fa860eadf2f1e1e docs/CACHE.md
+c3f4cb4e32d90a2f334d864cc3fb051f6a7d662f37daa554a8988530b6dec56f docs/CONFIGURATION.md
80bcc666736b10f6202386d0342e8d6feeba858d77aea310bf3ec6de01c2bfb3 docs/CONTAINER.md
dc670d912a6a946160c2f8528c9bb710ec38ebe406dcb7dcaf18fb2653f667b6 docs/CUSTOM_LOCATIONS.md
9fb2d0bcac70d1883dd16557622851a1f0527b3d3569a4b5177f5e6dedd3c74d docs/DASHBOARD.md
@@ -44,7 +44,7 @@ f1baabe34e8a1b204d7c78e2f558c019c156b03adfa6ddecb931b4b8a5501f78 docs/INSTALL.m
888cdc8c56e10b8a7615012e192e085bf2899d0ec9b3ddfb5731e7de6ab5bcde docs/MIGRATION.md
140b95ad778261455f269f2144a1c61c2315bd3b85300fb613822eacddf3cfc2 docs/MONITORING.md
d5894c07c68ec4230987767198434abee13b0e525842fea21bcbe752fa82742b docs/PHP_FPM.md
-f72a94114558f15341842352146c1743f79bb1f7fbca3b93b7ca89368a398961 docs/README.md
+6af7d306dc32ad03408a4bafcb819f7ef430fcc34fdbea460504483fea31b84f docs/README.md
490a6dbe870f2b1fd4ec7816768dde6c86fa7957fc9de2d2f075e123c9222222 docs/RESPONSE_DELIVERY.md
e2b36152c13d65621a367c69dd400118dae1e4426a4d2b2139d2f63fa30442d6 docs/SECURITY.md
bbef60ff1771da9f48af812987766e1e479408873ae2f079b13f1d5c62ecc6ff docs/STREAMS.md
@@ -76,8 +76,8 @@ cb01fdef286f38b442dd9252c23c4f8e44eb72e9ecdd99adb926e8e9f6318bb1 integrations/r
96563a83e87cfb33e238c2a970ce36b1a1b51e91318d09b123c3755002ba2646 integrations/routeros-oci-build/build-routeros-oci.sh
3f267cafa16006e5456ade78ee2d5fae02cc7ce747839523068ffd8d7c98798a integrations/routeros-oci-build/docker-entrypoint.sh
13189fa546c3488dddd8efc80c47f6da5241e5fc28b79cbfe795414ea05c7a4f langs/README.md
-7eb29175875efda638783d2c802eac176364a9e6c156df8960ab1f1099f366ef langs/en_US.json
-00dab018f5548e87b790ecbdad700aa01a595c6d5f439d61d146e84b0acf2a06 langs/pl_pl.json
+d08c2f6ea2abc0fc848300c2bfd911885863de81bceda533d10991cc55a93e97 langs/en_US.json
+1cf4e525442e65e6007c54304197e71853b8991d9a5990dfdae6e72b1de389e1 langs/pl_pl.json
a99ad040be10fa028351e290b9363236b3513a1cadbdc9fb9e0260d517b9b0ae make_zip.py
e830d37dd1f81a4b0aa7d535f5bba69e34e433b0fd99cc8ee0b296786c32379a migrations/0002_admin.sql
20112cc82192098b8d602f1c4f7ca08712e9e1366c845fabb92753187c370d35 migrations/0003_certificate_renewals.sql
@@ -98,7 +98,7 @@ ee50f38c037765fab742e888d4b9fc4d874c31c785c6064d4eca3d2c4d24d944 nagios/check_r
7458b2d74495e6fb1c1edeea4d5a793705476431dadb60627187111f91441e13 rust-toolchain.toml
bd313cacfc1b450a90368b30ae39ab48b877c8bed3c2db8bbd4e4a1f40865c9e scripts/README.md
f550ffab868c5241ff5d43d9ae569e19f6842b324b80ecefdc7034642125ed9b scripts/audit_css_usage.py
-31953ddf3fda1c9b47fb5de7f85b91a23782b4ccc9555b8423a965659a0a8786 scripts/build/swagger_assets.py
+216abccbb8b0b77b28de96382bb5790d1ce831699746d3fb06ef13a6dd1f5d21 scripts/build/swagger_assets.py
e4d15aa6aa864d04b9b30aca33826b833632af02ca643f8b23e219a5ea1298dd scripts/deploy/deploy.py
618603239b000bbe4af36a6a6ee268758af632c761fc53fc6b7f44a4a818bdf1 scripts/deploy/deploy_core.py
8c7da13e95bcddd2bd1b4f1b22ade1c5ac1ecf54448601daa8416905d4239751 scripts/deploy/deploy_runtime.py
@@ -106,7 +106,7 @@ a641bd35400c56f3b68b0a92e97b602d06090f03972ca8f01fa744e90dd97403 scripts/deploy
2cc658faaa610b21b48942c59b955525539ad4503fd60f2a49c7e626a22faaff scripts/migration/migrate_npm.py
a459d95bbb0076f33ade8b273b813308167f9d8d45242b309a2d18320ca0093c scripts/migration/migrate_npm_api.py
31ccad3ec3c880119f3b7002f0c6652f8b43634edad8ab3763cb0e4497d0bb1f scripts/migration/migrate_npm_core.py
-91c5ab0f82af5a4eb5589f5ebb19975f053eacaa46fa3d59b74f3ddde6370562 scripts/preflight.py
+3077405aae2dd0f32c0e168ef710745bd44e42283a4c566ab411e68d3bb745af scripts/preflight.py
3d6a0503afc25beab79ddc86864bcbb15248ded7368d33aa64321b8cdff59933 scripts/resolve_dependencies_0312.sh
20124173452b4514bad8850c1637569a9a191882478451e549bd16b432605fc1 scripts/runtime/acme_provider.py
e69813fb1d3a4cdcfb7243964cc323fc21a603087bf2e84188fa42b9d3cee4b5 scripts/runtime/acme_rfc2136.py
@@ -123,43 +123,43 @@ b9eff08fddf9b8787aa04e72288ea2ca0033965e4563d060ca51f267e4963918 src/acme/jobs.
f7f737aa28d2d209f4f20a221885e3bb3596dfc8e3c8c9a22ba53bb975c52df8 src/acme/model.rs
40cd44f2b0d43ba45471ef5a012b3737ca3e16e33f6404b4f13b9cd9bd57f0ac src/acme/providers/mod.rs
d1dcb7bdfb7cfdc9c3b88cfb6908201c58532bc888744a13f45853079f214659 src/acme/providers/tests.rs
-3ec53c7f6e1feb1dcd23bf4ab54cabd8b3601d48977cc01a0ec47c3b2bd88182 src/acme/runtime_bootstrap.rs
-069b79d455d1126fd3967837493af896a2da9c584ceb582f2ffcceff321795eb src/acme/runtime_env.rs
-579ddf69314d7f1e11270b00135de64762d77d5ebc25bf98a52945086a4cea72 src/acme/runtime_versions.rs
-9c1fa211bfd307ce301ea7ef5cdac15269d69d5e01f47bc08a4cfc26502c56ac src/acme/tests.rs
-1171a1854708210e2f2107445a7c39620b8048478ff0f252f20193be5385cdf9 src/admin/access.rs
+c51fd51177a476be6462ca980e9bc13f0d0b41538f520118b80a685130f0dbf0 src/acme/runtime_bootstrap.rs
+5a684eff5f3539c7bb8f66c3b83e7fb62527c52c61da727079d3897e0943f952 src/acme/runtime_env.rs
+2f02b08d88ad3c1fc9827e5bd3ef463effba633834d9c05e9c0d6d2a0e8869c5 src/acme/runtime_versions.rs
+cfc13a293c126bb511745859669719a14c72dd7ff6be197bc9e0d0e560deebbd src/acme/tests.rs
+b28a08ea996befe10949676f40fab5f1036a274c7d0ab1175cf5c43c59849dc3 src/admin/access.rs
bcf131abdae425a85b5a54ade51346f623de1e10fa08e18f7c10f1fd2dd0aec1 src/admin/api_token_access.rs
5f5b150bb8f51f57462e519650093354ae7b40fcb80c4380fd3391a33f4b30f2 src/admin/api_tokens.rs
-852820625bd330f6eb87aa734d02ef9f42d1eb5ce31b0f10a8cc06b1287b5bf1 src/admin/certificate_api.rs
+34e851f725e8605e3c5d9946e56ac035996f3bd9d608169cba3408060d229c9b src/admin/certificate_api.rs
a402209141667fdce69698a60dc0b867248effa191494d0a0d93d468d7df9476 src/admin/certificates.rs
521ac794501570cfa2e8e50c3a5cec2ca08ee4dbce8ac9c0e0310c09612f1062 src/admin/config_reload.rs
159c3970d25fa29acf2483fc9422b003e5d63884713f62baa8375e4a4020730e src/admin/dashboard_presets.rs
-e9b03088840689636cba66eae0e4e53c495900aae3c2021add6ea3a2ef91977b src/admin/documentation.rs
+aae1ca0e70d987830bd63948d431f54302083148177c1b551565be12df7fe771 src/admin/documentation.rs
d4a249e8c2bf06a12fbd561fcdf5a5211aa5ed0e0dcd5111b84bbb13b3640c49 src/admin/documentation/documents.rs
67b901485d5858d5b5bf78a6260035db32241531d99481754c3533fdf404facb src/admin/documentation/tests.rs
1ce779b84aa8f47bdb3c34f83593c1f2f06d2235f0319847096cfcd035434168 src/admin/file_log_search.rs
ab18acf6fb4ac86fb22635b9219a12dac76d24952c8f15538486267a9b4b7855 src/admin/file_logs.rs
-b4f225850d3d137ef23569d69774a46ccd5b02b21f7a035133cd14f45179d8ea src/admin/file_logs_io.rs
-75a51d477283f98d1b0d9b0aba1d593681fe4d120e243d9807c7ab3aa3ec21b5 src/admin/file_logs_query.rs
+d58a2ed83319176de4e66790ed292447c9497ae031464ec55cfe27174acb639a src/admin/file_logs_io.rs
+282352eda7957477e7da44f16b90984b26a4a67a8755833bc0a6b34eaf93e3af src/admin/file_logs_query.rs
f66ff718f82a326f80808b0a5088bd05a48625be802e5ba305fff3c344b59948 src/admin/logging_api.rs
1ba0520c6348246cbb35b60e596e99dc600137c0696de86508cf06587bd86563 src/admin/mod.rs
-fff31f340853b3f1a26b443e483a0a3937acb1a2cdaff67643933a32a06887ac src/admin/openapi.json
-74ad6cebcdfdd5ded422c6a720b5ad7d5f9566f1d995efeaec95319e2fe5a452 src/admin/operations.rs
-d75c1d31c8b57d64b0bf8d925b0b7630411b6a4b3e4be239fd9b8c82b5b97a82 src/admin/panel_assets.rs
-1a54d9c0594070d24e0faaf9497208085a5c7e0345dd30125e700727be34e010 src/admin/panel_content.rs
+4cd8f528ef3be20d7b58c928e368afca1c4edc4db22840d2e9effc309aa43bcd src/admin/openapi.json
+7cfd6593ac9bcea3d1b9e61bbcb7ed98d65ed3190f54f94c1e104541f4fbb4f5 src/admin/operations.rs
+f14afb6ae141053d83d0dc59df835b20e38a37a9e83f86f0f2053f2bd5d9ce57 src/admin/panel_assets.rs
+f5127855c2994d052678865df36d703b74f4a0afc633daf7718b10da18d26e37 src/admin/panel_content.rs
730c559afaa8a50affc3eb6dc6fbde7005c0356237352fcf8c5423b65725a8fe src/admin/preferences.rs
35a7f99c7448c90b8637f4b3a7becca138f1f378fe5dc3f87122151525bb20f9 src/admin/preferences_columns.rs
51dbfdf8b228cd4a381aa720b19146418d23763670fca74ff729bd88b13d6782 src/admin/preferences_tests.rs
62ecbae5dee00aeeca3eb806e2605372471dfab971cde8f66f11e711df8fcea1 src/admin/public/mod.rs
7a00e4ab943f74d2b1bdcbfab7f9cd3f584e9f59536b4aca6c4c31f5f5508d12 src/admin/public/tests.rs
-e81a0357d88ee3e3f9031755f4b0e2f5d381936abbbe569c5cde4cbc421b64e3 src/admin/refresh_preferences.rs
+6930b4f4b45257772b321b20a9becdf9bc4610274852948ba38c2d0cdf02dfaf src/admin/refresh_preferences.rs
00b5dd3090792986217b28c69bf826748145129e5517b260d95019b1d7b2ebb2 src/admin/router.rs
-2e7b0871e4af18ed3410f5b79c5fca6c75e6593d71b70b90aa3d80e3770bbb89 src/admin/session.rs
+e135431cb078ddb483165581123c64af8f00ea67acb3a395ec3e53c85d0d0d45 src/admin/session.rs
0c86d94b714cfff26e184541ed3bfcb317c88e45afe084d5f3b28558946dd9b3 src/admin/status.rs
2d5b4c28fd0bd48b06890fa8ec44a2296de948c1f88eb2909f4b495710d4e13e src/admin/status_live.rs
-060e0b378cc48ce17c7e007675467d369ebaf113b64074e595cc471bbfe41800 src/admin/status_system.rs
+8315c856cd50f1072593ecb30c274d42d82f078b5fb93e7c68a8857cd81b0841 src/admin/status_system.rs
cadd7dca29b9aad8c77c7bc23dd249ea37a15adfa4d636a8ef00273a91ce35dc src/admin/tail.rs
-fd38c6843e09508e90937362719da67a3678c657642ad5147cbce53ef891b011 src/admin/tests.rs
+666ef444c81e59a2fd47ace3be26e51a8630194d8ffd4db131eb228947fee8ca src/admin/tests.rs
c18c369124368f58524652565102817ed69fd25b222b0c5e737ef7632b45dcfb src/admin/web/acl-picker.js
48fcd818c522fe80f2c7b2e218f87de6a7772ffd0a24e93502780b03ec78e335 src/admin/web/acme.js
86abf50f39862d821cd2e43ca425671aa85289272915132c5a9a5dd1fc4182e2 src/admin/web/api-tokens.js
@@ -179,7 +179,7 @@ d997f62e8bd7ac9d4f16bb302800c98ad943afab663bb0b212ea26c35b58de11 src/admin/web/
43f4dddd1c3ea7fa42eeb9d7b655a8db48b5ddcc6c68213e08dfc2fcfbe8b17d src/admin/web/app/refresh.js
f1a764691f3e2cdb7c6c43e37dae78249561c017a1b74e973a378cb780b72835 src/admin/web/app/runtime.js
31201586925e6f4792071d7d03fb05dcc4a69a03c02a4e85eb0746f45af68074 src/admin/web/app/session-resume.js
-86ac42bd4a6a84bb137d5a3c3dc3d1f4e404a543447845e6ea6e6e8210e268ce src/admin/web/app/settings.js
+4596247d22cefe250345240942807fbcfebf4e9393457c37d4a97078f255e86c src/admin/web/app/settings.js
8386710827e5ccc9432fb46413368f94afc1016425404a6092b460903636837e src/admin/web/app/stream-dashboard.js
7f89bfae66e2a08a05a112733864e908f036bb1ee3d8b5b9ff23783b870acd96 src/admin/web/app/web-overview.js
849b2ca9d183bdf6cb1e04651cda52da55b8a631e11ab1d827a052c8436bbd76 src/admin/web/cache-panel.js
@@ -207,7 +207,7 @@ e6c4d91d1542d0a5b47bb8736f9539d43a6713df5a473b635519d5b7eac2eb9c src/admin/web/
0a5fff35555153f59d4346933030a67b6e1a8768cee7a47cfa2fcf1a2c564f63 src/admin/web/favicon.svg
7cbdef9192a9dee1f8eac42b85f52b3190f7f6efae50004aa7ad116a910e4036 src/admin/web/file-logs.js
b14e7b3578322f309627f6fe965cc16abcf85da3437c9070be6caecae1908743 src/admin/web/host404.js
-5ca0461ad1a701f5250b60961776c7691628ee532db5183f895fb2322b176c72 src/admin/web/index.html
+efe0560058dc4addd71f69a9642088f06c245099920b7511caa538adf4684443 src/admin/web/index.html
7915a06cebb3dfa2c51833c326586920691ba4431b1f984429b039333f9c2a93 src/admin/web/integrations.js
7a12f020fc587205694978ab41b660e9a80487d413fbf6e34fc525eabc58308f src/admin/web/login-keys.json
cbd41678eadd994dc5252628ee8ef9551fa9f7d8694ca5abd206240d9a96ad30 src/admin/web/login.html
@@ -238,7 +238,7 @@ b2f948bcc3dbd24952c7b1b02d41d06757f49f0c38a78caf51f8f8a687d8480d src/auth/files
745226cabb007819370fc6aa680995a03a8a13fa057dacfab0fcc21d0c43bbe4 src/auth/tests.rs
32a25e53ac9542424debeaf1b637155bd4e60abd8692df082729d81232eb90b3 src/backup.rs
76aa2afe9e7302be39b3512f30d0448d9134300f8ae930d64ada40cf3ad4a8a3 src/backup/archive.rs
-bb9de9d12dd57289b1941fd05b25f7de1249c3f114d663071b702a05b135879b src/backup/ownership.rs
+15213c87d4393739328ebf0eacfcb45f864ac12d7bd7509f750a241032f6c7e9 src/backup/ownership.rs
37f44cf3ecd71c7e817c76462c4c7de7ca6ecd68c0544f6429a861cdcde1fbdd src/backup/snapshot.rs
ece7a5eda4b57bae8f5d819a309cb411b95b1845f5746ac162dee51456365857 src/backup/tests.rs
f5afae218f3a6f91bc2f1f5a90094630ce5b7ca574de61807b5a317b13937ec2 src/backup/validation.rs
@@ -246,66 +246,67 @@ eec564a7ef886d18ab75289025a47d62bb702f07d63f92d2f83b7afeecebbb15 src/balance.rs
8f7975b488fad31f8d83ffedf8a5b6774b86b59290ce0711e779bf2496d5503f src/balance/health.rs
344631248c71164187497a10d177d8eaa3e2f4a08111520d2536ec89ae55e1e0 src/balance/lease_runtime.rs
ebe2b95f8fc5904850a88207f0690449ced49b28dc14ce5608b706659e338fca src/balance/model.rs
-aebcdcc1aaf8e38c4f286e6744c09525eef99625d1050479780c0f3c5b429c21 src/balance/pool_core.rs
+a3d052a928f73ea430480637b867ae874d447e24b1ac913a96a068a4dd74ff63 src/balance/pool_core.rs
477132dd381e23f1be197c32ff58a0925f41d3e6aa63fe77c10973cefb2b76f6 src/balance/pool_selection.rs
-a801a99646441cb748ab05f01101cc9c7a680788eb803c5b786ec6c5a7533e24 src/balance/pool_view.rs
-05227b05c37af2aebbde1ae37d81c2789088590ca45dcce3ae926c4fcf027bc9 src/balance/tests.rs
+d789bf40cf9433e2fd16409d112210fe93154588b1ac9bddc9c7f78e1db14426 src/balance/pool_view.rs
+3e75a3cba5f1cd1af996ab71b6ad50f6aa05ac9cd97ee3cf88fce7c6b7271fbe src/balance/tests.rs
16a22aa72f311d1fea6d8da03c3ea1590bc1f248b21876354eecc0da0fd93308 src/basic_auth/mod.rs
9a8858b7ff461a4d961ba701ca3ed6eaec15c3f7f05eef8e0e30edc63617605a src/basic_auth/tests.rs
-fb4bcb9d8852d2aeff41569291fe96d31c719d60789e860629a18cd15b8f24bf src/cache/cache_regression_tests.rs
+76b7db53f38c95e128fee503381efd3fdcc13340c124ef277faf0fe5c1c25c39 src/cache/cache_regression_tests.rs
7def03ace07dc38a4806277d75b6ce673d33ddaaf1c4855fa0a3372be1cf9489 src/cache/cold.rs
b75ff512a1c6344483e00d2c67578ceea6b5472c279da0246f3622daa68d7e16 src/cache/cold/cleanup.rs
-cd5cace53675f995f526e7296822ee5c7fb4b05d01c0ebb641d3efceb04175f4 src/cache/cold/cold_tier_tests.rs
-79547f697246651c89aac685b26f0701dd3a1db6b028695fa5ecc3d2ae14f643 src/cache/cold/demotion.rs
+af83946c4df0bb8101bcd3ece96a3193eac625a40a9f087dd2772c82fafdf019 src/cache/cold/cold_tier_tests.rs
+3c3897980c31a69d96f9295689d1ae19f2190da758c69ee7a0541f4171288bb8 src/cache/cold/demotion.rs
e80f84449412c4ae7bc753672a554160519bf1f186b5707252c3286cbe13f02e src/cache/cold/startup.rs
83095bc93132f306c537b31ba929669fedac99af3c4f133d0533b5ed7ac4e6ed src/cache/cold/worker.rs
-c1ce42ca57844c9f80234c1995f1b151dcc9373a0d55387ee887a8098d434f9c src/cache/collapse.rs
-81d61fad3b5d3d6cc131cb3cbed8438528e7473b23026440ff1b993ee69b5876 src/cache/dashboard.rs
-5820a33f7be9473b2a67613462e95db029c2e44385e460323936d314963d6b10 src/cache/dashboard_tests.rs
-7c2549ce80a50f6e998b8f74a5fb86300f7ebfbf8a24b4c35f855bf6a40a7880 src/cache/fill.rs
+a36a4a255a0fd2c38449bbc462b9c0e21488eae108c70326ab2a0e4c7cee0f97 src/cache/collapse.rs
+346fdb40d85627b583a01fa17c65e45c822dc7216198cdeadbb3d07904286fa3 src/cache/dashboard.rs
+4b8bea7aadae500df9a6223fb73a832820c56b47362c298499c3cc995f75f68f src/cache/dashboard_tests.rs
+4c4c3a70b0e40f9bc806c97939b7d08820e37e5359c87d8f39710b626a869bac src/cache/fill.rs
675d18afb53f25c56cba49bbb431fa39ecd9d7bdd192c7b39b0698225de7a2a2 src/cache/invalidation.rs
c1357a13658e1ed5158084d3a41ba9ea906512774a5863ce9c56cb508d3fa6c8 src/cache/invalidation/ban.rs
-d7a02eb7bad37e6a5524600aabb5e60ccf50e26c7a487e2806891c9d8acd48f3 src/cache/invalidation/http_invalidation_tests.rs
-ba90f7ae78b15c9cd13f9b75bccfb290d99e9cbba2023de73c7198ae24ca5637 src/cache/invalidation/invalidate.rs
-bfe59157d1656cdaf8e7cd82e659b25c7fcfd21c9b7ad17f7390466d7393957d src/cache/lifecycle.rs
+bbd9f372648d89b5e14d5b58029582d37f66a89752caf2c14eb1cbf8f24bb7a0 src/cache/invalidation/http_invalidation_tests.rs
+6223eaea3f061b111330cc26b28d85b9b239bef30328025f2ef337291e22a445 src/cache/invalidation/invalidate.rs
+9bae8be41d1e6b30cda51feff99fd77738940fa975bdd4ece7da75d936f07b47 src/cache/lifecycle.rs
bd831807ca4720b3a41a6ea1d9a6c0ed2d935225e2dacbd9313be064f2e4a20e src/cache/lookup.rs
-d5d01ffcc68e5ec6a913f20df108964a5b325f1aa972c078ba5e6defde81591d src/cache/lookup/hot.rs
-a0a23e7ec1baa403524811f8096bbc026b1027b7b1b79357ad920b0a4be770b7 src/cache/lookup/hot_hit_034_tests.rs
+9cfb83f414bdf4ccbedc3daf2eeeea4cb2ef83ab7c6aaef6063a331c9fbf5608 src/cache/lookup/hot.rs
+4148106b9baf70e41eeba24233b1edbe8dd6f927c11f2c7647e89fbbfb60555e src/cache/lookup/hot_hit_034_tests.rs
e9c6ab0c2be9f96573f826e6a1b9e4c2b8b526f779e72e95a6463ae07e45ab55 src/cache/lookup/insert.rs
-0338e0066e134b9e8032f117d9557b9bc5edc574f11710c2d36a6ca1c7467a99 src/cache/lookup/tiered.rs
+5303b3031d3ad97d7c4e75e5667d16775672ac1aeaca91c00f79f76ecb286cbe src/cache/lookup/tiered.rs
639d5be6258699ec7e9f260ec33bd2c366203b6655bf0e98f30517c2e12ceeeb src/cache/mod.rs
0c8b0d550e94d4474dcdf991aa0340228dc5f2f904f39350e6e666a16f16fe87 src/cache/model.rs
-952ce10a89c714571a5b8a79d5fb3ca60f5216901f95b3f82e7e257b4682fa9d src/cache/model/cache.rs
+c409174a9aaf20c69dc7b329108d1c26b5672a7341236cf639480df48800d262 src/cache/model/cache.rs
0ec4f6d0adea1ed80a3ca17c68c9c85502491da2904d9d690b4169ab9b025b21 src/cache/model/cold_metadata.rs
-4a44e2161c2e8b2d6decca6caf1f9315a723c888e0894236c88c656b01b8442d src/cache/model/entry.rs
-eee9e6614cc5a185e07686f9ad24525728cc49dfe8b9ce6a6bad0c14f3f0bcd3 src/cache/model/http_invalidation.rs
-a7b4b861127fe2b1527f12e5ce01ebacf60fe266f913467a2cc66d7f80e98c60 src/cache/model/maintenance.rs
-298fa122c7583bf8447d08255c4d0ab335e23c7e48cac3f621f235c201046fb7 src/cache/model/settings.rs
+000d82a19cda1501f12a8ef539c1e807529e104a77181fe541738fe6b22908c4 src/cache/model/entry.rs
+ff1c3a1a3bc0d26218dcc943ef951c2a212c180bbf6e4bf1c542ffbf12a9f150 src/cache/model/http_invalidation.rs
+dc1153685671be70c28bef814d72d8ef09afe070598f528ea62260c54d43b26f src/cache/model/maintenance.rs
+e9a17446038508275e72a85bf2a4fdc03aae1f8da98433f57de902a8aa22171b src/cache/model/settings.rs
c2efe75f740ba31e83c49bf76e7fc179e897f41c140eea700e2675ae648e4a1c src/cache/model/views.rs
e26dce02df9c043329ca164fed215d271781bce8fb03240f528331bf3df6b9d7 src/cache/policy.rs
-d01b8443c6d02a9b5d7f1477719865ea105126b8620e8fe13d7b4711e47fffb1 src/cache/policy/request.rs
-7cf0318d2b6dfc5f00806d608d78eeae9535b4fbb22b28826aad11b72579f9f0 src/cache/policy/response.rs
+b6dd187fe9a6f540653c9b7a0bac4e789f1c606b58bf99691e027bce776322ea src/cache/policy/request.rs
+130ebd918dace9552eee4f9633b8ad3fe5a1b7945bb00ae6f6683017cf10f527 src/cache/policy/response.rs
e59efd322f518ebd7b5b154115188f382c2cf7882ca0a401736ba5d685981ea5 src/cache/policy/scope_tests.rs
-982d4b32f5ef2f80e6e18dd7334152a903631d73edd2db532915e272b6bd2f59 src/cache/range.rs
-48c260e8dd75c89fb4518f6a20ece21017f69b0f5c9f9d80222ae34fab62b3b3 src/cache/stats.rs
-42a6bd984ee8ab69ba03030a113818252b26d5b922262b7759367d67899353e0 src/cache/tests.rs
-276a557d0ad85c4d5a7a3dae1e49e748591c79879f4c0d5784ec277ce8d08023 src/cache/tickets.rs
-9547a2fc3cf5220aa3edf3283e09b091f8b0fb6ccbe36e53f84c625c7482e08e src/cache/v022_cache_tests.rs
-c2d8548d12aeb2aaf02d47f6162904170526c9592aad9839a6bd5490feb269bc src/compression/mod.rs
+2b556ac9179b8a92de368f5e907e4114c2fc21a89155fe2a05665c45c08b3883 src/cache/range.rs
+e1d3f0512d6290b0ac4998f47398a0a7c404db249c5bbdbc4ad4767071013a72 src/cache/stats.rs
+8a300f5dad44815401eb23f4f5a157893761852ba4f3005041e0eb3f16892ce3 src/cache/tests.rs
+d0f7a9726c0a06553c91ca4d29eca207e9a9c3201fab371bec9dc5f6457ba12e src/cache/tickets.rs
+b7c063ed4c8ca96714e1dc5d279f38fc521da2132faad7bd4f40311352a71e7c src/cache/v022_cache_tests.rs
+6e503de08f3ea67608e534f5ceff58173eb2351d2fa7777e8fb646ed1c5bb7ce src/cache/varnish_compatible_tests.rs
+5a8022f6f4721f9fabdc715e01127d9299d47ee9981a79d26df1981448487d20 src/compression/mod.rs
2bb1ea392dc18553a03a6ae1c53f52712ae86571ea31b1bcd93c8fdec2cb60ec src/compression/tests.rs
e695079333ebdc2a6e7b3337cfabef171b3a0a01da0597b77feff70d417f833e src/config.rs
9f6272bd6d1f403cf6324b12472fd5c7d911a387139b57105ba1819e48ea0a54 src/config/backend.rs
-7261770b504b5d2bb4637a2a755c8ddd8301636aaf703ce9c8a01b0623bf339b src/config/compile.rs
-4febd62f15f33079b843f59fed94ffb1e9cc8693f58e54f4ab15ee03fd653b9f src/config/internal_routing.rs
+f9a400d66f37056a0a2d8c77fb44c2b3db9fceba3511e4a5b1e4b98890d27b13 src/config/compile.rs
+fbea01fea1213d98aea812c1b78d5db289e09200b98ae514d742235cd3fa70e1 src/config/internal_routing.rs
0d9f62fe4600b230e200f41652effc22ac7c1b649fbe63505ed6ea34c644feea src/config/model.rs
-5a2b888c2b2b3e506a8f1ee846ebdef60c1b3a3befe312d05431d4591a78c709 src/config/route_policy_tests.rs
+75839458ddbc7480ec4492a95eeb67b617ba7d62f7b67e7a767a3453b74dbcbc src/config/route_policy_tests.rs
40e9483d7b2450f55d29b46c408727f4e331b85ecda44fbd7b96bd9a09f02655 src/config/routing.rs
-422c43ef9fbbf6b9b8a44c162a95cda890ead6dfa1ccd24da4782844cbcb8834 src/config/snapshot.rs
-e09a3a8ca70ce7e42007553d48798bcb8b4fbdf791e338b36f238d7ab99fd05e src/config/tests.rs
-596a6697e8eea1d78fc86baaf8e9eb906ac38db6c1fe9a7ac62ecac85875940d src/config/transport_tests.rs
+dd9a6ad8f58e0cdd1ae74f3f972fee0ac14383cd8b8f518403b9a36c169f35bd src/config/snapshot.rs
+b7b0f851b4ca459fe8844a2e4f9cdcfc1135dec4c06f99beeea008c5b35c2ba5 src/config/tests.rs
+f35de0ee1516ece6bbfd2b2a7db7d1e0f5048b0ec47cf2a3765dffb799abfd93 src/config/transport_tests.rs
eb04a8922da26e45c9b6005c0cdf1b1ddf2da3c3b680650b22a1d1f16d17a4b2 src/db.rs
-e37168285f1c7e17a17a028a151784743e2ed6b9b5daa5560eacd6c0403eefb6 src/db/api_tokens.rs
-111baffc0fc7d2001d6b7d2542f95593ba5723bf37af7b209a273bc56545436c src/db/certificate_api.rs
+c290d0cb02dfa5d2c60ecabac1cfb20c8884e3d14cca1944906c6d8e677f1784 src/db/api_tokens.rs
+892ec0e5985700cca399c861197f6c9d2f1c823d8d95b88abac9d27ae15a069a src/db/certificate_api.rs
5491dd7bb9b3fceac97c4dea63aba6d5c7abcb0fbd06e36ae986e00c79bc07d0 src/db/dashboard_presets.rs
2ff744223934685439374572b83fd639bb3eabdbac168bea4a6501a6e9ce0ee0 src/db/history.rs
c05a02618d476e4670b4f9930555f199cac776cdf09edb8fcc1a675695b8f99f src/db/tests.rs
@@ -313,9 +314,9 @@ dada314e1709e960eb2e225b4d10c3cd12606c62c4bc2c0220aec1ba133e4ade src/demo.rs
5808205f03401e3f2c7f5c826d5de76e83e4b6f94c64ad3e50f505f985f6d26e src/diagnostics.rs
045593a42a6e4f632e5052c655788f0843faa313fc929265b89509f6dfff91ed src/docker.rs
93a8a3f6ba12761ddcbd19f22f32fb2c0e6948b660fb774ddd7ebdba9b6562a5 src/docker/client.rs
-da83e954040b281e99a9cacdf750d1745333b6c8ea1a5c3b6793ff01168e49e4 src/docker/model.rs
-a5239889203ac3fd6c82824ec3a8dfb1f250648ab05e3dea02a09183f82c1db2 src/docker/reconcile.rs
-3c0d97c9f6b8a5ccdf779ac2a965c39b9bd899dbb28a84e128d81fa75ccf696c src/docker/tests.rs
+f69087a82cf353e9a92fc97ee96510dbe0382efa1c5e53821d16c455a3eb95a4 src/docker/model.rs
+f095e5e3c564df409874019c647f7cec2156bf5a845b5b84864879fd07cf80ce src/docker/reconcile.rs
+2e8d4841665cc1d29e6262a1789bb64ced1cecd0036681cc1ef7b5d5bfe22065 src/docker/tests.rs
e36db1ed3188ffe54df7fc4ef76c4b453f23683bb7b8cdf601046e2bd50e0403 src/forwarding.rs
08d2e08a798abb944a53570f0bdaa08f1266b1107677ceda070091af4c2fc121 src/forwarding/peer_formatting.rs
b821e2efd2939cb13d01e402532f33feba6682acb6a7a3223be086c1cd171820 src/forwarding/tests.rs
@@ -329,34 +330,34 @@ c1b49bef28d87712e4c46138e70b52c4bcfb1a00196579031fac043d0b4aaa7b src/geoip/upda
61a2b01db9010f9debfb38b43a26bf588438a5e470dff938e4e54f9d7ba46732 src/headers/mod.rs
e4f07bfb7eb75b6897ef812870caff158679a3046d64582428abe8c6df490dbe src/headers/tests.rs
d7c764af29c132e3d8d1fae1bdbe6bf20a27046dc294f83761fea335726f2306 src/http3.rs
-4b56bddbfaa1db9151807c7bc016e573e78afce2ecf593df628e2e311df61658 src/http3/body.rs
-dd4e4200743b43895c0ee2071dc9ce36659b10251ce23d1082be169594a20d76 src/http3/diagnostics.rs
+0cc484bf0cc59a55a13e0e70435833a9a7a22ad7dfb5b9f86e059cf70a80cc2d src/http3/body.rs
+741972222414c280104acbcd8f8071bed9cbfcfa2f503c487c11c56f553f53cd src/http3/diagnostics.rs
49ce4452ef7973cafa2e4071e2e14be0e16000e931a6501e4dc613652e49e230 src/http3/identity.rs
0b41072f6bcf28725c80f471584cd55d4900424ce5d55ac7f6909813788c63fd src/http3/settings.rs
-01ed8610a8d169bafecf5ef91d325042d9b59a228caa8a89f76005cee20e6811 src/http3/tests.rs
+5c550075c7b0fe687ad02095c1cad57b46b579fe21dc5371525b6c77db459886 src/http3/tests.rs
68fb5ab6a889995a66ad12cb6acf88c5d04f0aca572e2ae15f1a9cd171a5f24b src/lib.rs
e8399753a6ff49b7de19edb0a268bf871c9979a518354160cf07b4669051fcbb src/logging.rs
-4310aa77bec91dc473808787cebef664d2c9bda8d78742ad0fd410670f0f4f56 src/logging/error_runtime.rs
-9f9705e07cba9f3c2888babb2eef63b706549042e0f4ce29fb6a1646ae58f9b8 src/logging/format.rs
+e4be3ad758c3d93ce52dd3b1ab1a87810e5226339400ed997607a5b746354751 src/logging/error_runtime.rs
+b2ed730006fdc080cf7eafc6d20bb89661c639631c89642d110e0c1319e431b5 src/logging/format.rs
e51524d45ddf54574bd33d71dd4ab18abbb642390fb6b6dda2a2c6e5439fe9a2 src/logging/model.rs
-3afbf5083695f21ae4a8bff10b81ec3dec55124007c31b8a0d36c3014e4873a0 src/logging/runtime.rs
-48187ebfebeaf6863207ce338df2d6d0f418fc3aa0689481c23c2a8ad9970b52 src/logging/tests.rs
+bf898b318feb9bd3dd2c335b6b1bad172da63fd5cefbff3e267421ce37c076fb src/logging/runtime.rs
+a9e453c94fc37e37d9f1f461494fffd5f88e13e15f6cd4158464dee4fafb14bd src/logging/tests.rs
0e9993aa6679381d91f3a22068b30e1611439d7fe50900f49a4a73ffdfbdb3b1 src/main.rs
-04ad738f90c67754f9f133863a0e2ae94665357f527c2fc3db05863087ae4d83 src/main/admin_runtime.rs
-2c32c9b2014f9fcb111b64dd85f2106a8731b6d57fc3721522b2ec5f4349f4fd src/main/bootstrap.rs
+87e69b46c548b861e9d90d9d2e42dfc2630891f4583800b1942f9065d25e29cd src/main/admin_runtime.rs
+224da3127b5f846a8932fb7f4b6e23d0dd590dc0170506267381d66042c64666 src/main/bootstrap.rs
5a98d0e249338e73aa57ae2e352dc16db2f79c2d042c1544ce1c2022da76a31c src/main/proxy_runtime.rs
b240033715323e7cb7b9bcaf92edd481f7089b4da6bab25005ca6733da8756dc src/main/shutdown/mod.rs
0a6578a0f4023b9f8d73043bf942dc5e096ef9afb8c0d2f131c14f65d08ac01d src/main/shutdown/tests.rs
ca01c97cc52a50797306193a546e4379fe3ce9401b0c936c756b881180315ab0 src/main/tasks.rs
a719c51aebcba0f16f8810c37618201954e79d6806da085ee6c5e4697a05b521 src/metrics.rs
9c7ed78345abc33d260f8d5cd52339bf8de748c08b53eaa2bdea8a32a0ea2a20 src/metrics/global.rs
-def9a23ea4edd87fe142ac597387f1c0235088c95c693809f5793279d4cbe02f src/metrics/rate_sampling.rs
+31154052757c2bb975b8ce8cad67f3fad7b5132b615a73d5b0d7bf1b5311722b src/metrics/rate_sampling.rs
f27f1f8bed769883d1a7ae6a48f89f7712394dfab65d05702b0f944f0a45bd8e src/metrics/vhost/mod.rs
-40cc25ed1993127dece24857221b6da2debac37faf403abcb451ec442a240273 src/metrics/vhost/tests.rs
-e7ddf1f453a3e207ece18a4358cb44cc02ee68333ecc0b6c68028ad17661cc8b src/not_found/mod.rs
-c915d30bbd7032d867e7916b4cd45f3bb7e7604d3f4558f4383c59394b4300c6 src/not_found/tests.rs
+ee401f943bd8b2706c33419ed69102269c08dcb4ceba6f4be2ac0861115874a7 src/metrics/vhost/tests.rs
+9c96c3e4edb20dd0c36b5c373f1925dd60368e75853002206523072d418d5417 src/not_found/mod.rs
+fa2fc6c6987a8356a9da92cade10db62426d8863e9cef3c0d4324c45780c5b33 src/not_found/tests.rs
d32d757ace8753eccb842c24b7af77061141478d10fe0acdfb05263d19e9a64c src/pages/mod.rs
-8416712d3e8ce81a1794152ef98220313066527d613142cc0958c4915add8c39 src/pages/tests.rs
+9d3f4db663016033c4ba0d86e30367bd5a1ab79c8bc121265d410698104fa19c src/pages/tests.rs
5650a3f70162abd97021e0a51a92cac2c4dd39004426ef99dff36cbb0741aeac src/prometheus.rs
192a780d5874afc158d62a7dbe1687d734635afe9342fff526b8a2f6db4e5633 src/prometheus/core.rs
2321ee667569803dfe6c92c0e98adba0ac8fcdc6a3eacd5857233f1acae93daf src/prometheus/docker_misc.rs
@@ -366,27 +367,27 @@ f9aab3297fcf647295849f77cbf99197f4dd27efd6817e54c03451e04972430c src/prometheus
028e1dd9f2ec2afaf699a6b21c2d4b0d96e76f11f5e4ed009c233dadf0f3be51 src/prometheus/traffic.rs
e03f0d6b3f35dae6b98c394837aa0d17e4d73a8306767b4c607868bc00c30286 src/prometheus/vhosts_backends.rs
f1b0254f53b1a4336bd8170ad441ba072b49a114e497b985cb20699b4e375044 src/prometheus/web_php.rs
-0e8db3facf4f4df7b05f058e2dccc8521d88bea9da67ac0889b77d349d524d9c src/proxy/body/mod.rs
+569eda61453affd053fbe24fa59652289cb12d22b77e64caa38325bbea48f7df src/proxy/body/mod.rs
57a71c9c6e4e0deba5d05963b9870af8f4c4d8dbd321ed4e52cee88746c997f0 src/proxy/body/tests.rs
dff5d29ad6d126fde26f2b5e770c3b35275a82b6d59e41dd85edf28ac5eb2740 src/proxy/cache_helpers.rs
7e3837d2f6ba7d07ca2cbabda57b315f5a7f4d75a13e5eddf6861a150d0d2ed6 src/proxy/cache_http_invalidation.rs
d134b0eb617f82f9971b3f3461379ea37c57bd0079bf54748d0c434b2ef1b475 src/proxy/cache_http_invalidation_tests.rs
-a679baaa062beadff9ddb61a3bd6cde1ce27cc62147d2e27b468c0a8cd32ceee src/proxy/cache_plan/mod.rs
+a03b1735daa8fa8e40cf5bd9c6e200d211baf19c30f62522d4237ed56642bce7 src/proxy/cache_plan/mod.rs
3404b03096862de1050088f62cdd811ea1ab61d191f902501173107f81f23b9b src/proxy/cache_plan/tests.rs
a0b9e2e9ab0bc89c7b64bd19365198234b1c5c13f455ea47be122a5660639b17 src/proxy/error_fallback.rs
-c825f436ce0730ce542f51a1363a0fdfb0b1a4113a2257384d052de1afd56359 src/proxy/forward/cache_fast_path_tests.rs
+fee36419c7e308cedff3b73ed1e8c5fab1fa054aaa6e0ccc016dd0b043c32c42 src/proxy/forward/cache_fast_path_tests.rs
a20cd11a504e423e5b1af5cebb5b4186530d4eaacaa02c3212a1174cdbfb6498 src/proxy/forward/cache_lookup.rs
-0f2eacadf1447db8aa1c1a78005aa262e0f747096bfe7e0a0e41a2cd31a0d17f src/proxy/forward/h3_navigation_tests.rs
+287012c81144d8f15af4a148ce3ca911d431bc59adff44e697567561aa372bb3 src/proxy/forward/h3_navigation_tests.rs
ce97cfcb07d90415937f0520ee7175502b22e60694c1ea8e3d2b47678d190e5f src/proxy/forward/response.rs
-02e1fbe16e59c746d57dfbabf655a729a2cde8131886689532a414c47467a53f src/proxy/forward/route_cache.rs
+f3c3b8c979c06bd84a72969f2908be1052097e32f3a21f0494dbd3ce72f17796 src/proxy/forward/route_cache.rs
3f91a40a01378d1fbac56ec376df6626e0c4fb6c3b8c8d42583b9c398d368ad9 src/proxy/forward/success_finish.rs
-e631c63fc10a23e4533bbd158659710b184656b323d0e6169a8627294c6972ba src/proxy/forward/success_prepare.rs
+aa30766a5d584c2143488f16caef19c1d369a2c7c00b5ff960eaf2ccf4045c31 src/proxy/forward/success_prepare.rs
e9ac9be64f6f83c4ca2cd5d299649f24dd16197712083c6dc10e55c662c65b80 src/proxy/forward/upstream.rs
-53ae013330edab4d97a9cdab2c513f8548f6816aac60f7035bf3433a6a2db818 src/proxy/forward/web_source.rs
+de548bd191c57b76b595f0a932195d303b43355982080a185c44f1973d00702c src/proxy/forward/web_source.rs
3340583d395fcc859cf3421f4e33cf8347915ee4c468f7d0e4abebce8156fdca src/proxy/forward_entry.rs
9b25f5e3ea4443a63ee6f45d12e1957dd316fe8e85325fc00ea416faaab1025a src/proxy/h2_graceful.rs
5b07b98d855453d5a4272f5fc98a75973c3e6032416e0fe4f7f151c1bf239fd8 src/proxy/headers/authority_tests.rs
-3e642599bb0aaa3ab36d83a69d9e04541cddde90f38661934ee0255011ceefb5 src/proxy/headers/mod.rs
+66efc52d64d34667ba7419f8a2da89d2efb1af1f426684f4fff8caccfdf19996 src/proxy/headers/mod.rs
0f9314d1380febe436def36b5f381731e97cbac90625637575f38f3d72eaaace src/proxy/headers/tests.rs
c04451ac8abebf4662ccc3ee4610d5342ad5382da2098f7af5db274d079770b6 src/proxy/identity.rs
a08ee061e146cb7a08311106f73a04468c89f77b6ad05a2c623621a2ae9faf2a src/proxy/mod.rs
@@ -404,7 +405,7 @@ faedf6cc2bd4c42f342a0aa188b634d6b8d280ca0e121032977eadaecb88e9d7 src/proxy/webs
7e9c4d4c207badabf90630223964bb2ad641f06d4149843cab751f192b8b4adf src/proxy/websocket/tests.rs
a44421714aab37f7ceda19e3ec2512c645d2a3ce5dcb3da5bc7a0d87a442d6a8 src/proxy/websocket/tunnel.rs
999cbf85cb6e917db529e30ba4a5eed1cc9e95a054da7b3039c730bb80061449 src/proxy/websocket/validation.rs
-00aff5b5b0719930230eff4d7e3adbe998cf0258bf7361d0913679c863afd3fa src/rate_limit/mod.rs
+80d0f744f7ad9f0d1edeb0d5c23b13cb40431f6b6f4d10d534ed34d4198e3dfd src/rate_limit/mod.rs
2fcfa9706eb0708519d5181debaf3c85a86e401a8898df72f9eaf0ab72c9df85 src/rate_limit/tests.rs
e53c40b85792d4804a432e3c97dc13af8e29304bb0d250ee9ab9018bde522eeb src/redirect/mod.rs
811c83ae9fd0f5a13d35b5443cd37843f82b9d600bee4bb136ba9b87732a5347 src/redirect/tests.rs
@@ -447,11 +448,11 @@ df98becda799b6bf4ff5e2fec7d0e0a486e6b7eca6f9f5ad49ffdafd49a4f498 src/tls.rs
2af2164ecdf2b7fd9eef7c6e358dec053dfac9aedaa501dbb75df742d18638b2 src/tls/acme_tests.rs
7425ee6c839f85d792e9251c6b9039e72fb49a5820a2266f751e6f4967a5871c src/tls/certificates.rs
2ff3c219f87bd82677045a4809d3d94921c5b230bbc2f3e7131b07548f73ea7e src/tls/external_paths.rs
-60c16793b3d6115596e79e2cfe5436ad774709d20ca1cd55883e0f44e40ec871 src/tls/external_paths_tests.rs
+f88a6c8c2e35c3aa58b7763c71a5a2cec82a34f24478a98b0960b81659a1ec4c src/tls/external_paths_tests.rs
7b4c0f58b3a1e1791bb3c682a001b78bfdbbdafdbc143db8063b3f22dc168616 src/tls/server_config.rs
9d6f048e791a3b7152904d1728258d298ad9d34aa3f83d13baf1b09a6fb7601d src/tls/tests.rs
d9d79edf5a8ef6e3b39a21d35dd5ec6e5a336047117918949e7ec6f5b20ed3f1 src/tls/types.rs
-d637a77a9271736993f2e49022f752750364d4c6ba3cfd5cf7c9c3c8f37154b3 src/traffic/mod.rs
+a535c8526b38de2990da7781e158b9ea70ef8c1f6fae0aac5ce6e9da21d3a309 src/traffic/mod.rs
dc8a83fae47da0d86e6ce0a329cb5274233264df56eebdb56b9bf37cb7be2bb4 src/traffic/tests.rs
65fcac840f8b5f1508213e3f374aa318b450b0f9f90ba827c5ea935b9c60bee7 src/transform/apply.rs
34a06c2dc635e80690961ef61fe84110f9578f55adf89f92a04668783ccb0a98 src/transform/compile.rs
@@ -467,14 +468,14 @@ d13fa462d6df516a4cfaee9f4e184044c5b6345e311aeb3d9058efafe54e4c5e src/transform/
4b52257e1a3643910b5e7043852d7218230c0021c31215d90d0f8e384f2ae233 src/transform/svg/mod.rs
0f53c64f442390ee20a59087a10f8f9ffb58053263e9aa848ddabfae1a6f3f51 src/transform/svg/tests.rs
d1f3f53fedae0d8ef69eeee457f7d30ed5a670a1ed4ced60683400ee46680260 src/transform/tests.rs
-64f711d2a0063036e3a2cba470b44eb165f3574bc28cf273296c2c3adb9ed4a5 src/update_check/mod.rs
+8d38f2f7d4ca4dd453cd0e2337614ec704fbd0a36d3e2374cda43f05dfcad663 src/update_check/mod.rs
c42d000d1d576721af3ffe930589388693001b8113554a7658f6dcbc665b5d1b src/update_check/tests.rs
b7ee3629a8fde0972bc1822b764f5fa2c813a760dd5dfb7f1ce643a7db8f9f75 src/upstream.rs
fe9d4deb34cea2408ac5a1030315989f29a6a7d078a46ac1b59d12aa07f67878 src/upstream/client.rs
eb513923f8951c8bf30bad3cbac77d34f5ebbc7af3ba69a08a25bae834f8a016 src/upstream/client_tests.rs
8c88d928b823e4b6ba6d852f74664c770d8b3fce32bc76c583dc1f672fe33f14 src/upstream/protocol_tests.rs
ae880b40197454ea3fbf4d2113984dc372098b2e54b97e87c83cc319de253377 src/upstream/tests.rs
-b88cb47a009be4924bcf069b05c3e788d1eaf2b15cbdcf3099036ece89cd0d66 src/user_agent/mod.rs
+e68599c376d190ae7bdeb154cb3e5a7151feabeb0d688360327dff06574d985d src/user_agent/mod.rs
6d7cb73de7d8c6f3780736480f5f81ef08813f4626fd5ed494aca0552cf214a1 src/user_agent/tests.rs
d61c427c1e9cf457f1232b822d73e846e9f329cfbe61215e7ca061d53762155d src/vhost.rs
54b0c1d2f04e5c654123c3422645eb5a0a9609141cc4a1c6addca2d028392772 src/vhost/error_fallback.rs
@@ -507,18 +508,7 @@ f826d8816bdb9edab966e10991e45335625ef7d7376169cf6fd1e0e5d01bf868 src/web_server
400e1c8aa2fe857d96036a64499fbc3de44c1e3a53811c5b25101fb843359792 src/web_server/security.rs
b791762b4ab7a43c3be19df84e523faf3dfb4df055f66d02178f93edb60d2204 src/web_server/serve.rs
df888adf893d0b6b99348d19fa07bd9c2b8fc0ce7f411d06be7411afb4311fe0 src/web_server/tests.rs
-cf729dc5d00132736521887e77ab0ab5280ede6840e1fb225736ccab09748f22 tests/acl_picker_corner_styles.cjs
-2467a6c2295d3fb2ad84cdb4a85176372953034fef2f4d95dc3bf58f019efe21 tests/acl_picker_dom.cjs
-8bfee0027ce317f3427ecdf9193549d4a52db58a7b2b99db7cdeebc458d7d4c0 tests/cache_outcomes.cjs
-667352945e67032a26e9f246a3f89b20b431b2cab8f48bb77b11533d89b3f2a7 tests/css_usage_audit.cjs
-2e957134ae1b041ab1f1cac6149892a2704bd61a37fbe4afc0810e2911b5cedd tests/docker_vhost_actions.cjs
-c1b806e756a84913d0a1cd2ace0b0f94fb5f5817e0480870a65279b4d7fc5bbb tests/docker_vhost_metrics.cjs
f00743af2cf4a5952caef7a1dcf68e7817b5599a252a9973e1c22045517c0b0e tests/fixtures/argon2id.json
-930cc63183479400d01195574ec0246a482618915bc3c24b4d48a11faa286018 tests/modal_frontend_0346.cjs
-071d590439bba50b526e1b2344b5ee414210af8f4f6a318d1611640386de576f tests/ux_0345.cjs
-b312f9f5d5f4b3d30f935ab3f3c893fd8b8f2d571acc8198a1a89ed9ecd1f0ac tests/ux_0345_followup.cjs
-67353441435c6378780e4b6c5dd8732d7160f7fbce8df9cf4791cbd6037f5840 tests/vhost_content_type_ui.cjs
-3421dc1baeb2a9882907b09e816213b375767089c79fce710248c61b9c3e1ae2 tests/vhost_ui_layout.cjs
eca68a07c2b1e45fdb8f512294f5a432db3ae5a6aec8fb200b47f155cd9a31d6 tools/README.md
358c1e94dd2b4a756430e5335747f0b437345b1713670a9972c5bcf78b837ccb tools/audit/admin_audit.py
7c30c280d0b0a8bf855eeffab583ca34dc161255f7ef6124148aa979c17c26d3 tools/dev/memory_load.py
diff --git a/docs/CACHE.md b/docs/CACHE.md
index ae9f5a9..cb4e9c7 100644
--- a/docs/CACHE.md
+++ b/docs/CACHE.md
@@ -8,7 +8,37 @@ RustProxy provides an optional shared HTTP response cache with a bounded in-memo
2. On the appropriate Vhost, enable cache for public, repeatable responses. Restrict or disable it for login, personalized pages, uploads, APIs and responses carrying secrets.
3. Ensure the origin supplies a valid public freshness policy, or configure a safe default TTL where supported. `Cache-Control: private` and `no-store` must prevent shared storage.
4. Optionally enable HIT-only diagnostics. Send repeated identical requests using `curl`, then inspect **Cache → Domains / Stored objects** for `MISS → HIT`.
-5. Check TTL, revalidation and invalidation after updating the origin's content or configuration.
+5. Review **Varnish-compatible cache policy**, enabled by default, then check TTL, revalidation and invalidation after updating the origin's content or configuration.
+
+## Varnish-compatible cache policy (0.34.7)
+
+**Settings → Cache → Varnish-compatible cache policy** (`cache.varnish_compatible`, **on by default**) changes *request-side* cache lookup, not authentication or the cache key. Disabling it restores the earlier strict policy without a service restart. **Changing this policy invalidates cached representations** to avoid mixing storage semantics across modes; allow time for HOT/COLD to refill. Effective settings also apply to eligible embedded Web Server resources and HOT/COLD entries. Existing JSON configs with no new field inherit `true`.
+
+| Condition | Enabled: Varnish-style | Disabled: legacy strict |
+|---|---|---|
+| Client `Cache-Control: no-cache`, `no-store`, `max-age=0`, `min-fresh`, `max-stale` | Ignore client cache directives for lookup and freshness; a **fresh** object stays HIT and keeps `Age` and hit count | Revalidate/bypass or constrain freshness as instructed by the client |
+| Client `Pragma: no-cache`, `only-if-cached` | Ignore both; do not force backend or a synthetic 504 purely because of these directives | Revalidate or give 504 for a missing only-if-cached representation |
+| Origin `Cache-Control: no-cache` | Do not store, like Varnish's built-in VCL | Store only with a validator and require revalidation per request |
+| Origin `Surrogate-Control: no-store` | Do not store | Existing RustProxy behavior |
+| Origin zero/nonpositive *remaining* TTL | Do not store | May retain a zero-TTL representation for revalidation; never a fresh HIT |
+| Expired but eligible object | Allow up to 10 seconds of background-refresh grace (or explicit larger `stale-while-revalidate`), unless `must-revalidate` / `proxy-revalidate` forbids stale delivery | Only explicitly configured stale/grace conditions |
+| Origin `private`, `no-store`, `Set-Cookie`, `Vary: *`; client Authorization | Existing RustProxy restrictions **always** apply | Same |
+| Static-file cookie-ignore allowlist, custom bypass/force rules, TTL caps, BAN/PURGE, request collapse, compression/transform, HOT/COLD, tenant isolation | Unchanged RustProxy mechanisms | Same |
+
+For `/ui/style.css` with `Cache-Control: public, max-age=600` and **no** origin ETag/Last-Modified, a hard reload with `Cache-Control: no-cache` should now remain `HIT` while its cached representation is fresh. The request headers are *not* stripped before forwarding when an origin fetch actually occurs; RustProxy only ignores them for its own lookup/freshness checks. Client `If-None-Match`/`If-Modified-Since`, range conditions, URL query, `Host` and `Vary` are preserved. Strict mode remains available for installations requiring clients to force validation.
+
+This is **a documented policy subset, not a Varnish binary/VCL clone**. RustProxy deliberately keeps an explicit zero-by-default fallback TTL (no implicit Varnish 120s TTL), configured cookie exceptions, multi-tenant security, stale prohibitions for `must-revalidate`, and no Varnish-style hit-for-miss/hit-for-pass markers. Not every Varnish configuration behaves like the default built-in VCL. Cookies continue to be omitted from the cache key *only* for the already-configured static-file exception; do not enable that exception for personalized static endpoints. A no-cache **origin response** must not be made cacheable merely to gain HITs.
+
+Use a three-request GET comparison with `curl` (replace URL with your static resource):
+
+```bash
+URL=https://example.com/ui/style.css
+curl -sS --compressed -D - -o /dev/null "$URL" | grep -iE '^(HTTP/|age:|x-cache:|x-cache-hits:|x-cache-reason:)'
+curl -sS --compressed -H 'Cache-Control: no-cache' -H 'Pragma: no-cache' -D - -o /dev/null "$URL" | grep -iE '^(HTTP/|age:|x-cache:|x-cache-hits:|x-cache-reason:)'
+curl -sS --compressed -D - -o /dev/null "$URL" | grep -iE '^(HTTP/|age:|x-cache:|x-cache-hits:|x-cache-reason:)'
+```
+
+Enable diagnostic headers if needed. With compatibility **on**, the middle response should be `HIT`, and Age should not reset on a fresh object. With compatibility **off**, it can be `MISS` and reset if no origin validator is available. Explicit PURGE/BAN and stale/expired TTL remain authoritative.
## Vhost editor options
@@ -31,7 +61,7 @@ In **Vhosts → Cache**, overrides for static extensions, bypass path prefixes a
| `BYPASS` | Cache was disabled or a policy intentionally skipped it (for example authorization, cookies or a path exclusion). |
| Revalidated | An existing representation was checked against the origin; a `304` can retain the body. |
-`Age` is total HTTP age, not only the time spent in RustProxy. The optional `X-Cache-Resident-Age` reports the cache residency interval. Debug headers such as `X-Cache`, `X-Cache-Hits` and reason labels are optional and should be enabled deliberately. Browser hard reloads commonly force revalidation, so test with `curl` when investigating.
+`Age` is total HTTP age, not only the time spent in RustProxy. The optional `X-Cache-Resident-Age` reports the cache residency interval. Debug headers such as `X-Cache`, `X-Cache-Hits` and reason labels are optional and should be enabled deliberately. With `varnish_compatible=true`, browser hard reloads do not force revalidation while an object remains fresh. In strict mode hard reloads can force origin revalidation; compare with `curl` when investigating.
Example, replacing the listener and Host values with yours:
diff --git a/docs/CONFIGURATION.md b/docs/CONFIGURATION.md
index 85f94b6..10d89d0 100644
--- a/docs/CONFIGURATION.md
+++ b/docs/CONFIGURATION.md
@@ -2,6 +2,8 @@
Most settings are managed in the authenticated panel. Save changes after validation; use **Configuration history** to compare or restore an earlier revision. Some listeners are process-owned and require restart to change. Configuration updates are not a replacement for encrypted full backups.
+> Cache compatibility: **Settings → Cache → Varnish-compatible cache policy** (`cache.varnish_compatible`) defaults to `true` in 0.34.7, also for configs without the field. Turning it off restores legacy client freshness handling. See [HTTP cache](CACHE.md#varnish-compatible-cache-policy-0347) for semantics and safety exceptions.
+
## Configuration storage: SQLite or JSON file
**Settings → Manual config** shows the active storage mode and path, sourced from the read-only `storage` member of the authenticated `GET /api/config` response (`revision`, `config`, `storage`). With no `--config`, the authoritative configuration is in `
When enabled, client Cache-Control and Pragma are ignored for cache lookup: Shift+F5/no-cache/max-age=0 does not replace a fresh HIT or reset its Age. Response private/no-store/no-cache and Surrogate-Control no-store stay uncacheable, responses with no remaining TTL stay out of cache, and eligible expired objects may use up to 10 seconds of background-refresh grace. Existing static-cookie exceptions, Authorization protection, Vary, explicit TTL limits, BAN/PURGE, HOT/COLD, transforms and unsafe-force rules remain independent. Off restores the previous strict client HTTP caching policy. Changing modes invalidates stored objects. This is not full Varnish VCL emulation.