diff --git a/AGENTS.md b/AGENTS.md index 68a34d2..f34bc36 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -2,7 +2,7 @@ Read README.md, ROADMAP.md and docs/TEST_REPORT.md before making changes. The project name is RustProxy; the Cargo package/binary remains `rust-proxy` for -compatibility. Current source version: 0.26.4. +compatibility. Current source version: 0.26.5. ## Delivery diff --git a/CHANGELOG.md b/CHANGELOG.md index f086cf7..f32d48a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,12 @@ > test-only changes and packaging implementation notes were moved to > [`docs/CHANGELOG_TECHNICAL_ARCHIVE.md`](docs/CHANGELOG_TECHNICAL_ARCHIVE.md). +## 0.26.5 + +- Keep compact toolbar selects and neighboring inputs on one interface-scaled control box so filters such as Stored Logs no longer render mismatched heights. +- Make **Streams -> Add TCP/UDP listener** navigate to **Settings -> Listeners** instead of opening the Stream editor. +- Keep SQLite schema 8 and the saved proxy configuration format unchanged; no migration is required from 0.26.4. + ## 0.26.4 - Add 404-host editors to the session draft dock so unfinished 404 forms can be minimized, switched away from and restored like Web Server, Vhost, Redirect and Stream drafts. diff --git a/Cargo.lock b/Cargo.lock index 8c33f9d..f9e1fae 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1688,7 +1688,7 @@ dependencies = [ [[package]] name = "rust-proxy" -version = "0.26.4" +version = "0.26.5" dependencies = [ "anyhow", "arc-swap", diff --git a/Cargo.toml b/Cargo.toml index 1ed21bd..f48676d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "rust-proxy" -version = "0.26.4" +version = "0.26.5" edition = "2021" rust-version = "1.88" description = "RustProxy - independent reverse proxy with local administration" diff --git a/README.md b/README.md index 26d93a0..c6871be 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,9 @@ -# RustProxy 0.26.4 +# RustProxy 0.26.5 Independent Rust reverse proxy and static Web Server with a dashboard, SQLite configuration, streaming HTTP/TLS/WebSocket forwarding, raw TCP/UDP stream hosts, IP-bound vhosts and backend pools. -**0.26.4 release source.** +**0.26.5 release source.** ## Layer-4 streams @@ -11,7 +11,15 @@ Raw TCP/UDP forwarding has its own **Streams** page in the primary navigation, a Named HTTP/HTTPS listener bind addresses use the same chip-style editor as vhost hostnames, including multi-address listeners. -## What changed in 0.26.4 +## What changed in 0.26.5 + +- Keep compact toolbar `select` controls on the same scaled box model as neighboring inputs, including Stored Logs, Backends, Docker, vhost-style lists and Settings filters. Form-control dimensions now consume the interface-scale field variables consistently instead of leaving selects visually detached from inputs. +- Make **Streams -> Add TCP/UDP listener** navigate to **Settings -> Listeners** instead of opening a new Stream configuration dialog. +- Keep SQLite schema 8 and the saved proxy configuration format unchanged; upgrading from 0.26.4 requires no data migration. + +0.26.5 retains the 0.26.4 administration consistency and backend-rotation fixes below. + +### Retained 0.26.4 release notes - Extend session-only editor drafts to **404 hosts**, preserving the complete unfinished form state when another editor is opened or the dialog is minimized. - Complete the Polish translation for **Settings -> Appearance -> Button style** and keep the button-size preference independent from global interface scale. @@ -21,8 +29,6 @@ Named HTTP/HTTPS listener bind addresses use the same chip-style editor as vhost - Run time-based upstream-client pool recycling from backend maintenance as well as request dispatch, so an idle backend rotates after its configured age instead of remaining on generation 0 until the next request. - Keep SQLite schema 8 and the saved proxy configuration format unchanged; upgrading from 0.26.3 requires no data migration. -0.26.4 retains the 0.26.3 appearance and administration workflow changes below. - ### Retained 0.26.3 release notes - Make interface scaling truly global: the 70-125% setting now scales the authenticated dashboard, navigation, dialogs, overlays, draft dock and other top-level administration UI consistently. Form fields receive an additional proportional size adjustment so inputs/selects/textarea do not remain visually oversized at low scale or undersized at high scale. @@ -51,7 +57,7 @@ Named HTTP/HTTPS listener bind addresses use the same chip-style editor as vhost - Replace backend sort text (`A-Z` / `Z-A`) with direction arrows (`↑` / `↓`). - Keep SQLite schema 8 and the saved proxy configuration format unchanged; upgrading from 0.26.1 requires no data migration. -The detailed 0.25.5 implementation audit remains available as historical baseline evidence. Current 0.26.4 verification status is maintained in [docs/TEST_REPORT.md](docs/TEST_REPORT.md). +The detailed 0.25.5 implementation audit remains available as historical baseline evidence. Current 0.26.5 verification status is maintained in [docs/TEST_REPORT.md](docs/TEST_REPORT.md). ## Documentation @@ -129,7 +135,7 @@ CARGO_BUILD_JOBS=1 CARGO_PROFILE_RELEASE_LTO=false \ CARGO_PROFILE_RELEASE_CODEGEN_UNITS=8 cargo build --release --locked ``` -The 0.26.4 source archive preserves the resolved `Cargo.lock` supplied with the source tree and +The 0.26.5 source archive preserves the resolved `Cargo.lock` supplied with the source tree and updates only this package's own version entry. This packaging environment has no Cargo, so the dependency graph was not re-resolved here. On the compiler-enabled deployment host, run the locked check/test/release gates below and retain the verified lockfile. `dev.sh` can generate a @@ -368,7 +374,7 @@ python3 scripts/release_smoke.py # Runs those checks first, then the Rust suite when Cargo is available: bash dev.sh test # Source-only package, with no Git checkout required: -python3 make_zip.py /tmp/RustProxy-0.26.4.zip +python3 make_zip.py /tmp/RustProxy-0.26.5.zip ``` ## New management and test-origin guide diff --git a/ROADMAP.md b/ROADMAP.md index d925486..6a4a0d7 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -1,5 +1,15 @@ # RustProxy roadmap +## 0.26.5 - Scaled controls and listener navigation + +Current direction: 0.26.4 -> 0.26.5 + +- [x] Keep compact toolbar selects and inputs on the same interface-scaled control height. +- [x] Reuse the interface-scale field variables for ordinary form controls so inputs/selects resize consistently with the UI scale setting. +- [x] Route the Streams **Add TCP/UDP listener** shortcut to Settings -> Listeners instead of opening a Stream editor. +- [x] Keep SQLite schema 8 and saved proxy configuration compatibility with 0.26.4. +- [ ] Run compiler-enabled `cargo fmt --all`, `cargo check --locked --all-targets` and `cargo test --locked --all-targets` on a Rust release host. + ## 0.26.4 - Administration consistency and backend rotation reliability Current direction: 0.26.3 -> 0.26.4 diff --git a/SHA256SUMS b/SHA256SUMS index 3d54010..6bf3828 100644 --- a/SHA256SUMS +++ b/SHA256SUMS @@ -1,19 +1,19 @@ 61bf40a0572889dc8b0dda9eae4e93e44b0de9364b3c798106c85700ffb37c23 .dockerignore 4140a2956264b44f259e6a37fc00ba02097bbe68b09296e04d3d243c1287129b .env.example 9e6356475bf587091bab72246ec9e325b498f7e48a6220e9a18baa50d0a385a6 .gitignore -3bb6c6c9cb4711103174833994befd1f25814c609ae99d444b6f6b5bc2c3c6a0 AGENTS.md -6e4073eae721bc224dc6551caf0928d9fefadf7d120ecfa02f2162157e10c1a0 CHANGELOG.md -56a24128244b2e0cab7050f0f83acae255dc97720fa165d06ea09bc14f50252f Cargo.lock -c5e5651b1a1dbfbe524ad2e6b131e971d6ffb1038c9519677f067d2d35bc4e07 Cargo.toml +0e637895c0169c86c349f78708e177ed9330600a0bbb72e18e510706abcf4356 AGENTS.md +ebe1675764f6f05f7d37a5e3e647b7b4f5f415fa688af1bd7c20d100f8683954 CHANGELOG.md +18e98232bb0168ba74a5b05e445bf4ba87466442862fb5551399f7312f5c98e8 Cargo.lock +6a74734ce0676472211dd47067f7466923ca273c368385d2d90f22fbbf432ed7 Cargo.toml d6d22ba63f4bc3d16a13012ecaabff8a156be57c824d2f20f66976502fb27d1f Dockerfile -82b353c623d514e9404eead2803f61addedaf4f3e27117c0b7c5341a3af6c512 README.md -fb8affd22820c5ef43a922ec8fa08ffe27d988bd4e24d4f2c4a0886dfabc1d7a ROADMAP.md +9c3dfa617a37af76cfa7816502c5f1d632530cc4534a0269a69cedd15f247d87 README.md +8b2f47dbef3c1969b115d9b03a7fa3fc9a17adf82781bb797de027e841c96edd ROADMAP.md da8311e3db945290666324a2f24bf4521b365272d7ac3f862ded1be993eea646 UPDATE_CHECK.toml 928ba6a504bc431ae100c6e587861e5088b28822d2cb19da5d437b39d26c864a build.rs -8eb7682c9d1e261fbc201bee412d52a823c9ad3015aae363c844394814426efe debian/README.md -37641fa2d47a0331249ccea8028bce95c8b88d2c2a13000a8a09116efb2cd6cf debian/build-package.sh +6422f839a1d8e88099b29807ec76fce1f1ce423df7d51611e206d55e18db5b3e debian/README.md +05860b730c1efcca949e90b8f4dd5c00b60a7bee42c6c956d0877be870df7697 debian/build-package.sh 0763a4bd8b429f7922b23a7276ff694f3a751b83fb127f6ad7ec654e5e507ecd debian/build-repository.sh -0af7b8ccded17dd9de34b23a9be73ffca0d3e420ab5902531889460f8cd22c20 debian/changelog +5455aea1c4ae15f108a601acde9e632b6b587319799bc3a38d6354a7746e88ca debian/changelog c90457b19b1b2f7998d3db59a656d215eb0fab23769197405960457b66d95cf7 debian/control dff2ecb9c14623416981f444bc6df1c4e2bf55d330260f36a312d8d42245400f debian/rules c537d54fd92a9b97c5f6e6ec63bc1276cda324513e2946b341b2193f63b62e6a debian/rustproxy.environment @@ -24,7 +24,7 @@ cb0db03a2c1b06fa04a11f7690755a0ca90b17f19ed8fdb228810f505c48c78a debian/rustpro e8e18df40bcd69d6aa404282679186d9b8256ac63a5b4e80d7f081e8a0095a2e debian/source/format 385ac7970fa94f043d0bcf04a91184e6e2c807587b85e55517ed064bb4bddba6 deploy/README.md 7b7fdf383bbaea4f37b5c120e98a24e9a075fba56ae7838a31a5152c7edcde02 deploy/rustproxy.service -4353c58f038fbd83fda1a9879bb4765b924896e61c2676be6da8ab7154604807 dev.sh +264fd41b01308a831a3413123eeab29d79eb4890ef49b44879f308447c0cd3a6 dev.sh 5f51efe621f45512a466fa7f2656867c6502a135ca040f4bfeec06a6919b39b6 docker-agent/README.md 7fee7d51a7deb67e73e53a0bdff3aa4630aea9bab9b23a0f9b8001b2169892b1 docker-agent/certificate.go 5e4f565c3c9de4dba897af2e801ea646a83395e72eae4717a6d502dff2fcec10 docker-agent/docker-agent.env.example @@ -33,14 +33,14 @@ bf687a851374d8f1fa59d050f3f76532f7c12f16a6daa7d3c36102c2d9a8ec9c docker-agent/d 9d77c90767fa929ee8338734d72ce83284d3d965673270f62cb2b1613d587a33 docker-agent/install.sh b68234472bec5cedd67c7cfe1de7d8806a965dfd4101f944aa6320132f18c14e docker-agent/main.go 3d4051a1f805d145df3877476e4b87773e74be8e123045065955a5133afdc68c docker-agent/main_test.go -eec37615a32bad4fab987f619734864a980e83ac09ace445a2e921bc17f8d326 docker-agent/model.go +dab3d2e6c93ae00f143f73cf35b2f7637d2014e040e5aa3c66930eee3c999600 docker-agent/model.go e52b31d0abf65ae3034f6cb367cca113633014ce8d1d799ad4dd5624d2c7b8bb docker-agent/network.go 634790f35ff4627df2a78cec2ed371f6e9ec9df00afb386075595fc7f3ed72eb docker-agent/rustproxy-docker-agent.service 5220d669171ec3ad65f50e0bc8de5178dadaa4904def8e1a4f61002aa9e9a55b docker-agent/server.go 802a30b793a6ae6a5046489612a23659f33d25e41d0794551381db202daac904 docs/ACME_PROVIDERS.md ec15163f5f51c9212003b7edd1fc380321311c2496fbaa9b45c838281b9af475 docs/ACME_RFC2136.md d699f2261a0d7854e49e9b8bae44fa37008a7d2f6340a73cdc37e840722ea211 docs/API.md -24cfd6b15a149d8dca0a334a8ac841ec008e6f64d3a11aac0563196ae5e1b168 docs/API_ACCESS.md +0d0136d93e466a12955dae1c3ac0b2e30cf90155d500f520cf03c7badc3afc5a docs/API_ACCESS.md 0f7f159ad5b4b5277f80c19f3c47f4e7823ea439ef02e5913e1391f1b34d129f docs/ARCHITECTURE.md cd2597465af031cdb47db802f8ad6d3af34ef9e79f679df906a7b84220ea3260 docs/CACHE.md 9cb338ed07ac1f92ad491e2099a7e3af63e66262417b1fef24d98c6a791d13fa docs/CACHE_DIAGNOSTICS.md @@ -49,9 +49,9 @@ db5534427ff0f004940fd6960906d3eaa75347a110e6322827c51c5d63f20adb docs/CONTAINER 9538a52d508d8d7053c1387c42eef60e6d5dc1879c300b6fe951b3374c16884c docs/CUSTOM_LOCATIONS.md 7db65a96f696aff1d7f74e2041cfc6ecdf437b1412ece90cee26da1ceff4cf7e docs/DOCKER_DISCOVERY.md 86bb62f288f2e999994c302716fc9986dba1ac7a26e598dc97cb56a7bc21cfb5 docs/ERROR_LOGGING.md -8e9df23ee4539162955f9ef86a09a3e227ec7c34c3ee1206b7c14ac6926da19d docs/FILE_LOGS.md +08d76ee22dfe51f6bcbaaacfad796a51d461fcf4e25c1914ba7ae66914021844 docs/FILE_LOGS.md df6ecd4a50796640243676ad4b3a87789f6e5d20cbebea6255e92fbfff1c7131 docs/HTTP3.md -bd94e892186c612459d890f4a1195986e7034b8b3b9d1980090f71b1d07e0263 docs/INSTALL.md +0a4e56fa7451f81fda17db7d5bee946d0aebd50ea856e37862eebf25793ca99c docs/INSTALL.md 3b5c31c805e5aee0dc2100b81246a9b631b5abb996faa598ae94f87ba39305f3 docs/INTEGRATIONS_040.md 4bb56add544f15d54695cf797cd16a51c09024360cdeef803a88988f4a54b3a5 docs/LIVE_LOGS.md 7c35c4cdbe7bbb81d94f3bf6aeb22b8a866af3e7f0d62bbedc299e4d6f264e0d docs/MANAGEMENT.md @@ -62,7 +62,7 @@ e7516646dfb107d6240370f4e7460b1189f2eb21f398740381d5d102847bbfe6 docs/NOT_FOUND 3da047768f32064c5ef0ad7a4c73c4b14930fe7317c54f5650f426af9f484593 docs/NPM_MIGRATION.md 712cb1cbf84515384b081fd2929e86e40af7c10f65bc69919b78b7b3e2fd12b5 docs/PHP_FPM.md 572c70fbd2f61fecd80a8ff9fa5de4a94c4f158de5e90da8e920f99b051241fa docs/PROMETHEUS.md -a4329e7e8f2149e87c8d5610fbea6fe7bbf40b4d01a74b79a60b5cda09808bfe docs/README.md +4a7d0b3586c8e7f92c139faef680b264612de27d1cc9c1c52e92be054d7201c5 docs/README.md 6e46a137b9c88dac8cb9e3fdca877430092392de9913d746278dbff8652460c2 docs/REDIRECTS.md 0dfd0d431c5aedc67abac1ce5de040ffa790ec9578fd7d6f91a987c333d73358 docs/REFERENCES.md ce5afb4f531bb5fb4c453deb49f643f2a563f32f7908c995e5bc8e0d7de995b7 docs/RENEWAL.md @@ -72,7 +72,7 @@ a699fd663bfbf001525f22f0fbacdf03a58c5e825232d8d144e51cbb8b1008b2 docs/SECURITY. 620b69e566d27af04f0604f4ca3f88cf95cdfea7fbc6ae9dd92446d2b2b5d9be docs/SECURITY_AUDIT.md f8baa8bdc8a67bf4e4a6e6d233435f5a43075a09bf08b08b597fcef1853ce5c5 docs/SETTINGS.md 3611defd206cde107e75cac006159856d12cd8f15df7ae2eb9ec3592ed2b4abd docs/STREAMS.md -2fe8ac5e426daec07395b4b1dde4cbd6a6a7def033ac062f6183ad53e29b8606 docs/TEST_REPORT.md +e4a7b55548a48fcc37808a5539056a500e26ca764194519939f3407cd29a882d docs/TEST_REPORT.md cfb452d8496839e832b5fbacdd4e52525b0ecc3112fbb62340c1e580bd5c1717 docs/TODO.md 8ee6187a5460ca45643b7fd789e27bffd264449e3a92ff70e9359edee011bbbb docs/TRANSFORM.md a1e9c6d38d21067d1ce7115ca3395ae8ff1f6a4c40fb0ebf00a6940ef79df439 docs/TRANSPORT.md @@ -104,6 +104,7 @@ bf9b4cf4fec2c8ce287e1b3c2e7d4828e101dafe4d6c173f099819f22493d144 docs/V0.25.5_A 91774f2c23f587a502c65fe2ffaf009aba81b221cb3ede4861ea79abb4d4a528 docs/V0.26.2_IMPLEMENTATION.md 57edc3d5ca6c268b2b6b2e8027e81fb543c0dab86e8f69c4ee5776ea8df901c7 docs/V0.26.3_IMPLEMENTATION.md da5ec87b9482f2fc506c4334d9365f3bfaec89254a14e5585dd6460326b20e10 docs/V0.26.4_IMPLEMENTATION.md +0ddf5215c40c8366844350bc6462d8013dba747b6f3e8fbf477985af215e5e8d docs/V0.26.5_IMPLEMENTATION.md ce259052c023e90a7bfb6e39fe82e52b845a8b2a051bfa29883d29e87a9301a2 docs/VHOSTS.md b979afd3d56731eeb06e9dc38d37730693e7fbf3aa78467932842c0e712e7b26 docs/VHOST_ACCESS.md f0e76167944861517d1d42b9186ff0b2f184be0371b9e8597827e60895de4a76 docs/WEB_SERVER.md @@ -118,14 +119,14 @@ b26833cb4251f9390a44192ecc827ff7f052fd19016a5ccf7498c94503ab4ce3 examples/mock- 5a8f3a8a054abc89c6e78896b9fe2f903212199a24dc3d2d2bcbd0696a31bcde examples/transport.json d242de9614fbb52933b4accd32f4715ca94107abe4a3b1d7e088362b07a6ba60 examples/vhosts-balanced.json af2bdb1343a8141069e94ccd2c7f92574ad848437e2f9fdb5c7576a9a18ef4a5 examples/vhosts-private.json -5c30f169bd7a034a843c7a4e6ccfb923ce009561c8d30c37a70d3c9841bbdbf1 grafana/README.md -ca48eeeb4c7019647fb94ab7d4ca594d1cf03a556c1a8d1c5cfe1fd2d4e96300 grafana/rustproxy-overview.json +a8305f40b11cda25675e6563e457ca54fab1efaabc3c7d8bfbfb808e19bcbbf8 grafana/README.md +350b5d3189f0005a72ed5e0483492638965342d48bf7dbe0d7e4c478415a17b7 grafana/rustproxy-overview.json 30763fc61c38992a44bc24ad6932b88fd3b322724fce799db1f17f9a747eb59a install-debian13.sh 858b39fa6886b71d20690bf369e76580922364b3cc7f0cf6ba9b040df9cd76e3 install.sh 29cada0936762f26495064d1524a668262ed729b21f20aebddc8b6e5cfea363b langs/README.md 8878f138bc909c004181e6ba91bad14c0bf96ea81235c972c3b8d86a640e1b4e langs/en_US.json 695ba1b195fb302dd05574049db98ee0bbe07fe71ef6a1c98dd43776d354235f langs/pl_pl.json -038191475df4ecde40905bae55615ca207aeb05d17aa9bdc13728d4854dd77b5 make_zip.py +a1495abecdfa71e41e6802f2701ad356adf6b334ea702b323d8c12a74c2882dd make_zip.py e830d37dd1f81a4b0aa7d535f5bba69e34e433b0fd99cc8ee0b296786c32379a migrations/0002_admin.sql 20112cc82192098b8d602f1c4f7ca08712e9e1366c845fabb92753187c370d35 migrations/0003_certificate_renewals.sql 5c62da30fa9db594a4d656c77ae676d3c388072b6a85f91170ec7d911d7cde43 migrations/0004_admin_preferences.sql @@ -144,11 +145,11 @@ edb6ee1445b01cd6f3a74a3a607f39fb107d411b49df028d2e0f4679e093de31 scripts/acme_p e69813fb1d3a4cdcfb7243964cc323fc21a603087bf2e84188fa42b9d3cee4b5 scripts/acme_rfc2136.py a5b4451e45ce975685772aa8409b64a57a20a7548466584c3ea7fb975e64729c scripts/admin_audit.py 20e83f8b6347b819d1d1ea3de5c691c36f0816954a4210b0d3f39557fefe1931 scripts/backup.py -9fd134172caa4de5308eb7437a1f7ad1f992ab0053d01b4b7d1f4cf6804e6389 scripts/check_source.py +75e9fe225a3b5b287723c33f9e2a67ed4e7c390d1de066af6db6fa8a32495ec3 scripts/check_source.py 187ee92c8029cdd59e89b4447cf4d170e856017a2091ceb85ae7c22dd1a79c72 scripts/deploy.py -a763d2dc2fec8cffe10714063364f40e4d08bd6412fabcfdefab828580b8d9cd scripts/deploy_core.py +50ec4f6a3ca690a98027f57fade01692a475ba0688696788831f82612a0eed43 scripts/deploy_core.py f014472588e889488976970dbaa95a8745b6907516aa81a7cca21d0f81eaaad3 scripts/deploy_runtime.py -f399b2ca97ba0c11675197ddf96ce6d8f233a2e1983619041c26e70bbef65558 scripts/docs_check.py +27ef5560957fa9f6e6aedc64a0534feca31699a82bd0059044f0d5f8fcd85b29 scripts/docs_check.py 6facb2d65bfab234f09855097d12da8f72669a38ebceb4b1cbd03ab42b8d2469 scripts/langs_check.py 2e35b7c78887fd56f83ca9017caa168630963a9f47da71dfc53b1a8f9ad436c2 scripts/memory_contracts.py 2cc658faaa610b21b48942c59b955525539ad4503fd60f2a49c7e626a22faaff scripts/migrate_npm.py @@ -158,8 +159,8 @@ d1418f8e574a7390fd45a2aa879bdf5720b773162d65e295ab0350506aa5220a scripts/mock_a 2d3ff92300b09ce9cecbbaaa9309b4d33160fa4b2291c9952b784e8cfb599ab5 scripts/mock_server.py 2d4c859aae5ba357a6d30024c8487ae8f59f01b192711f13f9c2f8fee0f48b50 scripts/os-acme-client/README.md c73b814a42bb4ff703441dbd177ee625055eeb115f9b5bb0c2150aede573a159 scripts/os-acme-client/opnsense-rustproxy-cert-deploy.sh -4b000848d10f552d39cab5be309fc455e2f3b90490762fe1055e7abd06968bc3 scripts/preflight.py -40c260046c93a43e12cd90e303b92de2c65d30dcdb365d68a739510749172b95 scripts/release_smoke.py +7d81a3c4f769f69c7e765a679256ae65d2f9b135ae9cd0733685d553ea007c30 scripts/preflight.py +a87225dab931238ab025de6a00142662b759089b6ffee86dba0f9ed23bbc1fb3 scripts/release_smoke.py 45be151cd85fc2ef2f1fdc3003ace63381af262e73af8a685ab48cb697cc0de1 scripts/routeros-oci-build/.env.routeros.example 3b48cff8506e5a6ae7d3876f47721f5de7d63e2e02264a78cf5b6ddd52d9fbc6 scripts/routeros-oci-build/Dockerfile.routeros 7c7a3e51f43b43e1c962a4b0bb591f99c1f06977bf77f23719f7f867dfe7eb8e scripts/routeros-oci-build/Dockerfile.routeros.dockerignore @@ -171,11 +172,11 @@ ecfe0bb21a7549225a19b0846bb6de8c99cbfbbf5a706d33cf84db2c7146abed scripts/rust_s 1c83054336b3508d7ad72cd259f039394682642439877fe69639c0b76be09154 scripts/security_contracts.py 295b6f2625b1875950ea3eecccd142f49be327afdd00c92641286e6de530ec51 scripts/security_dependency_contracts.py 6fefb5c459aacdef3dcabe9c5e6e7718a2145a0190b165c29d7a46216ac53bad scripts/source_module_contracts.py -28f516f8c5f686dfc72ebef0cb0338d06cbd4eb9f5ff93602f0dfbae3e9a871f scripts/swagger_assets.py +8081b503df9bb4e338f1ae222d0456e3964f1308acc105796caab80cd79c9b03 scripts/swagger_assets.py 102b23de19a88a8e60de392fb83aefd3dfb33e90cc97ed1690d9f3d4a33d8866 scripts/test_compression.py -010bc2454701e42e458e07a86c16ca62a9fa00449a9638ab0425b08739f07a91 scripts/upgrade.py +04a1865ada20e726ed9abdd13bddc0d1e38f99b740de5642fb5c2aac307414d5 scripts/upgrade.py 0aaa80453e25aae7ea953fadb91b3ae3eaff627977c81c9ab5a2779f9a93582f scripts/web_assets.py -f22b1b4211b76851fb8be7d5330af0b31fe7732a080f342ce5116bb27582a26a scripts/web_server_contracts.py +a68c6016f91ce16f9bba39dfd0db5983c8a0de83e7f2cddd44f7b0fac93c06cf scripts/web_server_contracts.py ced042b5e283fd40fe25c261457dceb57d946dffebd89876cd80d69b92823932 scripts/web_service_ui_test.mjs d8e2b51c39252dbb4305512fa9b1ef508ec610968aed316b10514fd160298762 src/acl.rs 4e3be1ea1be0a81529c7c9021fb9bb77c24e5044acd54094972745443ad2c26a src/acl/tests.rs @@ -188,13 +189,13 @@ b9e57db4bd80ef37564dfc533a96897d8a494671d53acea9fb4bf28d23ba370d src/acme/provi 55ef7ceb44c25c7a8ddcbfd5e0d4b647526f9bdcde901ee08db5314e4d055b39 src/admin/access.rs 85f00f8157e83a152cc531f4cfecd0b1472ce269be9c8eb1ac17ad0693748b42 src/admin/certificates.rs 1de4c7c116eeab2452ccccbaba3f2b7b63c6eb1c1e146ab870d19c5a5ca16f80 src/admin/documentation.rs -eab5d50e7326e2224b41fc8b5018a89a06ed9aa1f99954f84bf17d992e78bcf2 src/admin/documentation/documents.rs +c04fb07cff748a3ce49914340ba89750a3c25799444927615ac969c699f86513 src/admin/documentation/documents.rs 67b901485d5858d5b5bf78a6260035db32241531d99481754c3533fdf404facb src/admin/documentation/tests.rs 002922c91aa07cbea17cb0ee11127bb6e7e015de108ee032761b34507dcfa06d src/admin/file_log_search.rs d3210e037481e1f95e840550428e088ffd83ec9a42f1810e4c976298fb555a9a src/admin/file_logs.rs beb8be241e4f1a8cea7b6c4e02b42f0359fb1fff10ab5ce2c70ccd0e63a554b0 src/admin/logging_api.rs 58802528128f53e493f7339063433a747b605007a8842b5efc670132d897d6f7 src/admin/mod.rs -8b8ae7ebefe9a74ac47e3e024da2abb38fdde02109dfe7924eca8413745ff157 src/admin/openapi.json +43fdc5446451337ef3b227b168e5adf321cf02971e33d1e6b0e1f79cb11eece8 src/admin/openapi.json a53309daf118381031122ca70764f7a2f92adc44af3fc91df5f946e6856f76ae src/admin/operations.rs e9ea015aabdfdbb2f8dd72ea734002b5d648dc1bbef4cc4a0b85d2bcc059e9a5 src/admin/preferences.rs b4fa393b780b2676b5d72e0f90cd7290292f424b8062d4b5983e722d6ca72c32 src/admin/public.rs @@ -215,7 +216,7 @@ f869e4da5de149fc04ce1aab658befeaf3208c862f149ca976235d15832c3cdb src/admin/test 860bce21c27ced60f3d37344c1715d9c60899fa08f5f01c590f0ea81690b014a src/admin/web/app/core.js 145430fa86e8111f2cc8c0ee484eb732df84d42cc8b628f4c2097b8f33bf51d9 src/admin/web/app/preferences.js d7f6675277c927f4eae1b83c7aa91b315429e7034dfe61c489c2f737a9c19f07 src/admin/web/app/runtime.js -8afb11a17fa61d42390667d076ae1485a7398be9b095d235f1486d552d410620 src/admin/web/app/settings.js +6b48134f9fbc566356e7dbb6665267520fb8394798751338575335bbba3b5f4c src/admin/web/app/settings.js 642d013e2e18dc8a8eccc7a2fe93d6570521dc9a0644beac7af4bbe8c5cea1ee src/admin/web/cache-panel.js 50d1ebcbaf4d0b2968da23bb943fc3f67131c5d32df3f61d23ff37aad9da5b81 src/admin/web/demo.html 3b84a7a08f9f68e2c78fed4523b594c31a251addc5480a69c5f6949908230539 src/admin/web/docker.js @@ -232,7 +233,7 @@ e6c4d91d1542d0a5b47bb8736f9539d43a6713df5a473b635519d5b7eac2eb9c src/admin/web/ 0a5fff35555153f59d4346933030a67b6e1a8768cee7a47cfa2fcf1a2c564f63 src/admin/web/favicon.svg af6e7a2e890df2fb7385a374bcb3fba52fb5a53dbe18adc1fb7865660fcba842 src/admin/web/file-logs.js 631860ab3793ffd827c7cf19ddd049d14419509f2c2d8b27994b0e54baa0e32a src/admin/web/host404.js -b2b8b7ac06c79c7d69125d2cf092b33114d052b517dff37312eda023019c39a3 src/admin/web/index.html +1734c507580441c1b192b7300d6eabd41e06c5663ad1aa32a121273dceebf5f2 src/admin/web/index.html 24db88842707f764064657712d3660c6ac129fbfb47d188c0903925cf8244ce5 src/admin/web/integrations.js cdab0c11a28deebdf401c0453fbc76b675e9e643722106fb20e812bb9648ccde src/admin/web/login-keys.json a253d202dc9a147f2add34c64e0f35c38fdc7f667f9908933ce5f959b1a92a2e src/admin/web/login.html @@ -240,8 +241,8 @@ a253d202dc9a147f2add34c64e0f35c38fdc7f667f9908933ce5f959b1a92a2e src/admin/web/ 1b096d96a9d6b904a87bd4194fa40f22310a42c765f3ffa299c4da1f14c6e248 src/admin/web/management.js a2dbdd205b899b92cb9817f76d0c79a27b153c80ac0fd60da435c7a4fddbb958 src/admin/web/redirects.js f1ab20afa09f75f3635511756e36afea46a7917f04937d6f4e89c4e9f3f43204 src/admin/web/settings.js -f57c79477160dda93ba90aecb4c9293383caef3b3f8829a25608ad85954356f8 src/admin/web/streams.js -778b0b5fba6a774afb3c79a5b57b4591221cfd1ae770322342deab99e6179603 src/admin/web/style.css +0ffc345ffbbd0a60b80fd39413a4d2ca1023012c0f73ff61af6f5456c5072030 src/admin/web/streams.js +ed7844ad6735716caa681d888664a67e10aa38b7a58b4d42c96d609a62184f97 src/admin/web/style.css a8a73a4fa849ae49391fcd6143e900c515c8b577f71b55cbae9701fa9f5bbe47 src/admin/web/traffic-panel.js e686d68fd6a368110a85dc4c5dc64e8093950d20d63e9aa44790c03dea6fc193 src/admin/web/transform-panel.js 6856c230c4f6b18145e16efb6636433f8b21ce3ec5d34246d6561f0150ea0554 src/admin/web/vhosts/core.js @@ -351,11 +352,11 @@ a16613114273c54b6d2a16a94fa8748550e91468585469642622bd2c86087baa src/logging/fo 17425ebbca6bbbb0dcaeb65ebc44b1e51488a4092b7b6add556e764c6d486d6a src/logging/tests.rs 3836ed14b6710e183f048ee4d7807a35366c27a27338057fe4a2811129b63302 src/main.rs 46732ed6d9cf2a33031624f941b8318d2676fb1b6bb5142e96820301f9fa1ac4 src/main/admin_runtime.rs -d92c3414cf7a86b027042d14d5cedc8dd8adeeafd7bc961032e2c5f322d01d4f src/main/bootstrap.rs +9dbeabe4f29a2ca6ca89203d2ab2f4cd0b515739e8e9e2fbf7cdd4ac5ef78846 src/main/bootstrap.rs 5a98d0e249338e73aa57ae2e352dc16db2f79c2d042c1544ce1c2022da76a31c src/main/proxy_runtime.rs 4dd7c1084a6214c0f2513ebf86fe8ef144470695557772bfe25979edd64491ab src/main/shutdown.rs 0a6578a0f4023b9f8d73043bf942dc5e096ef9afb8c0d2f131c14f65d08ac01d src/main/shutdown/tests.rs -88edd345a0ea0eb9dd6800e990661639ec810997bc7b1206006a3d85707af76c src/main/tasks.rs +b60d30d1013df84a5656997a2e4a3b3bf04c97dabd14569ed27969bda19d3b98 src/main/tasks.rs 49d7e104585c8791ac9a203dddd95802784b68c0ba65d6f90f3d57154b4c7871 src/metrics.rs 201ab702722d6d21585fe8bb49939150d61bfac7ed8dc198b98c2cc6098ffb5f src/metrics/global.rs 49b11df65b4fb0b5b727f9f867436584680b45e3f4fbd53f74bc0cab8b9a88ec src/metrics/vhost.rs @@ -462,7 +463,7 @@ f0479524d66bfee7a6eed5eea03601630ba82064fb944902deb9166f90fe17cf src/vhost/vali 9c1c8d6eedecb95eadbfb23c3caea562f6f7a995606ef988f25b58c2d03bcdd5 src/web_server/config/model.rs 6191f4d541476c4a3ae296e7dd28bdb9f8a123fc509b47619f6f44519c44d278 src/web_server/config/validation.rs 86c744216d7132d8294a6e90ba9be5fd871646006313d1c62506d40c81db9b12 src/web_server/fastcgi.rs -1e5b3265e4aca4de07dc93a471faeaf248dbf843ed845a11b50226e9b61c950d src/web_server/fastcgi/protocol.rs +6d174715499fb64662a75dd4c81872097be9f6f27a16886a29308b823890be7c src/web_server/fastcgi/protocol.rs 134c4998f6a0aa27e121af1ae3355b7e335488b2ae867ac0a934c58b4eb77191 src/web_server/fastcgi/response.rs 8186363315bd998919c6c783e6f7501528f257a5c0da77c5d60f423e8670db5e src/web_server/filesystem.rs 0aafd7f37c4fe784b047646e4ce5ddcb5fe821231a41ed0a9f519529385288a8 src/web_server/htaccess.rs @@ -472,14 +473,14 @@ f0479524d66bfee7a6eed5eea03601630ba82064fb944902deb9166f90fe17cf src/vhost/vali 80f946570c14c8915fd21bfdb1a84dfb6a14c633ab6060acb828fab4c7c21daa src/web_server/mod.rs 67ab8bef567452f123c4b9b46a942b39c93f1f765c128edca7ee808ff1c5e304 src/web_server/request.rs c5cb561b0f276e8082f904b9446fa5885f6b3c0608f25ea2ef425061e9f7f6b4 src/web_server/response.rs -4ef82ec2746afd520c43f7c823a059a1ae903f840680f3da812aeaf8d8655a51 src/web_server/response/file.rs +7725efc335bf7ef30e6e7ca4dcc1c5f0c2b41ba6d6c7a48a455e62ddf9a99e30 src/web_server/response/file.rs 9aa68251a5f549f4ce3b1bda88d4abb9efc629caf444989381b4117c9488e37b src/web_server/response/headers.rs 2268a6aeed2f565f9791af33e1cd21c56c228c8873b031725b39a6c57184f2d1 src/web_server/routing.rs 400e1c8aa2fe857d96036a64499fbc3de44c1e3a53811c5b25101fb843359792 src/web_server/security.rs 3e0b4e92600a7d5abcec92efed532b3a01e0781cb4f2681daac6d6ae13b0a6e9 src/web_server/serve.rs cf86c4692080723bbdf8f4105e1abfae33d7fcf020d2ad9e13ebae3943bd0cbe src/web_server/tests.rs c62752fe2fa6b74ddc9d94d36f8d191376b1575b15d21fc434c5a5da4c932692 src/web_server/tests/part_01.rs -51b15848e0a43b08299c1e0420614966559c387a7f8731885b50399aa4ca8c6d src/web_server/tests/part_02.rs +ad33371765d64f896eda8b5e9789cd2db46af0a8f7d14ce2af1e92b40edb4f4a src/web_server/tests/part_02.rs e54f44f6ca1ed2c41e620de9195d32c4f8bb6936c3881745316a07160f87b4fa src/web_server/tests/part_03.rs f00743af2cf4a5952caef7a1dcf68e7817b5599a252a9973e1c22045517c0b0e tests/fixtures/argon2id.json 1725c10331745dc04a07675784d385260da7b14567b8dba3cbae5e891eb5dadf tests/http2.rs diff --git a/debian/README.md b/debian/README.md index 2018d7b..65c12c2 100644 --- a/debian/README.md +++ b/debian/README.md @@ -1,6 +1,6 @@ # Debian packaging -This directory builds the `rustproxy` binary package for RustProxy 0.26.4. +This directory builds the `rustproxy` binary package for RustProxy 0.26.5. The package installs: - `/usr/bin/rust-proxy` diff --git a/debian/build-package.sh b/debian/build-package.sh index b95ce92..89e1096 100755 --- a/debian/build-package.sh +++ b/debian/build-package.sh @@ -21,6 +21,6 @@ cargo fetch --locked dpkg-buildpackage -us -uc -b mkdir -p dist -find .. -maxdepth 1 -type f \( -name 'rustproxy_0.26.4_*.deb' -o -name 'rustproxy_0.26.4_*.changes' -o -name 'rustproxy_0.26.4_*.buildinfo' \) \ +find .. -maxdepth 1 -type f \( -name 'rustproxy_0.26.5_*.deb' -o -name 'rustproxy_0.26.5_*.changes' -o -name 'rustproxy_0.26.5_*.buildinfo' \) \ -exec cp -f {} dist/ \; echo "Packages copied to $ROOT/dist" diff --git a/debian/changelog b/debian/changelog index 214bfcd..9a49062 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,11 @@ +rustproxy (0.26.5) stable; urgency=medium + + * Align compact toolbar selects with scaled input heights. + * Route the Streams Add TCP/UDP listener shortcut to Settings -> Listeners. + * Keep schema 8 and saved configuration compatibility with 0.26.4. + + -- RustProxy Maintainers Tue, 06 Oct 2026 11:45:00 +0200 + rustproxy (0.26.4) stable; urgency=medium * Add 404-host draft support and standardize modal Enabled controls. diff --git a/dev.sh b/dev.sh index 0cd39f4..97f2812 100755 --- a/dev.sh +++ b/dev.sh @@ -18,7 +18,7 @@ if [[ $# -gt 0 ]]; then shift; fi case "$mode" in help|-h|--help) cat <<'HELP' -RustProxy 0.26.4 +RustProxy 0.26.5 ./dev.sh Build and start proxy + local panel ./dev.sh run [serve flags] Same, with extra server options ./dev.sh admin setup-token Generate/print a one-time setup capability before first login @@ -139,7 +139,7 @@ if [[ "$mode" == "test" ]]; then printf 'Checking all Rust targets before tests...\n' >&2 cargo check --locked --all-targets fi -printf 'Building RustProxy 0.26.4...\n' >&2 +printf 'Building RustProxy 0.26.5...\n' >&2 cargo build --locked BIN="$CARGO_TARGET_DIR/debug/rust-proxy" case "$mode" in diff --git a/docker-agent/model.go b/docker-agent/model.go index fe1d4cc..9e003ac 100644 --- a/docker-agent/model.go +++ b/docker-agent/model.go @@ -1,6 +1,6 @@ package main -const version = "0.26.4" +const version = "0.26.5" type config struct { Listen string diff --git a/docs/API_ACCESS.md b/docs/API_ACCESS.md index 281eca7..f6c7808 100644 --- a/docs/API_ACCESS.md +++ b/docs/API_ACCESS.md @@ -1,4 +1,4 @@ -# Administration API access - 0.26.4 +# Administration API access - 0.26.5 ## Sign-in boundary diff --git a/docs/FILE_LOGS.md b/docs/FILE_LOGS.md index 00fa9d2..ca39872 100644 --- a/docs/FILE_LOGS.md +++ b/docs/FILE_LOGS.md @@ -1,6 +1,6 @@ # Stored log explorer -RustProxy 0.26.4 provides an authenticated, read-only **Logs** workspace at `/logs`. The top bar has one **Logs** menu with separate **Stored logs** and **Live Logs** actions; the two data paths remain independent. +RustProxy 0.26.5 provides an authenticated, read-only **Logs** workspace at `/logs`. The top bar has one **Logs** menu with separate **Stored logs** and **Live Logs** actions; the two data paths remain independent. ## Separation from Live Logs diff --git a/docs/INSTALL.md b/docs/INSTALL.md index be90a59..2391ed6 100644 --- a/docs/INSTALL.md +++ b/docs/INSTALL.md @@ -1,4 +1,4 @@ -# Installing and updating RustProxy 0.26.4 +# Installing and updating RustProxy 0.26.5 The scripts prepare a Linux/systemd installation. This source archive is **not a verified production build**: Rust/Cargo, real CA operations, live systemd startup diff --git a/docs/README.md b/docs/README.md index 90744e6..dd04069 100644 --- a/docs/README.md +++ b/docs/README.md @@ -15,6 +15,7 @@ This is the canonical index for the current project documentation. The authentic - [0.25.1 release audit](V0.25.1_AUDIT.md) - historical Traffic/module-split release scope and compiler-regression guards. - [0.25.0 specification audit](V0.25.0_AUDIT.md) - Web Server foundation point-by-point implementation status. - [0.25.0 pre-production security audit](V0.25.0_SECURITY_PREPROD_AUDIT.md) - threat-oriented source/configuration review, fixes made in-session and mandatory runtime security gates. +- [0.26.5 implementation note](V0.26.5_IMPLEMENTATION.md) - interface-scaled form/select alignment and corrected Streams listener navigation. - [0.26.4 implementation note](V0.26.4_IMPLEMENTATION.md) - 404 drafts, consistent modal controls, compact Overview settings and idle age-based backend rotation. - [0.26.3 implementation note](V0.26.3_IMPLEMENTATION.md) - global interface scaling, chart themes, square draft dock and Settings navigation polish. - [0.26.2 implementation note](V0.26.2_IMPLEMENTATION.md) - unified Logs navigation, field-query search, dynamic JSON columns and RAW parsing. @@ -64,7 +65,7 @@ This is the canonical index for the current project documentation. The authentic ## Historical or version-labelled context -Version-labelled `V*.md` files are retained as historical implementation/audit records. Their version number describes the audited milestone. The current release implementation note is [V0.26.4_IMPLEMENTATION.md](V0.26.4_IMPLEMENTATION.md); [V0.26.3_IMPLEMENTATION.md](V0.26.3_IMPLEMENTATION.md) is retained as the prior appearance/UI milestone, [V0.26.2_IMPLEMENTATION.md](V0.26.2_IMPLEMENTATION.md) as the prior Logs/UI milestone and [V0.26.1_IMPLEMENTATION.md](V0.26.1_IMPLEMENTATION.md) as the prior protocol-attribution milestone. The latest retained audit is [V0.25.5_AUDIT.md](V0.25.5_AUDIT.md); older audit files remain historical evidence. +Version-labelled `V*.md` files are retained as historical implementation/audit records. Their version number describes the audited milestone. The current release implementation note is [V0.26.5_IMPLEMENTATION.md](V0.26.5_IMPLEMENTATION.md); [V0.26.4_IMPLEMENTATION.md](V0.26.4_IMPLEMENTATION.md) is retained as the prior administration/backend-lifecycle milestone, [V0.26.3_IMPLEMENTATION.md](V0.26.3_IMPLEMENTATION.md) as the prior appearance/UI milestone, [V0.26.2_IMPLEMENTATION.md](V0.26.2_IMPLEMENTATION.md) as the prior Logs/UI milestone and [V0.26.1_IMPLEMENTATION.md](V0.26.1_IMPLEMENTATION.md) as the prior protocol-attribution milestone. The latest retained audit is [V0.25.5_AUDIT.md](V0.25.5_AUDIT.md); older audit files remain historical evidence. Older context documents such as [INTEGRATIONS_040](INTEGRATIONS_040.md), [MANAGEMENT](MANAGEMENT.md), [SECURITY_AUDIT](SECURITY_AUDIT.md), [ACME_RFC2136](ACME_RFC2136.md) and older version audits remain available for traceability but should not override the current functional/technical documents above. diff --git a/docs/TEST_REPORT.md b/docs/TEST_REPORT.md index eec0096..67acf70 100644 --- a/docs/TEST_REPORT.md +++ b/docs/TEST_REPORT.md @@ -1,18 +1,16 @@ -# Verification report - RustProxy 0.26.4 +# Verification report - RustProxy 0.26.5 ## Scope -RustProxy 0.26.4 is a compatibility-preserving administration/UI and backend-client lifecycle maintenance release. SQLite remains schema 8 and the saved proxy configuration format is unchanged from 0.26.3. +RustProxy 0.26.5 is a compatibility-preserving administration UI patch on top of 0.26.4. SQLite remains schema 8 and the saved proxy configuration format is unchanged. -The release adds 404-host forms to the existing session-only draft dock; completes the Polish Button style translation; makes compact toolbar search/filter inputs follow the selected button height; reuses the vhost Enabled-state presentation in 404-host, Redirect and Stream editors; replaces the tall Overview-card checkbox list with compact visibility/reorder tiles; and makes age-based upstream-client recycling run from backend maintenance even when no request arrives. - -The backend change keeps request-count recycling request-driven. The new maintenance path checks `pool_recycle_seconds`, uses the existing atomic generation/rotation guard and starts an idle-maintenance generation with zero requests. A Rust unit regression is included for age-based rotation without a triggering request, but this workspace cannot execute Rust tests because Cargo/rustc are unavailable. +The release makes compact toolbar selects and inputs share one scaled control box, wires ordinary form controls to the existing interface-scale field variables, and changes the Streams **Add TCP/UDP listener** shortcut to navigate to Settings -> Listeners instead of opening a new Stream editor. The 0.26.4 draft, modal consistency and idle backend-rotation fixes remain unchanged. ## Source-level regression coverage -Rust-independent contracts now require 404 draft registration, the shared Enabled-control helper, compact Overview tiles, toolbar controls bounded by `--button-min-height`, and backend maintenance calls for ordinary and WebSocket clients. Existing source, security, memory, Web Server, documentation, packaging, upgrade and SQLite migration contracts remain enabled. +Rust-independent contracts require the shared toolbar control-height variable, scaled field variables in the common form-control rules, and the Streams listener shortcut handler to call the Settings/Listeners navigation path. Existing 0.26.4 draft, Enabled-control, backend-maintenance, source, security, memory, Web Server, documentation, packaging, upgrade and SQLite migration contracts remain enabled. -Browser JavaScript syntax checks cover the changed core/preferences/404/Redirect/Stream/vhost editor files. The simulated Web Server UI test remains green. Language packs and OpenAPI JSON parse successfully, and the Docker Agent Go tests pass. +Browser JavaScript syntax checks cover the changed administration modules. The simulated Web Server UI test remains part of the release gates. Language packs and OpenAPI JSON are parsed, and the Docker Agent Go tests are run when available. ## Verification status in this workspace @@ -36,7 +34,7 @@ Browser JavaScript syntax checks cover the changed core/preferences/404/Redirect | `./dev.sh check` | BLOCKED: Rust/Cargo toolchain unavailable in this workspace | | `cargo fmt --check` | BLOCKED: Rust/Cargo toolchain unavailable in this workspace | | `cargo clippy --all-targets --all-features -- -D warnings` | BLOCKED: Rust/Cargo toolchain unavailable in this workspace | -| `cargo test --all-targets --all-features` | BLOCKED: Rust/Cargo toolchain unavailable in this workspace; the new age-rotation unit test is therefore not runtime-executed here | +| `cargo test --all-targets --all-features` | BLOCKED: Rust/Cargo toolchain unavailable in this workspace | | complete release build | BLOCKED at Rust compilation: Rust/Cargo toolchain unavailable in this workspace | -The 0.26.4 source archive must not be described as compiler-verified until the Rust-enabled release-host gates pass. Rust-independent checks verify source structure, UI/translation contracts, security invariants, migrations, upgrades, documentation, JavaScript syntax, Go-agent behavior and deterministic archive behavior, but they do not substitute for Rust parsing, type checking, Clippy or runtime tests. +The 0.26.5 source archive must not be described as compiler-verified until the Rust-enabled release-host gates pass. Rust-independent checks do not substitute for Rust parsing, type checking, Clippy or runtime tests. diff --git a/docs/V0.26.5_IMPLEMENTATION.md b/docs/V0.26.5_IMPLEMENTATION.md new file mode 100644 index 0000000..2202fd9 --- /dev/null +++ b/docs/V0.26.5_IMPLEMENTATION.md @@ -0,0 +1,26 @@ +# RustProxy 0.26.5 implementation note + +## Scope + +0.26.5 is a compatibility-preserving administration UI patch. SQLite remains schema 8 and the saved proxy configuration document is unchanged from 0.26.4. + +## Scaled form controls + +Interface-scale preferences already publish field sizing variables. Form inputs, selects and textareas now consume those variables consistently, while compact toolbar filters derive one shared height from the active button size and scaled field height. This keeps native select boxes visually aligned with neighboring search inputs without allowing toolbar fields to grow taller than the action controls beside them. + +The change applies to the shared administration stylesheet, including Stored Logs, Backends, vhost-style lists, Docker, Live Logs and Settings filtering surfaces. + +## Stream listener shortcut + +The **Streams -> Add TCP/UDP listener** shortcut no longer opens a blank Stream editor. It switches the administration workspace to **Settings -> Listeners**, preserving normal Settings URL/tab synchronization. + +## Compatibility + +- SQLite schema: 8 (unchanged). +- Saved proxy configuration format: unchanged. +- Administration preferences: unchanged; no migration required. +- Upgrade from 0.26.4: no data migration required. + +## Verification + +See [TEST_REPORT.md](TEST_REPORT.md). Rust-independent source, documentation, browser-JavaScript, packaging and Go-agent gates can run in this workspace. Rust compiler gates still require a release host with Cargo. diff --git a/grafana/README.md b/grafana/README.md index e86e237..3f371bb 100644 --- a/grafana/README.md +++ b/grafana/README.md @@ -19,7 +19,7 @@ classes, cache outcomes, capture-state gauges and configured-route traffic. Raw are intentionally absent from Prometheus labels. Import the JSON in Grafana and select a Prometheus datasource when prompted. The -dashboard expects RustProxy 0.26.4 metric names and a scrape interval around 15s. +dashboard expects RustProxy 0.26.5 metric names and a scrape interval around 15s. Collectors can be disabled in RustProxy settings; panels for disabled collectors will simply show no series. diff --git a/grafana/rustproxy-overview.json b/grafana/rustproxy-overview.json index 7c41be6..ffaa595 100644 --- a/grafana/rustproxy-overview.json +++ b/grafana/rustproxy-overview.json @@ -4529,9 +4529,9 @@ }, "timepicker": {}, "timezone": "browser", - "title": "RustProxy 0.26.4 - Operations", + "title": "RustProxy 0.26.5 - Operations", "uid": "rustproxy-0170", "version": 5, "weekStart": "", - "description": "RustProxy 0.26.4 operations dashboard including backend client lifecycle/retry diagnostics, bounded Traffic analytics, country and User-Agent-family visibility, and built-in Web Server traffic." + "description": "RustProxy 0.26.5 operations dashboard including backend client lifecycle/retry diagnostics, bounded Traffic analytics, country and User-Agent-family visibility, and built-in Web Server traffic." } diff --git a/make_zip.py b/make_zip.py index 77197f8..63e516a 100755 --- a/make_zip.py +++ b/make_zip.py @@ -88,7 +88,7 @@ def add_file(archive: zipfile.ZipFile, rel: Path, data: bytes, timestamp: tuple[ def main() -> None: parser = argparse.ArgumentParser(description=__doc__) - parser.add_argument('output', nargs='?', type=Path, default=ROOT.parent / 'RustProxy-0.26.4.zip') + parser.add_argument('output', nargs='?', type=Path, default=ROOT.parent / 'RustProxy-0.26.5.zip') output = parser.parse_args().output.resolve() paths = files() checksum = ROOT / 'SHA256SUMS' diff --git a/scripts/check_source.py b/scripts/check_source.py index 4ae8f6a..c0ddcb2 100755 --- a/scripts/check_source.py +++ b/scripts/check_source.py @@ -24,7 +24,7 @@ def read_docker_agent_source() -> str: preflight(root) manifest = tomllib.loads((root / "Cargo.toml").read_text()) -assert manifest["package"]["version"] == "0.26.4" +assert manifest["package"]["version"] == "0.26.5" assert manifest["dependencies"]["quinn"]["version"] == "0.11.12" h3dep = manifest["dependencies"]["h3"] assert h3dep["package"] == "hpx-h3" and h3dep["version"] == "=2.5.19" and "quinn" in h3dep["features"] @@ -32,14 +32,14 @@ assert "h3-quinn" not in manifest["dependencies"] lock_path = root / "Cargo.lock" if lock_path.exists(): lock = lock_path.read_text() - assert 'name = "rust-proxy"\nversion = "0.26.4"' in lock + assert 'name = "rust-proxy"\nversion = "0.26.5"' in lock assert 'name = "systemstat"' in lock and 'name = "metrics-process"' in lock and 'name = "sysinfo"' in lock, "Cargo.lock must be resolver-generated after adding cross-platform statistics libraries" for release_doc, marker in { - "README.md": "# RustProxy 0.26.4", - "CHANGELOG.md": "## 0.26.4", - "ROADMAP.md": "## 0.26.4", - "AGENTS.md": "Current source version: 0.26.4.", - "docs/TEST_REPORT.md": "# Verification report - RustProxy 0.26.4", + "README.md": "# RustProxy 0.26.5", + "CHANGELOG.md": "## 0.26.5", + "ROADMAP.md": "## 0.26.5", + "AGENTS.md": "Current source version: 0.26.5.", + "docs/TEST_REPORT.md": "# Verification report - RustProxy 0.26.5", }.items(): assert marker in (root / release_doc).read_text(), f"stale release identity in {release_doc}" assert tomllib.loads((root / "rust-toolchain.toml").read_text())["toolchain"]["channel"] == "stable" @@ -195,7 +195,7 @@ for marker in ['toggleVhostEnabled', 'vhQuickEnable', 'vhQuickDisable', 'backend assert 'rustproxy-backend-table-v1' not in vhosts_js and 'poolTablePreferenceKey' not in vhosts_js assert 'window.rustProxyPreferences.update({' in vhosts_js and 'backend_table_sort' in vhosts_js and 'backend_table_descending' in vhosts_js style_ui = (root / 'src/admin/web/style.css').read_text() -for marker in ['--scrollbar-thumb', '*::-webkit-scrollbar-thumb', '.backend-table-tools', '.vh-enable-control', '.vhost-quick-toggle', '.dashboard-widget-toggle', 'height: var(--button-min-height)']: +for marker in ['--scrollbar-thumb', '*::-webkit-scrollbar-thumb', '.backend-table-tools', '.vh-enable-control', '.vhost-quick-toggle', '.dashboard-widget-toggle', '--toolbar-control-height: min(var(--button-min-height), var(--ui-field-min-height))', 'height: var(--toolbar-control-height)']: assert marker in style_ui, marker preferences_js = (root / "src/admin/web/app/preferences.js").read_text() assert 'dashboard-widget-toggle' in preferences_js and 'visible.type = "checkbox"' not in preferences_js @@ -231,6 +231,7 @@ for marker in ["rustProxyRedirects", "redirectTargetType", "status_code", "cache assert marker in redirects_js, marker for marker in ["rustProxyStreams", "streamTrafficChart", "streamPendingRestart", "stream-listener-add", "chartHistory", "sessions_total", "bytes_in", "bytes_out"]: assert marker in streams_js, marker +assert '$("stream-listener-add").addEventListener("click", () => { setPanel("settings"); window.rustProxySettings?.select("listeners"); });' in streams_js integrations_js = (root / "src/admin/web/integrations.js").read_text() assert "addressTagEditor" in integrations_js and "listener-address-chip-editor" in integrations_js assert "stream-host-rows" not in integrations_js @@ -249,7 +250,7 @@ assert 'Opt-in health decisions based on ordinary user traffic. Defaults to disa assert '"force_ssl"' in openapi and '"forward_client_ip"' in openapi assert '"backend_header"' in openapi and '"backend_timing_header"' in openapi assert '"StreamMetrics"' in openapi and '"streams"' in openapi -for marker in ['"version": "0.26.4"', '"/api/traffic"', '"capture_user_agent"', '"capture_country"', '"hot_auto_trim_enabled"', '"hot_auto_trim_after_seconds"', '"hot_auto_trim_target_percent"', '"/api/config/{section}"', '"ConfigSectionUpdate"', '"cold_on_idle"', '"cold_on_age"', '"cold_max_hot_seconds"', '"cold_on_lru"', '"cold_on_shutdown"', '"cold_gc_interval_seconds"', '"cold_gc_max_delete"', '"collapse_enabled"', '"collapse_wait_timeout_ms"', '"collapse_timeout_fallback"', '"stale_if_error_timeout"', '"stale_if_error_connection"', '"stale_if_error_dns"', '"stale_if_error_tls"', '"stale_if_error_statuses"', '"proactive_refresh_enabled"', '"proactive_refresh_before_expiry_seconds"', '"proactive_refresh_percent"', '"proactive_refresh_max_inflight"', '"TransformSettings"', '"TransformOverrides"', '"/api/cache/cold/cleanup"', '"/api/cache/invalidate"', '"/api/cache/bans"', '"/api/cache/bans/{id}"', '"CacheInvalidationRequest"', '"CacheInvalidationResponse"', '"ColdCleanupJob"', '"match_type"', '"regex_insensitive"', '"rewrite"', '"response"', '"covered_hosts"', '"default": true']: +for marker in ['"version": "0.26.5"', '"/api/traffic"', '"capture_user_agent"', '"capture_country"', '"hot_auto_trim_enabled"', '"hot_auto_trim_after_seconds"', '"hot_auto_trim_target_percent"', '"/api/config/{section}"', '"ConfigSectionUpdate"', '"cold_on_idle"', '"cold_on_age"', '"cold_max_hot_seconds"', '"cold_on_lru"', '"cold_on_shutdown"', '"cold_gc_interval_seconds"', '"cold_gc_max_delete"', '"collapse_enabled"', '"collapse_wait_timeout_ms"', '"collapse_timeout_fallback"', '"stale_if_error_timeout"', '"stale_if_error_connection"', '"stale_if_error_dns"', '"stale_if_error_tls"', '"stale_if_error_statuses"', '"proactive_refresh_enabled"', '"proactive_refresh_before_expiry_seconds"', '"proactive_refresh_percent"', '"proactive_refresh_max_inflight"', '"TransformSettings"', '"TransformOverrides"', '"/api/cache/cold/cleanup"', '"/api/cache/invalidate"', '"/api/cache/bans"', '"/api/cache/bans/{id}"', '"CacheInvalidationRequest"', '"CacheInvalidationResponse"', '"ColdCleanupJob"', '"match_type"', '"regex_insensitive"', '"rewrite"', '"response"', '"covered_hosts"', '"default": true']: assert marker in openapi, marker for marker in ['"NotFoundHost"', '"not_found_hosts"', '"PrometheusSettings"', '"allow_trusted_network_without_token"', '"include_docker_vhosts"', '"include_streams"', '"include_logging"']: assert marker in openapi, marker @@ -1212,7 +1213,7 @@ assert '"error_log" => {' not in admin_0241 and 'request("/api/config/error_log" assert '"error_log"' in openapi and 'logging, error_log, forwarding' not in openapi assert 'logging_section_persists_error_log_settings_atomically' in admin_0241 and 'error_log_is_not_a_standalone_configuration_section' in admin_0241 assert 'location.pathname === "/logging"' in settings_js_0241 -assert '"RuntimeInformation"' in openapi and '"version": "0.26.4"' in openapi +assert '"RuntimeInformation"' in openapi and '"version": "0.26.5"' in openapi # 0.24.1 compiler and hostname-cardinality regressions. tls_0241 = rust_source(root, "src/tls.rs") @@ -1257,5 +1258,5 @@ for schema_name in ["RedirectHost", "NotFoundHost"]: node = openapi_0241["components"]["schemas"][schema_name]["properties"]["frontend"]["properties"]["hosts"] assert "maxItems" not in node, schema_name -print("PASS: 0.26.4 manifest/package, shared system-statistics/runtime metadata, Settings logging, retained H2, Debian/Grafana/Prometheus/404-host/custom-location/path/cache/dashboard/Nagios UI/source contracts, stopped legacy-renewal removal, session/admin/transport contracts, deterministic package source and embedded SQLite schema-v8 migrations.") +print("PASS: 0.26.5 manifest/package, shared system-statistics/runtime metadata, Settings logging, retained H2, Debian/Grafana/Prometheus/404-host/custom-location/path/cache/dashboard/Nagios UI/source contracts, stopped legacy-renewal removal, session/admin/transport contracts, deterministic package source and embedded SQLite schema-v8 migrations.") print("NOT VERIFIED: Rust parsing, types, compilation, linking or runtime behavior. Run ./dev.sh test.") diff --git a/scripts/deploy_core.py b/scripts/deploy_core.py index 815c754..92fb1be 100755 --- a/scripts/deploy_core.py +++ b/scripts/deploy_core.py @@ -97,7 +97,7 @@ def digest(path: Path) -> str: def fetch_https(url: str, max_bytes: int) -> bytes: if urllib.parse.urlparse(url).scheme != 'https': raise ValueError('GeoIP downloads require HTTPS.') - request = urllib.request.Request(url, headers={'User-Agent': 'RustProxy-installer/0.26.4'}) + request = urllib.request.Request(url, headers={'User-Agent': 'RustProxy-installer/0.26.5'}) with urllib.request.urlopen(request, timeout=30) as response: if urllib.parse.urlparse(response.geturl()).scheme != 'https': raise ValueError('GeoIP download redirected away from HTTPS.') diff --git a/scripts/docs_check.py b/scripts/docs_check.py index ee5ec96..42d86df 100755 --- a/scripts/docs_check.py +++ b/scripts/docs_check.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -"""Rust-independent documentation/Reader consistency checks for the 0.26.4 release.""" +"""Rust-independent documentation/Reader consistency checks for the 0.26.5 release.""" from pathlib import Path import re from rust_source import rust_source @@ -55,16 +55,16 @@ assert '"/docs/content.json"' in admin readme = (ROOT / "README.md").read_text(encoding="utf-8") roadmap = (ROOT / "ROADMAP.md").read_text(encoding="utf-8") changelog = (ROOT / "CHANGELOG.md").read_text(encoding="utf-8") -assert readme.startswith("# RustProxy 0.26.4") +assert readme.startswith("# RustProxy 0.26.5") assert "docs/WEB_SERVER.md" in readme and "docs/README.md" in readme assert readme.count("## What changed in ") == 1, "README duplicates historical release notes; use CHANGELOG/archive" assert "## Release history" in readme and "docs/ROADMAP_HISTORY.md" in readme -assert roadmap.startswith("# RustProxy roadmap") and "## 0.26.4" in roadmap and "## 0.26.0" in roadmap and "## 0.25.5" in roadmap and "## 0.25.4" in roadmap and "## 0.25.3" in roadmap and "## 0.25.2" in roadmap and "## 0.25.1" in roadmap and "## 0.25.0" in roadmap +assert roadmap.startswith("# RustProxy roadmap") and "## 0.26.5" in roadmap and "## 0.26.4" in roadmap and "## 0.26.0" in roadmap and "## 0.25.5" in roadmap and "## 0.25.4" in roadmap and "## 0.25.3" in roadmap and "## 0.25.2" in roadmap and "## 0.25.1" in roadmap and "## 0.25.0" in roadmap assert "## 0.24." not in roadmap and "## Web Server follow-up" in roadmap and "docs/ROADMAP_HISTORY.md" in roadmap assert changelog.startswith("# Changelog\n") -for release in ["0.26.4", "0.26.1", "0.26.0", "0.25.6", "0.25.5", "0.25.4", "0.25.3"]: +for release in ["0.26.5", "0.26.4", "0.26.1", "0.26.0", "0.25.6", "0.25.5", "0.25.4", "0.25.3"]: assert f"## {release}" in changelog, release -assert changelog.index("## 0.26.4") < changelog.index("## 0.26.1") < changelog.index("## 0.26.0") < changelog.index("## 0.25.6") < changelog.index("## 0.25.5") +assert changelog.index("## 0.26.5") < changelog.index("## 0.26.4") < changelog.index("## 0.26.1") < changelog.index("## 0.26.0") < changelog.index("## 0.25.6") < changelog.index("## 0.25.5") assert "CHANGELOG_TECHNICAL_ARCHIVE.md" in changelog for developer_only in ["Clean the remaining compiler warnings", "Update package/source/UI/OpenAPI/release identity", "source regressions and update release identity"]: assert developer_only not in changelog, f"developer-only CHANGELOG detail: {developer_only}" diff --git a/scripts/preflight.py b/scripts/preflight.py index 822c84f..ac33eb6 100755 --- a/scripts/preflight.py +++ b/scripts/preflight.py @@ -75,10 +75,10 @@ def check(root: Path, repair_known: bool = False) -> list[str]: raise ValueError(f"Conflicting Rust modules: {flat.relative_to(root)} and {module.relative_to(root)}") for path in ["src/auth/mod.rs", "src/auth/store.rs", "src/backup/snapshot.rs", "src/upstream.rs", "src/tls.rs", "src/proxy/websocket.rs", "src/cache/mod.rs", "src/cache/model.rs", "src/cache/lifecycle.rs", "src/cache/cold.rs", "src/cache/dashboard.rs", "src/cache/tickets.rs", "src/cache/lookup.rs", "src/cache/policy.rs", "src/cache/fill.rs", "src/cache/tests.rs", "src/settings.rs", "src/compression.rs", "src/diagnostics.rs", "src/traffic.rs", "src/system_stats/mod.rs", "src/system_stats/linux.rs", "src/vhost.rs", "src/web_server/mod.rs", "src/web_server/config.rs", "src/web_server/filesystem.rs", "src/web_server/security.rs", "src/web_server/response.rs", "src/web_server/request.rs", "src/web_server/routing.rs", "src/web_server/fastcgi.rs", "src/web_server/htaccess.rs", "src/web_server/serve.rs", "src/web_server/tests.rs", "src/balance.rs", "src/security.rs", "src/admin/web/vhosts/core.js", "src/admin/web/vhosts/editor.js", "src/admin/web/vhosts/render.js", "src/admin/web/web-server.js", "src/admin/web/streams.js", "src/admin/web/host404.js", "src/admin/web/app/core.js", "src/admin/web/app/preferences.js", "src/admin/web/app/config-history.js", "src/admin/web/app/runtime.js", "src/admin/web/app/settings.js", "src/admin/web/management.js", "src/admin/web/drafts.js", "src/pages.rs", "scripts/mock_server.py", "scripts/mock_auth.py", "src/forwarding.rs", "src/tinyauth.rs", "src/http3.rs", "src/stream.rs", "src/admin/web/integrations.js", "src/admin/web/traffic-panel.js", "src/prometheus.rs", "src/admin/web/settings.js", "src/admin/web/docker.js", "src/docker.rs", "docker-agent/main.go", "docker-agent/model.go", "docker-agent/docker.go", "docker-agent/network.go", "docker-agent/certificate.go", "docker-agent/server.go", "docker-agent/main_test.go", "docker-agent/rustproxy-docker-agent.service", "docker-agent/install.sh", "docs/DOCKER_DISCOVERY.md", "docs/WEB_SERVER.md", "docs/PHP_FPM.md", "docs/README.md", "docs/TODO.md", "docs/V0.25.5_AUDIT.md", "docs/V0.25.4_AUDIT.md", "docs/V0.25.3_AUDIT.md", "docs/V0.25.2_AUDIT.md", "docs/CHANGELOG_TECHNICAL_ARCHIVE.md", "docs/ROADMAP_HISTORY.md", "scripts/docs_check.py", "scripts/web_server_contracts.py", "scripts/rust_source.py", "scripts/rust_module_contracts.py", "scripts/source_module_contracts.py", "scripts/acme_provider.py", "src/basic_auth.rs", "scripts/deploy.py", "scripts/deploy_core.py", "scripts/deploy_runtime.py", "scripts/migrate_npm.py", "scripts/migrate_npm_core.py", "scripts/migrate_npm_api.py", "docs/NPM_MIGRATION.md", "docs/STREAMS.md", "install.sh", "install-debian13.sh", "update.sh", "build.rs", "scripts/swagger_assets.py", "src/admin/documentation.rs", "src/admin/openapi.json", "langs/en_US.json", "langs/pl_pl.json", "Dockerfile", ".dockerignore", "docs/CONTAINER.md", "docs/PROMETHEUS.md", "docs/NOT_FOUND_HOSTS.md", "debian/control", "debian/rules", "debian/rustproxy.service", "debian/rustproxy.logrotate", "grafana/rustproxy-overview.json"]: if not (root / path).is_file(): - raise ValueError(f"Incomplete RustProxy 0.26.4 source tree: missing {path}") + raise ValueError(f"Incomplete RustProxy 0.26.5 source tree: missing {path}") text = (root / "src/lib.rs").read_text(encoding="utf-8") if '#[path = "auth/mod.rs"]' not in text: - raise ValueError("src/lib.rs is not the 0.26.4 entry point; extract the complete package, not individual files.") + raise ValueError("src/lib.rs is not the 0.26.5 entry point; extract the complete package, not individual files.") return messages diff --git a/scripts/release_smoke.py b/scripts/release_smoke.py index 173170a..bf78e9b 100755 --- a/scripts/release_smoke.py +++ b/scripts/release_smoke.py @@ -123,7 +123,7 @@ def upgrade_smoke(tmp: Path) -> None: assert backup.is_dir() assert (backup / "src/obsolete.rs").is_file() assert not (target / "src/obsolete.rs").exists() - assert 'version = "0.26.4"' in (target / "Cargo.toml").read_text(encoding="utf-8") + assert 'version = "0.26.5"' in (target / "Cargo.toml").read_text(encoding="utf-8") assert (target / "data/keep.txt").read_text(encoding="utf-8") == "preserve\n" assert (target / ".env").read_text(encoding="utf-8") == "RUST_PROXY_DEMO=0\n" assert (target / "langs/site.json").is_file() @@ -134,7 +134,7 @@ def upgrade_smoke(tmp: Path) -> None: assert (target / "docker-agent/certificate.go").is_file() assert (target / "docker-agent/server.go").is_file() manifest = json.loads((backup / "upgrade.json").read_text(encoding="utf-8")) - assert manifest["to_version"] == "0.26.4" + assert manifest["to_version"] == "0.26.5" assert manifest["removed_obsolete_runtime_state"] is True assert not legacy.exists() assert not (backup / "legacy-data").exists() @@ -376,6 +376,7 @@ def ui_contract_smoke() -> None: assert "stream-host-rows" not in integrations and 'id="settings-page-streams"' not in html and 'id="streams-form"' not in html for marker in ["rustProxyStreams", "streamTrafficChart", "streamPendingRestart", "chartHistory", "sessions_total", "bytes_in", "bytes_out"]: assert marker in streams, marker + assert '$("stream-listener-add").addEventListener("click", () => { setPanel("settings"); window.rustProxySettings?.select("listeners"); });' in streams assert "/assets/streams.js" in html assert "/assets/redirects.js" in html assert "/assets/host404.js" in html @@ -399,7 +400,7 @@ def ui_contract_smoke() -> None: for marker in ['id="pool-search"', 'id="pool-sort"', 'data-pool-column-toggle="vhost"']: assert marker in html, marker style = (ROOT / "src/admin/web/style.css").read_text(encoding="utf-8") - for marker in ['--scrollbar-thumb', '*::-webkit-scrollbar-thumb', '.backend-table-tools', '.vhost-quick-toggle', '.dashboard-widget-toggle', 'height: var(--button-min-height)']: + for marker in ['--scrollbar-thumb', '*::-webkit-scrollbar-thumb', '.backend-table-tools', '.vhost-quick-toggle', '.dashboard-widget-toggle', '--toolbar-control-height: min(var(--button-min-height), var(--ui-field-min-height))', 'height: var(--toolbar-control-height)']: assert marker in style, marker assert "pool-vhost-disabled" in vhosts for marker in ["locationMatchRegex", "headersVisualBuilder", "headersAdvancedJson", "openLocationHelp", "cloudflare-client-ip", "timing-headers"]: @@ -554,7 +555,7 @@ def source_contract_smoke() -> None: assert marker in admin, marker anonymous_block = admin.split("fn anonymous_allowed", 1)[1].split("const CERTIFICATE_API_KEY_HEADER", 1)[0] assert '"/api/status"' not in anonymous_block - assert '"RuntimeInformation"' in openapi_0241 and '"version": "0.26.4"' in openapi_0241 + assert '"RuntimeInformation"' in openapi_0241 and '"version": "0.26.5"' in openapi_0241 assert 'id="panel-logging"' not in html for marker in ['id="settings-tab-logging"', 'id="settings-page-logging"', 'id="logging-form"', 'id="error-log-form"']: assert marker in html, marker @@ -1011,7 +1012,7 @@ def source_contract_smoke() -> None: assert '.managed-update' in main and "flush_hot_to_cold_for_update" in main openapi = (ROOT / "src/admin/openapi.json").read_text(encoding="utf-8") assert '"/api/config/history/restore"' in openapi - for marker in ['"version": "0.26.4"', '"memory_preset"', '"cold_preset"', '"memory_budget_bytes"', '"max_inflight"', '"preset"', '"session_days"', '"session_lifetime_seconds"', '"accept_local_listener_risk"', '"backend_header"', '"backend_timing_header"', '"cold_on_age"', '"match_type"', '"regex_insensitive"', '"NotFoundHost"', '"not_found_hosts"', '"PrometheusSettings"', '"allow_trusted_network_without_token"', '"include_docker_vhosts"', '"include_streams"', '"include_logging"']: + for marker in ['"version": "0.26.5"', '"memory_preset"', '"cold_preset"', '"memory_budget_bytes"', '"max_inflight"', '"preset"', '"session_days"', '"session_lifetime_seconds"', '"accept_local_listener_risk"', '"backend_header"', '"backend_timing_header"', '"cold_on_age"', '"match_type"', '"regex_insensitive"', '"NotFoundHost"', '"not_found_hosts"', '"PrometheusSettings"', '"allow_trusted_network_without_token"', '"include_docker_vhosts"', '"include_streams"', '"include_logging"']: assert marker in openapi, marker assert '"software_update"' in openapi and '"update_available"' in openapi for marker in ['"/api/certificates/deploy"', '"CertificateDeploy"', '"CertificateDeployResult"', '"/api/certificates/reload"']: @@ -1186,7 +1187,7 @@ def main() -> None: source_contract_smoke() container_contract_smoke() debian_grafana_contract_smoke() - print("PASS: 0.26.4 SQLite/upgrade, local-response 404 hosts, Prometheus/Grafana diagnostics, Debian packaging, cache/dashboard/logging/Nagios, retained admin/H3/stream/TLS contracts and reproducible source archives.") + print("PASS: 0.26.5 SQLite/upgrade, local-response 404 hosts, Prometheus/Grafana diagnostics, Debian packaging, cache/dashboard/logging/Nagios, retained admin/H3/stream/TLS contracts and reproducible source archives.") if __name__ == "__main__": diff --git a/scripts/swagger_assets.py b/scripts/swagger_assets.py index dbe4ef8..de04e51 100755 --- a/scripts/swagger_assets.py +++ b/scripts/swagger_assets.py @@ -85,7 +85,7 @@ def download(destination: Path) -> None: """TLS verification uses Python's default trust store; never executes a shell.""" started = time.monotonic() opener = build_opener(HttpsRedirects()) - request = Request(DOWNLOAD_URL, headers={"User-Agent": "RustProxy-build/0.26.4"}) + request = Request(DOWNLOAD_URL, headers={"User-Agent": "RustProxy-build/0.26.5"}) with opener.open(request, timeout=30) as response, destination.open("wb") as output: length = response.headers.get("Content-Length") if length and int(length) > MAX_ARCHIVE: diff --git a/scripts/upgrade.py b/scripts/upgrade.py index bc38bb5..8a78888 100755 --- a/scripts/upgrade.py +++ b/scripts/upgrade.py @@ -46,7 +46,7 @@ def upgrade(source: Path, target: Path, *, stopped: bool, data_dir: Path | None for name in MANAGED: if (target / name).is_symlink(): raise ValueError(f"Managed target {name} is a symlink; refusing to replace it.") - backup = target / ".upgrade-backup" / ("before-0.26.4-" + uuid.uuid4().hex[:12]) + backup = target / ".upgrade-backup" / ("before-0.26.5-" + uuid.uuid4().hex[:12]) backup.mkdir(parents=True, mode=0o700) installed: list[str] = [] moved: list[str] = [] @@ -84,7 +84,7 @@ def upgrade(source: Path, target: Path, *, stopped: bool, data_dir: Path | None remove_legacy = legacy.exists() if remove_legacy and (legacy.is_symlink() or not legacy.is_file()): raise ValueError("Obsolete renewal observation sidecar must be a regular file.") - (backup / "upgrade.json").write_text(json.dumps({"from_directory":str(target), "to_version":"0.26.4", "managed_paths":MANAGED, "removed_obsolete_runtime_state": remove_legacy}, indent=2)+"\n", encoding="utf-8") + (backup / "upgrade.json").write_text(json.dumps({"from_directory":str(target), "to_version":"0.26.5", "managed_paths":MANAGED, "removed_obsolete_runtime_state": remove_legacy}, indent=2)+"\n", encoding="utf-8") if remove_legacy: legacy.unlink() except BaseException: @@ -115,7 +115,7 @@ def main() -> None: backup = upgrade(Path(__file__).resolve().parents[1], args.target, stopped=args.stopped, data_dir=data_dir) except (OSError, ValueError) as error: parser.exit(2, f"Upgrade refused or rolled back: {error}\n") - print(f"Installed RustProxy 0.26.4. Previous managed source files: {backup}") + print(f"Installed RustProxy 0.26.5. Previous managed source files: {backup}") print("Preserved data, .env, .git, target and other unmanaged files. No database migration was run.") print(f"Next: cd {args.target}; ./dev.sh test; ./dev.sh") diff --git a/scripts/web_server_contracts.py b/scripts/web_server_contracts.py index 0ae85be..84264cb 100755 --- a/scripts/web_server_contracts.py +++ b/scripts/web_server_contracts.py @@ -96,7 +96,7 @@ need(web, 'HeaderValue::from_static("no-store")', "builtin_error_response(StatusCode::FORBIDDEN, &method)", "empty_index_can_go_directly_to_directory_listing", - "RustProxy 0.26.4", + "RustProxy 0.26.5", "traversal_and_symlink_escape_are_not_served", "try_files_rewrites_cache_rules_headers_and_downloads_work", "precompressed_sidecars_keep_mime_validators_and_range_semantics", diff --git a/src/admin/documentation/documents.rs b/src/admin/documentation/documents.rs index 3f1fc70..2abfb1a 100644 --- a/src/admin/documentation/documents.rs +++ b/src/admin/documentation/documents.rs @@ -399,6 +399,14 @@ pub(super) static READER_DOCUMENTS: &[(&str, &str, &str)] = &[ "/docs/V0.25.1_AUDIT.md" )), ), + ( + "docs/V0.26.5_IMPLEMENTATION.md", + "technical", + include_str!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/docs/V0.26.5_IMPLEMENTATION.md" + )), + ), ( "docs/V0.26.4_IMPLEMENTATION.md", "technical", diff --git a/src/admin/openapi.json b/src/admin/openapi.json index 69ad4e6..63001b2 100644 --- a/src/admin/openapi.json +++ b/src/admin/openapi.json @@ -2,7 +2,7 @@ "openapi": "3.0.3", "info": { "title": "RustProxy Administration API", - "version": "0.26.4", + "version": "0.26.5", "description": "Administration API for the active panel origin. Sign in through the panel; the same-origin HttpOnly cookie authenticates all private operations. Mutations also require the exact Origin, X-RustProxy-Request: 1 and a session-bound X-CSRF-Token. Loopback HTTP is the default; Settings can enable HTTPS before using a non-loopback administration bind. This document contains no live configuration or credentials. Object schemas marked extensible are summaries: full configuration validation is authoritative in Rust." }, "servers": [ diff --git a/src/admin/web/app/settings.js b/src/admin/web/app/settings.js index 2315423..8807ea4 100644 --- a/src/admin/web/app/settings.js +++ b/src/admin/web/app/settings.js @@ -6,7 +6,7 @@ function renderSettings() { if (!settingsDirty.has("response-form")) { const server = config.server_header || {}, compression = config.compression || {}, diagnostics = config.diagnostic_headers || {}; $("expose-request-id").checked = !!diagnostics.request_id; - $("server-mode").value = server.mode || "preserve"; $("server-value").value = server.value || "RustProxy/v0.26.4"; + $("server-mode").value = server.mode || "preserve"; $("server-value").value = server.value || "RustProxy/v0.26.5"; for (const name of ["gzip", "br", "zstd", "deflate"]) $(`compress-${name}`).checked = !!compression[name]; $("compress-min").value = compression.min_bytes ?? 1024; syncServerMode(); } diff --git a/src/admin/web/index.html b/src/admin/web/index.html index e879dc9..51b9c53 100644 --- a/src/admin/web/index.html +++ b/src/admin/web/index.html @@ -1877,7 +1877,7 @@

Diagnostic headers

@@ -2676,7 +2676,7 @@
-