diff --git a/CHANGELOG.md b/CHANGELOG.md index 5924ef4..24bf50b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,21 @@ ## 0.34.0 +- DEV 1 KiB reverse-proxy throughput follow-up: identify HTTP/1.1 upstream + idle-pool capacity as a bottleneck using 4-vs-64 live tuning trials on the + *supplied, unmodified executable*. Change the new-vhost default from 4 to 64 + (still bounded to 1..64), preserving explicit saved values and all recycle + settings. Keep resource/FD trade-offs documented. +- Avoid uncontended `Mutex::lock` operations in final `Exchange::drop` via + exclusive `get_mut`, move final owned log strings, and skip reserved-cookie + sanitization when the corresponding header is absent. Preserve analytics, + history, counters, all security checks and cookie handling when present. +- Add source guards, Rust regressions and a measured-configuration report in + `docs/PROXY_1KB_HOTPATH_DEV_0.34.0.md`. This **source** is not compiled; + newly introduced code performance and full protocol parity remain unverified. + No version increment and no claim of reaching 100k RPS / 80% nginx. + + - Follow-up HOT cache path: clone response headers outside the shared store mutex using immutable `Arc` metadata; preserve exact hit/LRU accounting and per-response Age/transform flags. Fast-path direct no-Vary diff --git a/SHA256SUMS b/SHA256SUMS index 6c9679b..0d5cf56 100644 --- a/SHA256SUMS +++ b/SHA256SUMS @@ -2,11 +2,11 @@ 4140a2956264b44f259e6a37fc00ba02097bbe68b09296e04d3d243c1287129b .env.example 9e6356475bf587091bab72246ec9e325b498f7e48a6220e9a18baa50d0a385a6 .gitignore 46bab1d2c2d6e0a80d57a6b232b1ba4c220884b95cd45ddccbafce2aa160cddb AGENTS.md -688f666a676d77847aade6ef97fd82a565b88c9b314050ddeb313a1b3ec4663a CHANGELOG.md +364809f8807bb1fefcf1fdb80abf706e022d54415250b79178fcc9d7b68a3302 CHANGELOG.md ca201e3cd3f9842eae0006d0b40a0a72bcd3d4da6e4e5ecaf200d1b9a1390db2 Cargo.lock fec5f1bae9a59ef1fabd27c5e45d31448dd8f811736eebfa8826b3806a7e3349 Cargo.toml 25c7f3c8162cbf5cc156439774118a81dae9fdc52b611ec7e40c230fc99a772c Dockerfile -4dba0f83d900cbfb131eed06768084f18fbe018952cecfd4857533b36bccb747 README.md +646eeb8d0d421923010f14201de5b8864753511ef715e38af8aad1c78068c45d README.md 1119f4de537b90a6263d93eb1ce2b6b0f233fd7a398f32d758c892ba16ea7dd6 ROADMAP.md da8311e3db945290666324a2f24bf4521b365272d7ac3f862ded1be993eea646 UPDATE_CHECK.toml f645f218dd062bf6cb54a8ee634290562cad364a4cccf09f16e3c8303582af8c build.rs @@ -32,6 +32,7 @@ f27053f8a93d7883025a04922d015e0b697cad653e714be632b757e167297de1 docs/API_ACCES d30551a52ffd34c5963094d2826ba39795210a4e6a4e4d7333066dae7456fc50 docs/ARCHITECTURE.md fb99fac0a490af262a0ecdad593ffe5164004c2166fe7ddd607476bcc56a1623 docs/CACHE.md 9113f3abbfe81bafc4855d8680df8aa2a381ecc358cc3e1a0f78b6b756421117 docs/CACHE_DIAGNOSTICS.md +a8fd061f8bdd920158fa42972f9d26418cbfe9d2cd8757ba1d9d1d12e5c908ee docs/CACHE_HOTPATH_0.34.0.md 3822d72e12f82c37a9e70ab40c7e89e89145ad37f29914e4702db4bf024a5501 docs/CHANGELOG_TECHNICAL_ARCHIVE.md c8e69e492179ce39958cc63615cf46c4ac08cfdb7f3483aaab66868a3abcd687 docs/CONTAINER.md 833ddb12f23dcac796223521388b19c6ec3ea04c5550cf1c5f4ea4eb7c58f3a0 docs/CUSTOM_LOCATIONS.md @@ -55,8 +56,9 @@ be53a58afbeddbd7deb4b5f6447f2dc74db0327839bd83407c20915df98dcfa0 docs/NOT_FOUND e68d5a5cf0991de9308f78afb0264e02979f7463a5f395eb7a6e9ec2bd3a3d54 docs/PHP_FPM.md bc068a176056f5ea4d3b637071e644ed58a2140494c233ef22aa66e9700e3299 docs/PHP_FPM_ISOLATION.md ad6e3f003b820a4f45e30e39577d120a69d167c70910bda4891971759458c3dd docs/PROMETHEUS.md +f13ee0005d57d2576ccc970745f17069096df4afa23d712ea0f748da85433f7d docs/PROXY_1KB_HOTPATH_DEV_0.34.0.md deea89aed410c0619bdbdb12437edc7aff9dca2fec7fdc059e918c649fc36b51 docs/PROXY_HOTPATH_0.34.0.md -f92715fc95ca3b837ff8352e3c899569cdb0f72bcb45c09b050cf1f1ff7ccfe5 docs/PROXY_RPS_0.34.0.md +a7d6189b0e8cb854918456e0063101ee77bfb2419a9ba0430eb0e3f8678c0f09 docs/PROXY_RPS_0.34.0.md 887d1fdcc3b546b024afcd18b1716b8e3a74a3800012bf4bda7a122d2eabe233 docs/README.md 6e46a137b9c88dac8cb9e3fdca877430092392de9913d746278dbff8652460c2 docs/REDIRECTS.md 0dfd0d431c5aedc67abac1ce5de040ffa790ec9578fd7d6f91a987c333d73358 docs/REFERENCES.md @@ -70,11 +72,11 @@ ec7e32fd19e6ba6ed1732f1f3dd92ac0860609e8c0bbd3c1998840cdfb24bf54 docs/SECURITY. 4dcf3243a13d9ae1827b5cefdbb9e27bd6310321c50d4d5934527d44437df6ef docs/SETTINGS.md 8fc112cb45a2f35ef5b0dd4371aa6f43aca4df85db62c6ae02e56d74a3b702ae docs/STREAMS.md 95148bfa1d2f8ff52b591c9acefc6c8992dadc4ebda43a195101d9b31d67a576 docs/TEST_REPORT.md -ec1bf1690edc056068cbdec7244e3a98a2da2da953e0b4399301d76585a69be6 docs/TEST_REPORT_0.34.0.md +9bc103492b1ddeae5d5489a3e47a1c21ff14ec0e98372dc14c6ccb412dfb7846 docs/TEST_REPORT_0.34.0.md cfb452d8496839e832b5fbacdd4e52525b0ecc3112fbb62340c1e580bd5c1717 docs/TODO.md 751c9b13b47d0959a8575d6e82bdecba988b950a374ba0b084fbba08b4b65ebe docs/TRANSFORM.md -fe3ec6ca16ff933239c12dacf39dd7b45717c0551a8b9f6ce601bf78136c9e37 docs/TRANSPORT.md -711c69c9e05761ba5cb96dadc3c368eb2961e2d2287ca039eb49c7fbca0dd63c docs/VHOSTS.md +e6d270894cafe96f8aa9cf58c9609223d03c9bcf6f872adfcbfb767a7b313f0a docs/TRANSPORT.md +811390a8c4ad6439dda4d532e35edc389db70f185ec728604ab35e22033f7e07 docs/VHOSTS.md 09b60fb7b40db4d0139fa2a9e69a2aa9f28d4e61b8643521cfc7e936d7df8774 docs/VHOST_ACCESS.md ca5d1d1d7e8aa372dcd3e2bd56bb7a9b8977953482ece560cfef58a19314242e docs/WEB_SERVER.md c336f998027330c58d5afbbbb3a3a682fd44ae3997643882fe342633822f8bb3 docs/screenshots/README.md @@ -130,7 +132,7 @@ a641bd35400c56f3b68b0a92e97b602d06090f03972ca8f01fa744e90dd97403 scripts/deploy 2cc658faaa610b21b48942c59b955525539ad4503fd60f2a49c7e626a22faaff scripts/migration/migrate_npm.py a459d95bbb0076f33ade8b273b813308167f9d8d45242b309a2d18320ca0093c scripts/migration/migrate_npm_api.py 31ccad3ec3c880119f3b7002f0c6652f8b43634edad8ab3763cb0e4497d0bb1f scripts/migration/migrate_npm_core.py -c79b709fb6f806a772464b709e652e6dfcf498b850281df5e1c594c98392cb23 scripts/performance/README.md +76009d786638720efb996401a8752340d00c21b93c81657fc2d5364431d7a1a4 scripts/performance/README.md 0380406a059ee9ec27473f8a46435f638f73a6dc729382ae1561c08dbf7ccb53 scripts/performance/benchmark.py 9ac220163256e08513597c397c016a48345b114d7876b439259cc310b36c83fc scripts/performance/checks_cache.py f09125d081d0eed9a44fdca75de14e6bbf09dcb00fe1f027ba2270f89e3ff192 scripts/performance/checks_policy.py @@ -159,6 +161,7 @@ e69813fb1d3a4cdcfb7243964cc323fc21a603087bf2e84188fa42b9d3cee4b5 scripts/runtim f0b48ec0cc4411755cc0b4128eebce710375afa99344cb76198cf31074f8eb63 scripts/test_stream_udp.py fafd577ccbb58485c47de35fc125e5c64a3a7628ae40d01d4cd924fce2f414db scripts/tests/cache_age_policy_034_model.py b75a381d1b41bfb2ea7d2ce09728249b5e1465f76d57e2c3f151af72a5ae4d03 scripts/tests/cache_age_transform_034_live.py +45a2f4c271b03f413fd96aa2e8360c7895b9a55d5d8f2d2a0fedf0118933086e scripts/tests/cache_hot_034_static_test.py 6cb79535f742d1a41685f486688dc2f1330ea362e3da1a15d4fa32561094282f scripts/tests/cache_scope_034_static_test.py efb7a1fde2c74f30cd4a1abb88ae07c1cac7378bb33685dd09d52bb30849daac scripts/tests/dashboard_chart_headers_0335_browser_test.py eb2c9e5c968938b6fbe4675b547ba1f537519878b9095e1fea133f4d83f96fc8 scripts/tests/dashboard_chart_typography_0337_browser_test.py @@ -178,8 +181,8 @@ fa42ec0475e4398d647b3c094309b4332cd2b5649db223cae0b8e821d6b44a28 scripts/tests/ 72185f59f31bf04a4e88d53fe2fca52509f3663cb5f40b1d3bc319a5f945ef23 scripts/tests/panel_html.mjs b0136544af717b75df2cb107900ea65c3f945fdd0040369dbb93919008fb954c scripts/tests/panel_html.py 8d1903e2b17b3d59cd0a5bec3e298e468b3d88ed2dda8b724239cc45d8353c59 scripts/tests/progressbar_0332_browser_test.py -f94612eaefb4098e1a4efc0d970ce52a656db239aaa0a012df47567527bf3708 scripts/tests/proxy_hotpath_034_static_test.py -9d28d523aeed722f6ed9217d6eb30530d4fb103e036983d680909a9011dba8de scripts/tests/rps_hotpath_034_static_test.py +2a6e75c05f3860acf65ea8132f0083904478b690145115ec017c120d70f26cca scripts/tests/proxy_hotpath_034_static_test.py +e2a698093c6e0125562eade1ce8098be11105ec24b8fdb0b120b831762072ccb scripts/tests/rps_hotpath_034_static_test.py 5be5cdc60324f4f0f6638640000b888a5babb0a9bbf29511c824a0ba38878c2a scripts/tests/sendfile_034_panel_browser_test.py 978789bfe89d43034dfebddba49b9b17daedb1be031732734f95375e56c78306 scripts/tests/sendfile_034_static_test.py 1bb99b148d0297235b707f16865ca077329246fc19ecbb20a143bdeb56a23f37 scripts/tests/sidebar_nav_0333_browser_test.py @@ -193,41 +196,41 @@ f0a2e3daa0a49aac54723cb5a281360e49a97c076281372c5cca2a85e096c02c scripts/tests/ f55efa99245bbdbc98fe3202e52952d224ac3200612561580d52f6e251810049 scripts/tests/web_server_0330_ui_test.py 0dd1cef06a1c3e1546e2fb9b085bf369dfbed02107b9ab01b4fb4f3b894099c0 scripts/tests/web_server_0334_browser_test.py 22e880e98c7b9d700c7a4c02b9b1d543e5dbd1f4ecdca42813a1083165b32a19 scripts/version.py -4803e44de39b872a5b3b55f9ca9e81c066ba52cb8f6adb879fd57c5f94b93e89 src/acl/dynamic/tests.rs -63efab1e95d41134fc30cc57320c32810bbae9f81a640bdb24b1be2059e63d8a src/acl/dynamic.rs -a22e5ea6381a1eacafe650be0f5cd6e653773e31f6491a562fe0459a309fb7cc src/acl/tests.rs 55485a513e8c4da2a58daa7abcb15b32ed408a5fc062cf23599fb83d16b90cfe src/acl.rs +63efab1e95d41134fc30cc57320c32810bbae9f81a640bdb24b1be2059e63d8a src/acl/dynamic.rs +4803e44de39b872a5b3b55f9ca9e81c066ba52cb8f6adb879fd57c5f94b93e89 src/acl/dynamic/tests.rs +a22e5ea6381a1eacafe650be0f5cd6e653773e31f6491a562fe0459a309fb7cc src/acl/tests.rs +6f5d3137bf24451da05c1db9f0f9e2a451305db17b6bc2590815ad54a6511829 src/acme.rs 587097620b2f25ce7c6f59f907b47660184b095e3040c7615e74509a82e7cdd8 src/acme/jobs.rs 3f158f46e80b403b658b4e9b1e3710e38c70e47b2d476b8223d9c394ffeeba95 src/acme/model.rs -d1dcb7bdfb7cfdc9c3b88cfb6908201c58532bc888744a13f45853079f214659 src/acme/providers/tests.rs c5334de6c732d76b2bea7bfc17b3ac305a250bbaad31a5420d6a7d7abb200449 src/acme/providers.rs +d1dcb7bdfb7cfdc9c3b88cfb6908201c58532bc888744a13f45853079f214659 src/acme/providers/tests.rs 29ff0647417b0f1d50a4cc075ab51afecff9ddf47db3eb7948d51db5a38f33f3 src/acme/runtime_bootstrap.rs 87f64198770ae026c03a242fa542db2590ca734b02e756f1e5c28d66236f753a src/acme/runtime_env.rs f8075a5ef9ae5651d72a33ac0f0fd5b44ad0ae30f6e2d2318412177e0ed837f5 src/acme/runtime_versions.rs e38331a1b186b49fe9d04051de52b603e1fa028def37e4e2f52e386b4d7b29ac src/acme/tests.rs -6f5d3137bf24451da05c1db9f0f9e2a451305db17b6bc2590815ad54a6511829 src/acme.rs b6f38f3fd75d6685bbc882ed1077a38bf495cfcf01c397f69ed9b98be68b446f src/admin/access.rs b4a2a068acfa1143b0032b9cd072c19cf3fdda2580f0b932d11d6368cd2ab3ad src/admin/certificate_api.rs 51f46a2cb3167c4e3a784dfbb59b8fe0e9d5d3d51365b26699498e31d0afb6a9 src/admin/certificates.rs b5f6d49f1add583cfc8cd4aa36ffe4db56dac4de3b151fe8239fe42f507019cc src/admin/dashboard_presets.rs +5e150d4ef0413a2f92db5b6631669933b84d4b4796633d01476c4b39188cd05c src/admin/documentation.rs 958546c43c05bf4bed8121b24db3b3096f9243f3c56a71e1762592b755684013 src/admin/documentation/documents.rs 67b901485d5858d5b5bf78a6260035db32241531d99481754c3533fdf404facb src/admin/documentation/tests.rs -5e150d4ef0413a2f92db5b6631669933b84d4b4796633d01476c4b39188cd05c src/admin/documentation.rs 1ce779b84aa8f47bdb3c34f83593c1f2f06d2235f0319847096cfcd035434168 src/admin/file_log_search.rs ab18acf6fb4ac86fb22635b9219a12dac76d24952c8f15538486267a9b4b7855 src/admin/file_logs.rs c6b552cd5acd9e743c28b1a5564420c214c619fe891ab0561b7d4499aae8d6c0 src/admin/file_logs_io.rs c720a7cad6a15c57b1f2ae7b3e5fbf30a97c64afb9137915f37b23f4e576bdc5 src/admin/file_logs_query.rs 74636c6560618ee95757335452baf8db03394e1ad18acd54252f54b15746b8d5 src/admin/logging_api.rs e552c4b565e3198cc2224d1efa3bef21db02a9872cb80cd96f446181035f19fb src/admin/mod.rs -93f63f7bbde1ed84fc6cfbbb7cf6b96b7d1a1411fd6dbf6d90a3a9070ed9f5f8 src/admin/openapi.json +f571add511ccd00c6b1068851ae32120e3a0b354de8d6dc8c3e762db47e97765 src/admin/openapi.json d9120f7dc61d27621c5ac27ea49815dc7945c44d5b99d208da503818c198f649 src/admin/operations.rs 30895e05c5d5d0a26be29f667e0f6d72f16a96a5c8a98e09cd11d8ef2d7b4763 src/admin/panel_assets.rs 75bbedd54fdabb2b489642a642ee7c6533f69cdacb85e251763a56ba11174d5c src/admin/panel_content.rs 92b3e05f04711d8001b56816405859631d9e917868e15be965c7e76ef4ddef99 src/admin/preferences.rs 4a5cb4c3a3aa8b9a519020854506ce4be5e688a6c4298260322ae641dded7fe9 src/admin/preferences_columns.rs 9a3f13e2477769ae680c03d63336880c3b7b7d5aba4a91e44390a976608b9b1d src/admin/preferences_tests.rs -7a00e4ab943f74d2b1bdcbfab7f9cd3f584e9f59536b4aca6c4c31f5f5508d12 src/admin/public/tests.rs 4a7a2017ba57c9e7a8b29e73764d439f6d03653403909ef198ded8c48d152784 src/admin/public.rs +7a00e4ab943f74d2b1bdcbfab7f9cd3f584e9f59536b4aca6c4c31f5f5508d12 src/admin/public/tests.rs 9926827131254677a848c178c80850b3ca1993c05b4bf913687dc0c7992ad048 src/admin/refresh_preferences.rs daef5e663c1bc99a22b3b8fa4481ae5e4916b91db132c104bc050f51b1fdf77f src/admin/router.rs a40adfbaa908da3ea726d7aa3d45394a70a6a55b6fc0063270ec4d2a2f2026a3 src/admin/session.rs @@ -297,73 +300,75 @@ c13cffe18a616fe5faa5ee945ab0d94d8d392ae8f32474c62fe41010e063ddb1 src/admin/web/ d290c048450655b3eeae7c6ec54a82d645d1965513694ab29fdf7eef796a1abd src/admin/web/traffic-panel.js dfb4ded2fefb90fc1e2d33370cdef10b040a85cb43235ea9dbc1d73bef823a79 src/admin/web/transform-panel.js d816f2f70eef398c18091479320c36d07f9afe07278a250b840ebcdd7bc715f2 src/admin/web/vhosts/core.js -b31782c61da3623389b57fdbba5bd41d2287d45fc172e9c14360a9dd7accf061 src/admin/web/vhosts/editor.js +1f0c6cad61554851b8f10e0a888348c3a2467af188f2369d9236aa2272698033 src/admin/web/vhosts/editor.js 8338ce13b5e3e3f421437631124cb691aeb5b9e17409d256b4b9bcac457b3c59 src/admin/web/vhosts/health.js b3239e67901f1796d7a974ade0796f2e3590ff8064628a5629b78c7f6ce2f32e src/admin/web/vhosts/protocol.js 2170cfddf5c611672de34b0525d36ade8fcbe459cc21269281d6b615d8601b93 src/admin/web/vhosts/rates.js bb93e2017f40e3a45ff7f4ca92e4188bb464f432704b6d2c39da9d9621b7984c src/admin/web/vhosts/render.js 4dfdeb7c73c2775eacaca65fd8ef1dc80b275421b15522d319d338f5b96288cc src/admin/web/web-server-profiles.js fd476445a88eb40270e706814eee50cbfbba4069a26dd843c095367e55a147a1 src/admin/web/web-server.js -b2f948bcc3dbd24952c7b1b02d41d06757f49f0c38a78caf51f8f8a687d8480d src/auth/files/tests.rs 53237ae8b08d261ce21e0aa6fd225bf4f3bb17a37a80529e2a4039d45b13f7c5 src/auth/files.rs +b2f948bcc3dbd24952c7b1b02d41d06757f49f0c38a78caf51f8f8a687d8480d src/auth/files/tests.rs 775178ee5781e64574bdd7c1fb7d64e7e283977fbd9c98c99896532a7f1df612 src/auth/mod.rs c96a87e82ff0c1c9ce3d0cd5135903bb53af78d1c4fb6ebfe5fea503bf5644ea src/auth/store.rs 745226cabb007819370fc6aa680995a03a8a13fa057dacfab0fcc21d0c43bbe4 src/auth/tests.rs +09c3a622a7d2169e49e3369ea5f0f816eab2f717eaf1675c625d518c8f34d367 src/backup.rs 76aa2afe9e7302be39b3512f30d0448d9134300f8ae930d64ada40cf3ad4a8a3 src/backup/archive.rs 732cd4f9ed38ae69f8bbae61b1db8baaa6f86b07ca21c41f24a206a30f0a96fc src/backup/ownership.rs 076350506215faec3cfe7d9de4e60baf29672cc22a41eabe601dcc510c257799 src/backup/snapshot.rs 5c19490d834d9971166b6b784a75b081bb95fd50c8c634ef3c87924dfffd4a19 src/backup/tests.rs f5afae218f3a6f91bc2f1f5a90094630ce5b7ca574de61807b5a317b13937ec2 src/backup/validation.rs -09c3a622a7d2169e49e3369ea5f0f816eab2f717eaf1675c625d518c8f34d367 src/backup.rs +426a946b2c9e244f09f6cbc5f9664b8ad0737529a9bb5a3d549d27196a1f8043 src/balance.rs ca1e03b56a872dca37ed9d05ead41c1538a808e80b09fb9494823c443cd51c61 src/balance/health.rs 109c55f9af8918d4f314f0796e19de06f3129eefee3ef405770b99fc368f2aee src/balance/lease_runtime.rs -554b730c39a935b7da46bfb76b474b99cee07f8c482cb0490f2cf81ba7a51cf2 src/balance/model.rs +aba0f4ae46f05b07bfc434b7174553ce20e5187e1b40a6cf946eb2aefbe1840b src/balance/model.rs 8550e5d64aa6fee442cea3e8e243fc4cfc1e8aa39726bc5cc6b2afa9307e3d05 src/balance/pool_core.rs 477132dd381e23f1be197c32ff58a0925f41d3e6aa63fe77c10973cefb2b76f6 src/balance/pool_selection.rs 8abb6048303ee8c022546a528d5693167766e7450efd8e20f37ec6fd0fa9ef5e src/balance/pool_view.rs -842318f21a919055522f8bd9dae67bf4ec1c8c32dc52314cc048ba1d54a0b379 src/balance/tests.rs -426a946b2c9e244f09f6cbc5f9664b8ad0737529a9bb5a3d549d27196a1f8043 src/balance.rs -9a8858b7ff461a4d961ba701ca3ed6eaec15c3f7f05eef8e0e30edc63617605a src/basic_auth/tests.rs +2ae82db4e3ff2d8df1f6fb3786b54ff61ed4a0e8d725d50fbb080b4fa0e641c6 src/balance/tests.rs 5049d2bd01a9c866f3bad2288d8d594df96bba6045dfe15cd22b4173562b7388 src/basic_auth.rs +9a8858b7ff461a4d961ba701ca3ed6eaec15c3f7f05eef8e0e30edc63617605a src/basic_auth/tests.rs +7def03ace07dc38a4806277d75b6ce673d33ddaaf1c4855fa0a3372be1cf9489 src/cache/cold.rs a9eeb93519aae2de7a1282296ced91d2eb8307cc966f8fbf6085af0fd21b0ad2 src/cache/cold/cleanup.rs 8354ae90c1a0857773a0c6d79427925e0115d94ccfafb809ccc1ebf4ef10f9b9 src/cache/cold/demotion.rs 2eaba3261da2a547e9af91330319a3abd3a8ad8b5b44a337a84040720209017d src/cache/cold/startup.rs e7c7fd71727d542c2df3e03a4a1cba9d839c516963f66bbfde1c29ec81053500 src/cache/cold/worker.rs -7def03ace07dc38a4806277d75b6ce673d33ddaaf1c4855fa0a3372be1cf9489 src/cache/cold.rs d51fa4f320be56c572f767617428c3f3838543cb0eeb7d1f8ae791e1a1ce9a71 src/cache/collapse.rs -7e8741bc21e5ca75f3bf8c5e57c59b6814dc1e5e2e0548963fe35089256772bb src/cache/dashboard.rs -780c2654c67dbe176d8310678e6deec8022bcebfd85b95df7262069ed41f57b1 src/cache/fill.rs -c1357a13658e1ed5158084d3a41ba9ea906512774a5863ce9c56cb508d3fa6c8 src/cache/invalidation/ban.rs -0cc31d8e70fb3774c4ce3713b94ed79c184a8d8f0d38ce66a97724410733e17e src/cache/invalidation/invalidate.rs +0b9b3ff7ff6089bedf1a101c3a015a1a217b8221c6cac9c07a4a8df75f0fbf6b src/cache/dashboard.rs +7eaf3947cfc89cc6ef55a64fef0b3fedf1d9a1c33322aba2b5170c0ea34a5f2c src/cache/fill.rs 675d18afb53f25c56cba49bbb431fa39ecd9d7bdd192c7b39b0698225de7a2a2 src/cache/invalidation.rs -373031e18d0c23d006a31822ef977015c0263637e3da70c1442407f7bfed1033 src/cache/lifecycle.rs -5aa0d9ae53f0350f5cfc4d1694a6faf9eea893460d421344d3bc5d1c4ce66529 src/cache/lookup/hot.rs -1779abcee77600c13050a2882f896a5b35625b1ae53737c2554179492ce0e40d src/cache/lookup/insert.rs -107a589974b9689009a9bbf088818dfaec71cd1aab8676bbc6d0118359a54a31 src/cache/lookup/tiered.rs +c1357a13658e1ed5158084d3a41ba9ea906512774a5863ce9c56cb508d3fa6c8 src/cache/invalidation/ban.rs +3b8f77bde71253a3ca600be5438b7cc72f7da258f3afa5de2cf64553e49922d1 src/cache/invalidation/invalidate.rs +6764e2a20038fb2f75d1b821b5fbe683325d32ed78bc547f064e6e8a245ceec7 src/cache/lifecycle.rs bd831807ca4720b3a41a6ea1d9a6c0ed2d935225e2dacbd9313be064f2e4a20e src/cache/lookup.rs +b52ba2f8a54fdff986bd9026639e7c6d084016046072b698d0278ddfd32e3ebb src/cache/lookup/hot.rs +7c5c7cd2788c09e801ef8aa9598b41d1a9c3991007801a06e962c4368a60a0ea src/cache/lookup/insert.rs +b38f93fa2eac694aac4dd2f1d69b55688928b53b78bf095d479843956c78e605 src/cache/lookup/tiered.rs 58c03fde09e5eab40968679793b364f4f1cf5fd832bd79ebcdc92bb23871ad82 src/cache/mod.rs -875116e319c5bb9d281817fed626a94e468e9e3305f21dac99d3f2535e2fb157 src/cache/model/cache.rs +0c8b0d550e94d4474dcdf991aa0340228dc5f2f904f39350e6e666a16f16fe87 src/cache/model.rs +4862b330040664b663da7540a694da573010eba188b770d27a72bf2b35b327fe src/cache/model/cache.rs 0ec4f6d0adea1ed80a3ca17c68c9c85502491da2904d9d690b4169ab9b025b21 src/cache/model/cold_metadata.rs 29bfce96b2ffd102d9c848c7b717a45fedb9aa44511f62f7a1f28a53dafd063a src/cache/model/entry.rs 88d74fc1b7b9ca15a54a8f4893ad3993105952148bcfee099e9bc9727b622aa3 src/cache/model/http_invalidation.rs -d890524999dc50aeb1dbda90264b46a1d53f08ac923d831b89ba82e4a564d923 src/cache/model/maintenance.rs +ff4dab5a6591b1afc359c6aa2b7e0f5f2be013836bb3c67a24db2eb418ce7bd5 src/cache/model/maintenance.rs 5441fa3a384add28b6fdd15300cf2648f8237dbfc211cad9117754203be76911 src/cache/model/settings.rs 55dcc0ad84d6b73689ba43e759d5685c406419c7733e23e78d5b072891ab17d7 src/cache/model/views.rs -0c8b0d550e94d4474dcdf991aa0340228dc5f2f904f39350e6e666a16f16fe87 src/cache/model.rs +e26dce02df9c043329ca164fed215d271781bce8fb03240f528331bf3df6b9d7 src/cache/policy.rs 989df11e246123f760ef31689370f3500e0913fcc6b70d7ac0c2c95e2f412fb0 src/cache/policy/request.rs d6051d55168fe1db97980a54c22c708f4f325ba72bfc36f35a1851eb5dcc051d src/cache/policy/response.rs -e26dce02df9c043329ca164fed215d271781bce8fb03240f528331bf3df6b9d7 src/cache/policy.rs 7e2bcfbb2b57732cdc704d9df7a9298fb80e735e37984431bc936630e41e7f8a src/cache/range.rs +93bd3e9e5c1a045c784cee0e1fdb9e1c5d862ed70d5d91c54c5a769bca8fd949 src/cache/tests.rs 9183fa8e6086e92fb148fc278fd866d44e3dd988c848a071e32066e44a1cbf0a src/cache/tests/cold_tier_tests.rs -3842cdcf7c3414b9c30f5fbed927b93e835eec3ef96d4c6ee44250038b834276 src/cache/tests/dashboard_tests.rs +334893037a278ca2a6f0b8b1a32fe0e2d286665f24db78d787bfe9425dc5a88d src/cache/tests/dashboard_tests.rs +a0a23e7ec1baa403524811f8096bbc026b1027b7b1b79357ad920b0a4be770b7 src/cache/tests/hot_hit_034_tests.rs d7a02eb7bad37e6a5524600aabb5e60ccf50e26c7a487e2806891c9d8acd48f3 src/cache/tests/http_invalidation_tests.rs 1659ffd8d227d2ec8b98e6a5e06b6143e6ac4ac06ab423c184980abcb47085da src/cache/tests/scope_tests.rs d4429cf4f35fd8d0082108fb62602fde72c9c2fc6edfadfe3268c6a8214a8f89 src/cache/tests/tests.rs af28534625859ff66011e10c54cff8f82c2cfa1c173c4d99b89c27c1437f0659 src/cache/tests/v022_cache_tests.rs -7ad96b3baae36ec49c90d03b380e749944fb3d54abb045c90db3a35f6b89b1c1 src/cache/tests.rs -22f8f16cf7383c579b19810819030072fc827681478e17068dddc85da8dc53ad src/cache/tickets.rs -4bdbde197d135fee8be20e93427eba8ca7b60b801717ed7ca734319bedb6ef05 src/compression/tests.rs +f76b41a2b0ffa5699a456cc2cfa0b063098c90552fe01e0d05e6ee91a01cbe57 src/cache/tickets.rs e0146bf5d2e2e33aedcccd9205e5bd457559c9d77dc7ce266f8c165d1b867f0f src/compression.rs +4bdbde197d135fee8be20e93427eba8ca7b60b801717ed7ca734319bedb6ef05 src/compression/tests.rs +7bc8285cb2012506fd1a38a71dffa561f885f4ab65a9b2a7c8344319e3cd1cf6 src/config.rs 56b3d37e7447995bec2fdda1c17dcc74b60958a63ca88b88ff57e56347d8b0b9 src/config/backend.rs beb831a208c4e5f7ebe8327686b1e0edc66608c7032f895cb4fc3366b189aae0 src/config/compile.rs dfa89a9e214d0b33b4efce8fa678f1fec17d17656e203acf84dfd09ce33868e0 src/config/internal_routing.rs @@ -371,58 +376,58 @@ dfa89a9e214d0b33b4efce8fa678f1fec17d17656e203acf84dfd09ce33868e0 src/config/int fc993c356386a9ff17379d48a70ef388df5b2b10ca9ee04f06342f68f9dbbaae src/config/routing.rs a7ccffdeeb258adae41c616022ed0181cf590d708d305d48c63317e4a3f68699 src/config/snapshot.rs 41a4fa4f9a919a8c848ee01d01423d82a136790c9d74f27319c1e5a6d9f18097 src/config/tests.rs -7bc8285cb2012506fd1a38a71dffa561f885f4ab65a9b2a7c8344319e3cd1cf6 src/config.rs +23541660151d9005555a07db6d491455d61b185f0cc70c3ec3a0bee2aef08dc3 src/db.rs 30f0b7269224a64e3f1ec9e6fbe9e27ddb1d308dc84cc9882e50545cf612695d src/db/certificate_api.rs 20ba52d3755c359d670968efa53b0604ff7cbed63a416f9f765b50a1f45074ac src/db/dashboard_presets.rs 2ff744223934685439374572b83fd639bb3eabdbac168bea4a6501a6e9ce0ee0 src/db/history.rs c05a02618d476e4670b4f9930555f199cac776cdf09edb8fcc1a675695b8f99f src/db/tests.rs -23541660151d9005555a07db6d491455d61b185f0cc70c3ec3a0bee2aef08dc3 src/db.rs 19ab6c3ae37009c544291cb0b65c1bb9c721e168f95c1ed3fa88155aca7463ad src/demo.rs e69031875ffec32c9f548c43bed5f1a5c4c626e9568c9173e3b093f9a8b73036 src/diagnostics.rs +b45d6040810c93ae2acb04ef6b0a59c189751edf9008cd81a4521c9e04e7f07d src/docker.rs 93a8a3f6ba12761ddcbd19f22f32fb2c0e6948b660fb774ddd7ebdba9b6562a5 src/docker/client.rs 4c2c988191a97f81568a8df64af772463d010844f1abf327871901cdb32d4336 src/docker/model.rs 5f4610c59b2d4ff6a205a2d9ae11bc84be689b2a68302459f546b3f43e53593c src/docker/reconcile.rs a12c47df4b90b6fc36c978a42477e6ddffbbbf69aed7252101c2fd829709bd6e src/docker/tests.rs -b45d6040810c93ae2acb04ef6b0a59c189751edf9008cd81a4521c9e04e7f07d src/docker.rs -057e652f216a1478638cbb53b1c64ac88c7f413a65825caacbf893c5af004a63 src/forwarding/tests.rs 2a02ea2e010cde1b1fe99b2e6baa80ea344ea6b332dbb3c4be795b71541f64a7 src/forwarding.rs +057e652f216a1478638cbb53b1c64ac88c7f413a65825caacbf893c5af004a63 src/forwarding/tests.rs +af7a4e91c32ffbe4701c8c06e48ba3f8bbbe55e8b9e877aecb30ccdf858e9e8f src/geoip.rs 80850f7acd1ed4c0048b065e9e81740869a8efbb0d9b5d2e83d8ec7fbc494703 src/geoip/mmdb.rs 06aa056d789742cc11c8826c338d985e6a6fb22da6c3530937eec38e35478034 src/geoip/mmdb_tests.rs d3dc58628683472ef4d205fa5c42f0b7ef83cf90846146d96941cd3b36a40766 src/geoip/tests.rs 70091bdf6f38f03b6df8c8c4407c300677e57f293130122503f936500963d37c src/geoip/update.rs c1b49bef28d87712e4c46138e70b52c4bcfb1a00196579031fac043d0b4aaa7b src/geoip/update_http.rs 9a912dad0b8d1e10410fd95d0da3684656092ef85cf8b23eda4ffe7fb92921d8 src/geoip/update_tests.rs -af7a4e91c32ffbe4701c8c06e48ba3f8bbbe55e8b9e877aecb30ccdf858e9e8f src/geoip.rs -e4f07bfb7eb75b6897ef812870caff158679a3046d64582428abe8c6df490dbe src/headers/tests.rs f6ebafafa82391f8cb3b5a09331f3762b6ca5a9fb64bafb5772cde3ab814dfcf src/headers.rs +e4f07bfb7eb75b6897ef812870caff158679a3046d64582428abe8c6df490dbe src/headers/tests.rs +9e21edc67a14ef8a2ce3dda0ed18784d0fd0be305973e5d216058b7ac802c6cb src/http3.rs eb57117938a447d9a6c2ec1806ebd9fecc640a68c88950a8b35fa9bad14d0dc6 src/http3/body.rs ed25da264a2d25b40c4fcddc97c626a3a43d4f3a9be6c6d31af58b9e4925c198 src/http3/diagnostics.rs 37f54961d8f52b79a75fb2be31e81f4fdb1e66b06350345c4483d6197b8a0bbc src/http3/identity.rs f2a8c2a98f4ccfb708f9d75a48ec7b351232be9b8a4364b7e63ba14d28eead7c src/http3/settings.rs a31db7eac12b578b1eb5a74fae98bbe36312da95b7d7173135dbc41fc454da21 src/http3/tests.rs -9e21edc67a14ef8a2ce3dda0ed18784d0fd0be305973e5d216058b7ac802c6cb src/http3.rs 68fb5ab6a889995a66ad12cb6acf88c5d04f0aca572e2ae15f1a9cd171a5f24b src/lib.rs +2551189a3e5701371026c9abd2c5d44d37495f28fb67e220180421bfd315e3dd src/logging.rs 18c8d74c21a47f234be93551d7264b1f8f8c00d1bbfbe555d91618c58cea0740 src/logging/error_runtime.rs bc3873c6f22d1ee7fa76ae586547c9867e6eeaec8266e3ed1f529c87108df2b6 src/logging/format.rs f5815d778cc1785723faed4abb15f9880f22b6524b5289fe1e7158905aac0986 src/logging/model.rs 42fef80af50735cd566c6801dad86ba81be98cf4a8ec7d45c2ea26f53f556a22 src/logging/runtime.rs 7ee1eb1d3b52b4c14303f8ca14a1924d4d6bbe75b2e43ce3ca47d7958f792c7d src/logging/tests.rs -2551189a3e5701371026c9abd2c5d44d37495f28fb67e220180421bfd315e3dd src/logging.rs +3836ed14b6710e183f048ee4d7807a35366c27a27338057fe4a2811129b63302 src/main.rs fc8e99eac83c083d65101f6402aacbcc8392d66508c31566a50de3ebcb12e7da src/main/admin_runtime.rs 42a9197475823f67c1ca762951ede5d7a2f10124bd6ed4d1a3365f4297be894c src/main/bootstrap.rs 5a98d0e249338e73aa57ae2e352dc16db2f79c2d042c1544ce1c2022da76a31c src/main/proxy_runtime.rs -0a6578a0f4023b9f8d73043bf942dc5e096ef9afb8c0d2f131c14f65d08ac01d src/main/shutdown/tests.rs 4dd7c1084a6214c0f2513ebf86fe8ef144470695557772bfe25979edd64491ab src/main/shutdown.rs +0a6578a0f4023b9f8d73043bf942dc5e096ef9afb8c0d2f131c14f65d08ac01d src/main/shutdown/tests.rs e5c2e9189777725f4afa1c3c052e4f75047ec3f2f486630d990f5d3c194bcc96 src/main/tasks.rs -3836ed14b6710e183f048ee4d7807a35366c27a27338057fe4a2811129b63302 src/main.rs -201ab702722d6d21585fe8bb49939150d61bfac7ed8dc198b98c2cc6098ffb5f src/metrics/global.rs -a54b5b34ea65f29723b89b81bf7968a238e8247b9c9760f3430d3504cb1017c9 src/metrics/vhost/tests.rs -49b11df65b4fb0b5b727f9f867436584680b45e3f4fbd53f74bc0cab8b9a88ec src/metrics/vhost.rs 49d7e104585c8791ac9a203dddd95802784b68c0ba65d6f90f3d57154b4c7871 src/metrics.rs -c915d30bbd7032d867e7916b4cd45f3bb7e7604d3f4558f4383c59394b4300c6 src/not_found/tests.rs +201ab702722d6d21585fe8bb49939150d61bfac7ed8dc198b98c2cc6098ffb5f src/metrics/global.rs +49b11df65b4fb0b5b727f9f867436584680b45e3f4fbd53f74bc0cab8b9a88ec src/metrics/vhost.rs +a54b5b34ea65f29723b89b81bf7968a238e8247b9c9760f3430d3504cb1017c9 src/metrics/vhost/tests.rs a4702c95c7e5077c2ccff86e2e3216e1da6ff9ee4383ae199a0aff2f78db325f src/not_found.rs -da40e8ece87245efc49a0c4e750526b1d19fd97565856bd5caf641fcc1dfe18d src/pages/tests.rs +c915d30bbd7032d867e7916b4cd45f3bb7e7604d3f4558f4383c59394b4300c6 src/not_found/tests.rs d66936cc15fd5d56566d40fa8cab93f80d94b05f10ac44478a30f63572a95e32 src/pages.rs +da40e8ece87245efc49a0c4e750526b1d19fd97565856bd5caf641fcc1dfe18d src/pages/tests.rs +0dba7b6a33866cc7bbe05509b01961e545892645d1dad4eb88ac8a4bec65e3bf src/prometheus.rs cc6fb14351b009a16d07ed0f412c2bcc68cd7e551421aea03d8d97ceec9bee40 src/prometheus/core.rs c46882ed26742d93806a976257674326e105b8ca1fc23f5ca81e317b268057aa src/prometheus/docker_misc.rs d3c6b08088df0003144544936a55e2a3661aac85292821b594f00adfd19a2951 src/prometheus/model.rs @@ -430,13 +435,12 @@ d3c6b08088df0003144544936a55e2a3661aac85292821b594f00adfd19a2951 src/prometheus 028e1dd9f2ec2afaf699a6b21c2d4b0d96e76f11f5e4ed009c233dadf0f3be51 src/prometheus/traffic.rs e03f0d6b3f35dae6b98c394837aa0d17e4d73a8306767b4c607868bc00c30286 src/prometheus/vhosts_backends.rs fb2d8d45cd2e947f783eb981b37fa418c39fcb327a3af17a648fadea7f37f888 src/prometheus/web_php.rs -0dba7b6a33866cc7bbe05509b01961e545892645d1dad4eb88ac8a4bec65e3bf src/prometheus.rs -f0f3e21350e4fb15fa2ae282da6b290857dcd6716e62b183e9ecb728b7c24c63 src/proxy/body/tests.rs -ea38488f8507609dbf6e5ae6e9c10f4045bc424a42e8eb11b608538a2d55d6ee src/proxy/body.rs +fc234886805226f744306c83df859805c444edf102dc4eb14f443afaa4b3362a src/proxy/body.rs +c9b76abd91f0dfe81e07073e89d35faa033c19e11fa88b223f075428542284f1 src/proxy/body/tests.rs b88d1d7a6837a2a470e5863f1f3247878daee62791fc3d8e72baeb66469bdfbf src/proxy/cache_helpers.rs aa49c9928bb91e3d5bae0d340d88396a0417b9edec6192d41e1403533319a897 src/proxy/cache_http_invalidation.rs -3404b03096862de1050088f62cdd811ea1ab61d191f902501173107f81f23b9b src/proxy/cache_plan/tests.rs 676c1b325fd8e55bcdd86451c7d1d8b8d347ca00e8da6b3e5b148a58c376a9b4 src/proxy/cache_plan.rs +3404b03096862de1050088f62cdd811ea1ab61d191f902501173107f81f23b9b src/proxy/cache_plan/tests.rs a8848cbdf85368548b003af2b43823c453866c472af4c7d2ff0ec7da14c44c8d src/proxy/error_fallback.rs bf2e6bbd64fb45fceed54af0bff1c1e00da22b79c64dd8f5c23d2af0dbab0b7d src/proxy/forward/cache_lookup.rs cfa941b60b5d167ec9d8e2566ea3342b588d1a9078a6ca711ad6062ddf00fec9 src/proxy/forward/response.rs @@ -447,123 +451,123 @@ bb24da9c9ab986a9c4d4144d4d1be0f661561d4afc755f298b58bc679b182850 src/proxy/forw 11dccc239ac8a8e9ea06e884c2f2658f86b7807d14a59b8e052bc7dd75e86d63 src/proxy/forward/web_source.rs facde401ba5bcbafdcea5524f236cfae37eec11144ceeea879e83314c84bc97e src/proxy/forward_entry.rs 9b25f5e3ea4443a63ee6f45d12e1957dd316fe8e85325fc00ea416faaab1025a src/proxy/h2_graceful.rs -5cb7522ceb9a9f083a15596ac4898559295e38d1138c80099577211de8a868ec src/proxy/headers/tests.rs -c438066616527a3108f2ad53e3698ae9b2a80961714394cdd0a450c92f99d992 src/proxy/headers.rs +3e856a2e3e2236caebf4a7e7e8aba229a529cc552c1fb73e4b81c38784ecad26 src/proxy/headers.rs +02542edb25302ab4778d5f84f900b546ed126be56e4bc9d3580703edea6f492c src/proxy/headers/tests.rs 3f25429418941eb72c3847125340db74684ad316eb278ecf658953026fd41f4f src/proxy/mod.rs 55133ceace2e5262d9c54fa41bea099a27b817d1e09c1cd0e2493fd9cee4da38 src/proxy/redirect_helpers.rs -d2df55b6ccfc7ceb8a3d2c49f664acd183448e3d932d5399d6692e87f79a094b src/proxy/request_id/tests.rs 96da894a86c05f8f467bf83cc23e56627ed3f9f490ffc936872d70126c8ecb41 src/proxy/request_id.rs +d2df55b6ccfc7ceb8a3d2c49f664acd183448e3d932d5399d6692e87f79a094b src/proxy/request_id/tests.rs e56c65c85e42ee4fe6adf3655f3b2d176798e37c648db6bfb8e1602300b723eb src/proxy/tests/authority_tests.rs 1aa9bbbfb2659facdaeaf185e11221b1c8cd5fe6e23c7c1dacd3aa55e3db4fcb src/proxy/tests/cache_fast_path_tests.rs 0f2eacadf1447db8aa1c1a78005aa262e0f747096bfe7e0a0e41a2cd31a0d17f src/proxy/tests/h3_navigation_tests.rs d134b0eb617f82f9971b3f3461379ea37c57bd0079bf54748d0c434b2ef1b475 src/proxy/tests/http_invalidation_tests.rs 7789a80202d606dcea3776345464a5487bf6124e4878bf8c94db91b67f0d4eb8 src/proxy/types.rs 1cbca5fbe91f40447e9eadc349e2d56f220119d14504f07ce90ed70f945a767e src/proxy/upstream_helpers.rs -d7b4b809b12ee89293df45e9a64b1c9981fb3f89deaab3762f4a3ad3992dd7b1 src/proxy/web_cache_revalidation/tests.rs 2d9142e3ae95895b5271b4009ab48236a3a2074ce51179c021193b35777560e4 src/proxy/web_cache_revalidation.rs +d7b4b809b12ee89293df45e9a64b1c9981fb3f89deaab3762f4a3ad3992dd7b1 src/proxy/web_cache_revalidation/tests.rs +69f775f6746b4c6d729dc10961dbef54168846f4ce9cf7fe453ab5a2b879c9b8 src/proxy/websocket.rs d866e7e72dee6ff54c2418c34e9899cbcd7e4e027d9cbe2b625044dc9062e4ee src/proxy/websocket/handshake.rs 7e9c4d4c207badabf90630223964bb2ad641f06d4149843cab751f192b8b4adf src/proxy/websocket/tests.rs a44421714aab37f7ceda19e3ec2512c645d2a3ce5dcb3da5bc7a0d87a442d6a8 src/proxy/websocket/tunnel.rs 15fabd38576b61f650c039acdbf7ac5a5bd24330062475b94315285b2dc258b6 src/proxy/websocket/validation.rs -69f775f6746b4c6d729dc10961dbef54168846f4ce9cf7fe453ab5a2b879c9b8 src/proxy/websocket.rs -e7e3a898e2c769b1ef11e58a13c1053104ada93dd694f8a03ea4b647c44c7d69 src/rate_limit/tests.rs 545247eb00b0116efbd4cc913cc251195a55feded1530e0d8d8945abbae78039 src/rate_limit.rs -811c83ae9fd0f5a13d35b5443cd37843f82b9d600bee4bb136ba9b87732a5347 src/redirect/tests.rs +e7e3a898e2c769b1ef11e58a13c1053104ada93dd694f8a03ea4b647c44c7d69 src/rate_limit/tests.rs d40ad63939097d2b91339127d5835a74b618d83b7ba31db0c512f05a82107d6e src/redirect.rs +811c83ae9fd0f5a13d35b5443cd37843f82b9d600bee4bb136ba9b87732a5347 src/redirect/tests.rs +d0939e1b0829c25356a0b67ecb3a178c74936dd07baa15fee24eb32544db6cad src/runtime.rs 8d0d7b01871c8c588c40a54330a1053c85024655fbe38516ca6c94c3c19a8956 src/runtime/certificates.rs 2ccafa8a5a8462417f65d05a0c6c42f294afa4ad1067ea0b93623181546d1f96 src/runtime/constructors.rs 92b4b284f1b69dca58e4e3f76199f0aecc397eed26d10123b427af1bb8a4a57e src/runtime/docker.rs ee2050b9f8efb45a209c91d76043a1ba29c4289978896aaf7e7d344d48fdc369 src/runtime/tests.rs 779137f320133ec96f73c8b3d357ad4f0b825ee2367e9e8300f4f143b38eecb7 src/runtime/types.rs 5947afaf7d070ea2047eb7969a8e0d84f981e91ace283f6506cf7685fb8afab9 src/runtime/updates.rs -d0939e1b0829c25356a0b67ecb3a178c74936dd07baa15fee24eb32544db6cad src/runtime.rs -6dca8da072a3bd610704a391bb6e25c9042971f4ebc60edb47665ce1d74cbc58 src/secret_store/tests.rs 208a378b14ca80e1412ffa19ef1b140594182971e2e797ee0bb95bcdb8404da7 src/secret_store.rs -0e5fc2aff856bf6fd959cba12b5ddd1e3b3cbeb0fbaadde906c811cdfafdaae7 src/security/tests.rs +6dca8da072a3bd610704a391bb6e25c9042971f4ebc60edb47665ce1d74cbc58 src/secret_store/tests.rs 6fa1d8c352bce7a16ff0208bc4cdbe80404715df0aff4ed26910a5df57cbbcd4 src/security.rs +0e5fc2aff856bf6fd959cba12b5ddd1e3b3cbeb0fbaadde906c811cdfafdaae7 src/security/tests.rs +98c52aa3b50d2e211ab752ccaf353c9a8c1500a87f9c1684b5dd0ba9d10e4619 src/server.rs f2f6196632b2fdb2444189624f961edaf5bdfff57f700b0207b57e2491c1daa5 src/server/http.rs 050c48ea1127aa87dba92c074ab84e8346e65dbe253621ea53f8ca2f68d791ab src/server/http1_connection.rs 8c6ca5eaffb9acab57199d0349722703b903cfff3752baad2cf2596bd51188de src/server/listeners.rs 4424a99b0b688d1119ee25626778b4804aedfaa0799a4a9bc0ee99bc5c7ba96b src/server/sendfile.rs -e9e478cf45b88994eaffd115f51764b6b07852ee3c941cafdabb20584d3dabc0 src/server/serve/tests.rs 71899a9b1897fa22ab9e8eb6a670054a6d382bad78714006b9b218d07ba99902 src/server/serve.rs +e9e478cf45b88994eaffd115f51764b6b07852ee3c941cafdabb20584d3dabc0 src/server/serve/tests.rs 960a82e02f09d75141fe3c1eecca915b66f17fdc8167196cd2fe21d5e6859376 src/server/tls_runtime.rs -98c52aa3b50d2e211ab752ccaf353c9a8c1500a87f9c1684b5dd0ba9d10e4619 src/server.rs +73ec453ac2850f6963f5bc33401cb8c92aa26d5123f15d68e6633860d91f265e src/settings.rs 240ecdd70e8662ff3b84c21830dc0cbbbacadd755d56146e54214bc2887f068c src/settings/public_origin.rs 1f1121c3562c8f8f3fdee2113be2afffb8849be2d303e4c4409f87478b6e3307 src/settings/tests.rs -73ec453ac2850f6963f5bc33401cb8c92aa26d5123f15d68e6633860d91f265e src/settings.rs +9dbf814870b8636770f579c3d36d16f5b6afe8bc66adfad356c26d7ae7dbce45 src/stream.rs 254840126be2310426f6332f5efbe98147d9d8de1999731f40a3d13325c1dc6c src/stream/health.rs bdc56be7dae85a97a4d5b8d46ef31ec4177292b1cadd507fe423b6d4ee1403bd src/stream/model.rs de138a4ac68bcddba3a4f17ceba008bab643359d76a68726a755069f19334bed src/stream/pool.rs 6ec42b8647c95a0c2025462e0be29c71481ce1c3b1f4d4193926471f1cf06be0 src/stream/runtime.rs 9346cbd71e006e41a7188f28eb86f9b00bac822e4cb31c76c8d6d2ec5d4c4711 src/stream/tests.rs -9dbf814870b8636770f579c3d36d16f5b6afe8bc66adfad356c26d7ae7dbce45 src/stream.rs -d9123c623e2a97d09e41edaa29993b4b2c8cba39a3abdf2b48a205aa9a9c2939 src/system_stats/linux/tests.rs 3070d78a7b88c2e47ed59960fa35e7d220a4cd7d78e48f6c6d2bcc5ff77f9620 src/system_stats/linux.rs +d9123c623e2a97d09e41edaa29993b4b2c8cba39a3abdf2b48a205aa9a9c2939 src/system_stats/linux/tests.rs 751d59582fb92c84e0c0cc7c0855c9d0a545805c9ba3be61826e50fb96c297ed src/system_stats/mod.rs 050aa831b1012c4aaade63863f433f01bfacf5d3f95787e57975572116a30ab2 src/system_stats/tests.rs -0e1d87554db55e724f30c41ec4a5c80bdb8fc9c8cba8700ac509864d4abf8871 src/tinyauth/tests.rs 7467d83066bb6986d8c9103597f7a7617ac677579ed46d573c573ff6ca57bbd9 src/tinyauth.rs +0e1d87554db55e724f30c41ec4a5c80bdb8fc9c8cba8700ac509864d4abf8871 src/tinyauth/tests.rs +1084cccd9de28acd6cb0f0813de7c0953910f51726f73f4acdb2e3ada4593976 src/tls.rs 4972a436f8878dec5f9eb8ff17eb82670b0bfd9e94e821c516575479f5fc1919 src/tls/certificates.rs 436575144aa352498a4696f12c2258bef3a898f3f50e6fbc6d67c3b93afa099f src/tls/external_paths.rs 3e6947dde167f82a5efc407ccf9bd4c9f5b26cc8633d1418a10284bc1a1503d4 src/tls/server_config.rs +31c0f51a3a0bab433f438c3ba1b1cdaf3c63fae6086e7d99b3464a537f75a5e1 src/tls/tests.rs 2af2164ecdf2b7fd9eef7c6e358dec053dfac9aedaa501dbb75df742d18638b2 src/tls/tests/acme.rs 93b359e9defd62506729bc90e56c96783e2f14dd477dd67f337ca83149da7168 src/tls/tests/external_paths.rs -31c0f51a3a0bab433f438c3ba1b1cdaf3c63fae6086e7d99b3464a537f75a5e1 src/tls/tests.rs 10c4a187e3aeb0c72a8c8968ea0cc8bfae4e3cb2f3d834ebd3da1056c4171ec5 src/tls/types.rs -1084cccd9de28acd6cb0f0813de7c0953910f51726f73f4acdb2e3ada4593976 src/tls.rs -36301bcbd20b557dd3d58e77a9175f3581947f577c0bb0b972899cec6786b03f src/traffic/tests.rs c2f802d95da4332fb8480e83f0c7502334457b3408141c1c4516c9ba320a0463 src/traffic.rs +36301bcbd20b557dd3d58e77a9175f3581947f577c0bb0b972899cec6786b03f src/traffic/tests.rs d88c92f5a2a7773bc3e715d24039db35da4df53881f1a0859eec819b96f06d3b src/transform/apply.rs 87f8af5261d79072f8215f1fb8a90715a58e7626544fd8176ce840e3111bdb92 src/transform/compile.rs b2c5236589093454ec60984b785ad6a4af6149d47f6db37d8e08c17fec7a2c1b src/transform/css.rs -aa99b0d3029ef92c78371cb90e11f2026cce890d1be8e10ebd7fa9bc5cb13287 src/transform/html/tests.rs 5478670cef87777b14a2dab308f5a9182df56d7ea2f5625bdc94aa7e3d661503 src/transform/html.rs -cf5195ab6bacccae0082da7b3f1bd0382b73fdeb3607f4ae569ca6daab9d10d0 src/transform/js/tests.rs +aa99b0d3029ef92c78371cb90e11f2026cce890d1be8e10ebd7fa9bc5cb13287 src/transform/html/tests.rs a1d2fec07617c8a8dc425bfaeaf77c844152a0a174568a88a5baf4c317cc6c5c src/transform/js.rs -216e24e29ea87be4a124f95f898e155f127fd959d7d5d9b30f8cd0b2b5018f30 src/transform/json/tests.rs +cf5195ab6bacccae0082da7b3f1bd0382b73fdeb3607f4ae569ca6daab9d10d0 src/transform/js/tests.rs 226ae561dc7b0243c04e55e28cdfd2b76acd48cf614d1919b81c196660b03cfb src/transform/json.rs +216e24e29ea87be4a124f95f898e155f127fd959d7d5d9b30f8cd0b2b5018f30 src/transform/json/tests.rs 6a8c28be93fb590942493c075b29ace1527981542bd183f232aa82b62e951eca src/transform/mod.rs fde2fa3aa94b30d8536afec1c11348cfbd922d0b5ff89e91d34266e8e3863e26 src/transform/model.rs -0f53c64f442390ee20a59087a10f8f9ffb58053263e9aa848ddabfae1a6f3f51 src/transform/svg/tests.rs a4e1d2aa2913587c250f251356431097b76995aee6e8bf9e35c4978a95491de1 src/transform/svg.rs +0f53c64f442390ee20a59087a10f8f9ffb58053263e9aa848ddabfae1a6f3f51 src/transform/svg/tests.rs d1f3f53fedae0d8ef69eeee457f7d30ed5a670a1ed4ced60683400ee46680260 src/transform/tests.rs -c42d000d1d576721af3ffe930589388693001b8113554a7658f6dcbc665b5d1b src/update_check/tests.rs 6146c59f36cf419623747d497b3de685da6c84964df43317bebdcb21deb9ee09 src/update_check.rs +c42d000d1d576721af3ffe930589388693001b8113554a7658f6dcbc665b5d1b src/update_check/tests.rs +92efcdaafb9f5a8514daf63d7fcde29be977d7bdcd90162eda0ce00d6967ffbd src/upstream.rs ca695e246bee5389b3757fe8588e48bff5d0ad473bc8588ad4ba7b52c99d7dfa src/upstream/client.rs 56c8a9d1c801be0f41b35c75cb42716c46976951948009c8707122c0a6a1eb58 src/upstream/client_tests.rs 75fef0a488d3f3dabfa03c2eabc5995442dfb3c9a1fde8eb6653a124dda25d43 src/upstream/protocol_tests.rs 8a112154b9631f62a54584302a3ff6a64e4f177ce79aba678b4cb23e466c6ea3 src/upstream/tests.rs -92efcdaafb9f5a8514daf63d7fcde29be977d7bdcd90162eda0ce00d6967ffbd src/upstream.rs -6d7cb73de7d8c6f3780736480f5f81ef08813f4626fd5ed494aca0552cf214a1 src/user_agent/tests.rs a6b4905c245a22eafb1aa535d303d0fa24e4353db94e1d67fd42b825bf8c5adb src/user_agent.rs +6d7cb73de7d8c6f3780736480f5f81ef08813f4626fd5ed494aca0552cf214a1 src/user_agent/tests.rs +3aa1b07cd26d4a5b9e5e94d1d6a712ef1397d827e7f1e8c01f7195b98d2c5f67 src/vhost.rs 6678192de56bc10c5cf82bdff8da14eece7685f409592450c07478333aa3b99c src/vhost/error_fallback.rs 63e9fc7f7be78dc3e16a89f015a56a2da6ba3aff0197b70ff48321dfb17529bb src/vhost/model.rs 35a0aca3eee8d47d1bab27c83d4532cd572fc3e17b5f0d4a8d4515a8f85b3d96 src/vhost/redirect.rs 9b16b5307e140db97363f56c9fac8319e56df846bb1c919d3bc06091ab6ce69c src/vhost/tests.rs b7d0f7f5d0bbd74add3fda9b1308350c4f70f8b6debf979fb977a4f2f659c32f src/vhost/validation.rs -3aa1b07cd26d4a5b9e5e94d1d6a712ef1397d827e7f1e8c01f7195b98d2c5f67 src/vhost.rs +8d1eff4b24f01d137414ef5419f75dd281879228adb70409645b11b3c78c20e9 src/web_server/config.rs 9744e8c29ae72a4d9fbc9a76166a97f8292c4c312295ea40d1cb699e03d80a9d src/web_server/config/compile.rs bcaa1ae15134d85668b05a88d8abea01e5d188f535ad83cd4459732fd56f2f44 src/web_server/config/model.rs a863ad1337fbc353c0f42caea4ac8b3644792e2aa08c37f992b7882b4b8dc6d5 src/web_server/config/validation.rs -8d1eff4b24f01d137414ef5419f75dd281879228adb70409645b11b3c78c20e9 src/web_server/config.rs +86c744216d7132d8294a6e90ba9be5fd871646006313d1c62506d40c81db9b12 src/web_server/fastcgi.rs 200cba8cb3482e49db73d2c60cb60786175177c7d4be2a566cd281fec7ba7fca src/web_server/fastcgi/protocol.rs cef44ccdf882d84892a64bdbfdc1ba01380fce5e5f86d2829b0f9613f738b964 src/web_server/fastcgi/response.rs -86c744216d7132d8294a6e90ba9be5fd871646006313d1c62506d40c81db9b12 src/web_server/fastcgi.rs e15361622683268c5606a39a9e5db3938e630999767898391226e94ad2e421e8 src/web_server/filesystem.rs +d4fec3682532b0f2d11a0aefcd024f69fb623a39922ddb6c528a2d2de265347d src/web_server/htaccess.rs ca3cd376b313af1ce0ee65081b3327eb213f000d5a215aa4ee6b764de9702126 src/web_server/htaccess/model.rs 76de1d11df75f4a64556b2821fd0a1774d26c9f0ca0e5f2b5fcfad0722d43d47 src/web_server/htaccess/parse.rs 66260d159986d41eab0dfde2cb9f0713fc1cc209c2fb47e9023bd24fd37919e8 src/web_server/htaccess/rewrite.rs 8ca74d9cc4470045301f70eb4a9fbabd0dbfe74434429148d2230df9f996c06c src/web_server/htaccess/tests.rs -d4fec3682532b0f2d11a0aefcd024f69fb623a39922ddb6c528a2d2de265347d src/web_server/htaccess.rs 3341264f6e8041ac5a5d3c4b1601a69787386116019b5febc1a5e22bdb1186f9 src/web_server/metrics.rs 0dbef9b71869fc52cf01e9cb400ffd48fb433ae625383edee6c6c2d735608a76 src/web_server/mod.rs 67ab8bef567452f123c4b9b46a942b39c93f1f765c128edca7ee808ff1c5e304 src/web_server/request.rs -833c9fea744b9649046e1a64d6fc6972fbf6cea640e1943b0db52b7ccfa9faad src/web_server/response/file.rs -c2e54fd803a10f74490f183e8c030fd0e3e72f5de4e79c55bc393ab57d90ab9a src/web_server/response/file_body/tests.rs -ba793a140699956a9aef6bc79b0c731c481af8ab7ac3d816a28695743febcb30 src/web_server/response/file_body.rs -20509f9302b79d3a7be76dda6edaf5711826d3ddf47d19ebe07cb289427ca328 src/web_server/response/headers.rs d98c80663847d6d83073df074ebff65952755415574708abcc153bd8d3adfaa9 src/web_server/response.rs +833c9fea744b9649046e1a64d6fc6972fbf6cea640e1943b0db52b7ccfa9faad src/web_server/response/file.rs +ba793a140699956a9aef6bc79b0c731c481af8ab7ac3d816a28695743febcb30 src/web_server/response/file_body.rs +c2e54fd803a10f74490f183e8c030fd0e3e72f5de4e79c55bc393ab57d90ab9a src/web_server/response/file_body/tests.rs +20509f9302b79d3a7be76dda6edaf5711826d3ddf47d19ebe07cb289427ca328 src/web_server/response/headers.rs 305c0109b4f869a99381a142853f9e2205f5c7c4f904b2dfa4643274bfc542af src/web_server/routing.rs 400e1c8aa2fe857d96036a64499fbc3de44c1e3a53811c5b25101fb843359792 src/web_server/security.rs 54cf72a82e023fe46513b9cf3130adfef1cd96c40f790c533016b4825d542e06 src/web_server/serve.rs diff --git a/docs/PROXY_1KB_HOTPATH_DEV_0.34.0.md b/docs/PROXY_1KB_HOTPATH_DEV_0.34.0.md new file mode 100644 index 0000000..96428e7 --- /dev/null +++ b/docs/PROXY_1KB_HOTPATH_DEV_0.34.0.md @@ -0,0 +1,137 @@ +# RustProxy 0.34.0 DEV: 1 KiB reverse-proxy throughput audit + +## Goal and evidence boundaries + +Priority 1 is short (~1 KiB) HTTP reverse-proxy responses: aim for approximately +100,000 requests/s, and eventually at least 80% of nginx under the **same** +controlled benchmark, without disabling authentication, ACLs, caching semantics, +rate limits, traffic accounting, request IDs, logs, body streaming or protocol +support. Priority 2 is local WWW serving, to be tuned and measured separately. +This is a development revision; Cargo/package version remains **0.34.0**. + +**This source is not compiled in the current environment.** Neither `cargo` +nor `rustc` is available. Only the user's pre-existing executable (SHA-256 +`453757748455d7b9b50a6140e322ee4d4cf4a030eea29318686f2e28c594b644`) +was run. Live configuration A/B tests therefore substantiate a **configuration +bottleneck**, not the throughput of this edited source. + +## Real baseline experiment (existing executable only) + +Disposable loopback nginx upstream, 1,040-byte body, HTTP/1.1 persistent +frontend connections, caching disabled, identity response encoding, four Tokio +workers, ApacheBench (`ab -k -n 12000`), 16/64 concurrent frontend clients. +Checks outside the timed intervals verified HTTP 200, exact 1,040 bytes and +SHA-256 `62a08d75cdde0416c883d72458385b5e56ae8c14466934ad784587ddb93a548b`; +0 failed requests in the shown samples. The host has shared CPU resources; +results vary and are not a pinned-CPU or production acceptance benchmark. + +| Existing executable configuration | 16 clients, RPS | 64 clients, RPS | +|---|---:|---:| +| max_idle_per_host = 4 | 18,226 | 17,935 | +| max_idle_per_host = 64 | 30,906 | 24,872 | +| Relative change (configuration only) | +69.6% | +38.7% | + +A separate repeat experiment at 64 clients (two runs per variant, in order) +produced: `idle4` 14,028 / 14,834; `idle16` 22,205 / 24,711; +`idle32` 25,580 / 29,088; `idle64` 36,521 / 33,847; +`idle64 + recycle 250,000` 31,168 / 29,753; +`idle32_again` 34,798 / 29,194; `idle64_again` 34,677 / 29,965; +`idle4_again` 23,503 / 23,514 RPS. The order drift warns against +reporting a single percentage as a robust speedup. Raising generation +recycling from 25,000 to 250,000 did not establish any improvement; its +original limit is retained. All shown variants reported zero HTTP failures. + +A preliminary nginx comparison gave ~75k/117k RPS at 16/64 clients, but later +nginx samples were ~50k/93k on the shared host. Do not compute a definitive +"% nginx" from these non-isolated runs. The 100k/80% goals remain **OPEN**. + +## Source modifications + +| Location | Change | Preserved behavior / caveat | +|---|---|---| +| `src/balance/model.rs` | New vhost default `max_idle_per_host`: **4 -> 64** | Configured values **1..64** remain validated; existing explicitly saved `4` stays `4`. Disabled keepalive, 30 s idle timeout, 25k-request and 3,600 s recycling rules are unchanged. Increased idle sockets use more file descriptors and memory. | +| `src/admin/web/vhosts/editor.js` | Match the new `64` default when the field is absent | Existing values, limits and all editor settings remain unchanged. | +| `src/proxy/body.rs` | At `Exchange::drop`, use exclusive `Mutex::get_mut()` rather than lock/unlock; move owned `route`, `client_ip`, `country`, `upstream_error` into final observation where possible | Exactly the same log fields, analytics sample, counters, permit lifetime, errors and websocket/H3 fields. Analytics still gets a clone when a vhost sample is queued; history still receives the original. | +| `src/proxy/headers.rs` | Skip reserved cookie sanitization immediately if the corresponding `Cookie`/`Set-Cookie` header is absent | Full sanitization, admin-cookie separation and restoration restrictions still apply when the header is present. | +| `src/balance/tests.rs`, `src/proxy/body/tests.rs`, `src/proxy/headers/tests.rs` | Add compatibility, completion and cookie regression assertions | These Rust tests **require** a compiler before they count as run. | +| `scripts/tests/*hotpath*` | Update source-only guards for the new **bounded** default | Static assertions do not prove functional or runtime performance equivalence. | + +**Persistence note:** old vhosts may store `keepalive.max_idle_per_host=4` +explicitly; the new code default does not rewrite them. To apply the measured +configuration improvement before rebuilding, change that option to `64` in the +relevant vhost and verify actual idle socket/FD usage. Where hundreds of origins +share a host, test `16` or `32` if the FD/memory trade-off is preferable. + +## Bottlenecks to profile next, not silently disable + +1. `src/cache/dashboard.rs::Cache::record`: obtains a **shared cache-store + mutex on every outcome**, including `BYPASS` when cache is disabled through + `src/proxy/forward/cache_lookup.rs`. This may compete with HOT cache + operations and admin dashboard reads; profile `pthread_mutex`/futex and + lock hold times. Candidate: separate bounded, sharded domain/reason + counters from the HOT object store while preserving exact dashboard totals, + reason labels and reset semantics. +2. `src/logging/format.rs::Logs::push`: per-request bounded history + `try_lock`, potentially causing recorded log drops under high concurrency. + Preserve *existing* drops/accounting, live subscribers and external sinks. + Candidate: worker-local bounded batches or sharded history with deterministic + bounded merge; validate log order, recent history, retention and drops. +3. `src/proxy/body.rs::Exchange::drop` + `src/traffic.rs::Analytics::push`: + request-sized log strings, sampling queue sends, atomics and lifecycle + observations. Profile allocations and CPU per completed request. Candidate: + compact shared immutable identity fields or conditional cloning solely + where consumers require ownership, without removing logs or analytics. +4. `src/proxy/forward/route_cache.rs`: request-target path copies, + header policy and several route/cache eligibility steps. Measure with + sampling `perf record -g` before extracting additional fast paths; preserve + query handling, canonical host, ACL, authentication, retries and WebSockets. +5. `src/upstream/*`: profile H1 pool misses, TCP connect rate, Hyper + connection reuse and generation swaps. Increasing recycle thresholds or + changing HTTP/2/H2C modes without an isolated performance case is not + recommended. +6. **Separate WWW priority:** benchmark short static objects independently; + existing `sendfile: auto` applies to eligible cleartext H1 objects >=64 KiB + and cannot accelerate 1 KiB bodies. + +No lock removal, tracing/log disabling, caching-policy weakening, bypass of +security checks, or transformation of complete bodies into buffered copies is +proposed without a test proving semantic equivalence. + +## Acceptance gate on a machine with Rust toolchain and isolated load generator + +```bash +./dev.sh doctor +./dev.sh check +CARGO_INCREMENTAL=0 ./dev.sh test +CARGO_INCREMENTAL=0 cargo build --release --locked +python3 scripts/performance/regression.py \ + --binary after="$(realpath target/release/rust-proxy)" \ + --out /tmp/rustproxy034-1kb-regression +python3 scripts/performance/lb_regression.py \ + --binary before=/absolute/path/to/old-rust-proxy \ + --binary after="$(realpath target/release/rust-proxy)" \ + --out /tmp/rustproxy034-1kb-lb +python3 scripts/performance/transport_regression.py \ + --binary before=/absolute/path/to/old-rust-proxy \ + --binary after="$(realpath target/release/rust-proxy)" \ + --out /tmp/rustproxy034-1kb-transport +python3 scripts/performance/benchmark.py \ + --binary before=/absolute/path/to/old-rust-proxy \ + --binary after="$(realpath target/release/rust-proxy)" \ + --nginx /usr/sbin/nginx --wrk /absolute/path/to/wrk \ + --out /tmp/rustproxy034-1kb-benchmark \ + --modes proxy --sizes small --concurrency 16,64,128 \ + --duration 30 --warmup 5 --repeats 7 +``` + +Use the **same explicit** `max_idle_per_host=64` and all other vhost settings +for the *source A/B* test. Run 4 vs 64 as a separate *configuration A/B* test; +never attribute a settings difference to code. Verify full content checksums, +HTTP 2xx/4xx/5xx, p50/p95/p99, drop counters, backend connections, +FD/RSS trends, CPU/request and packet/TCP retransmit rates. Test H1/H2/H3, +TLS, WebSockets, sticky/rate/ACL, cache MISS/HIT/BYPASS, admin sessions, active +failover, cancellation, idle timeouts and a sustained memory/connection soak. +Profile the freshly **built** executable separately from timed RPS runs. + +Until compilation and those gates pass, this is a **development source-only +candidate**, not a claim of reaching 100k RPS or 80% nginx. diff --git a/docs/PROXY_RPS_0.34.0.md b/docs/PROXY_RPS_0.34.0.md index d0044cf..68d8a61 100644 --- a/docs/PROXY_RPS_0.34.0.md +++ b/docs/PROXY_RPS_0.34.0.md @@ -18,11 +18,12 @@ passes compile, unit tests, live regressions and paired performance comparisons. | Log history | Move completed `LogEntry` directly into bounded history when there are no live viewers or enabled external sinks, instead of deeply cloning its strings. Continue cloning and delivering to live viewers/sinks when enabled. | Same JSON fields, history size, drop counters, file/Loki/Logstash forwarding. | | Route/HTTP instrumentation | Remove redundant route-ID mutex/write in forwarding and collapse H1/H2 version tallying into one branch. | Route is recorded once before forwarding; H1/H2 counters remain. | -These changes build on the previous 0.34.0 route-Arc, single-backend LB, +These historical changes build on the previous 0.34.0 route-Arc, single-backend LB, conditional retry/fallback-header cloning, atomic exchange flags and cache HOT -LRU changes. There are no new UI toggles. Pool defaults remain `max_idle_per_host` -4 and `pool_recycle_requests` 25,000; tune these only in separately labelled -trials. `sendfile: auto` remains opt-in and applies only to eligible Linux +LRU changes. There are no new UI toggles. This **earlier** revision retained `max_idle_per_host` +4 and `pool_recycle_requests` 25,000. The **subsequent DEV 1 KiB revision** +changes only the default idle limit to 64, based on live configuration A/B +with the old binary (not source A/B); see `docs/PROXY_1KB_HOTPATH_DEV_0.34.0.md`. `sendfile: auto` remains opt-in and applies only to eligible Linux plaintext H1 static WWW responses, not reverse proxy or TLS/H2/H3. ## Cache transform/query policy diff --git a/docs/TEST_REPORT_0.34.0.md b/docs/TEST_REPORT_0.34.0.md index f136270..803446a 100644 --- a/docs/TEST_REPORT_0.34.0.md +++ b/docs/TEST_REPORT_0.34.0.md @@ -9,6 +9,34 @@ compiled**, the new Rust tests were **not executed**, and no 0.34.0 RustProxy binary or live throughput figures are supplied. Source inspection and simulated UI/cache tests do not close the runtime acceptance gate. +## DEV 1 KiB reverse-proxy follow-up (October 2026; source only) + +The supplied **old executable** passed loopback HTTP/1.1 1,040-byte content +checks and ApacheBench 12,000-request samples. The configuration trial +`max_idle_per_host=4 -> 64` increased short-run RPS, but shared-CPU noise +precludes a stable nginx-parity percentage. The edited sources now use 64 by +default for absent/new keepalive fields and reduce exclusive-Drop mutex/clone +and absent-cookie overhead. See `docs/PROXY_1KB_HOTPATH_DEV_0.34.0.md`. +**No newly modified binary was built or run.** Rust unit tests, runtime +regressions, long soaks and post-edit code A/B are still required. + +Current DEV source checks performed on the modified tree: + +| Check | Result | Scope | +|---|---|---| +| `./dev.sh doctor` | PASS | Source preflight; reports `cargo` and `rustc` absent | +| `scripts/tests/rps_hotpath_034_static_test.py` | PASS | Guardrails, defaults, retained routing/security and source-size limits only | +| `scripts/tests/proxy_hotpath_034_static_test.py` | PASS | Routing and telemetry source guards only | +| `scripts/tests/cache_scope_034_static_test.py`, `cache_hot_034_static_test.py`, `sendfile_034_static_test.py` | PASS | Cache and WWW source guards only | +| `scripts/tests/dashboard_presets_sql_test.py` | PASS | SQLite migrations and preset constraints | +| `scripts/tests/upgrade_performance_test.py` | PASS | Disposable upgrade/preservation/locking test | +| `scripts/tests/sendfile_034_panel_browser_test.py` | PASS, 2 widths | Simulated Chromium admin API, not live Rust | +| `scripts/tests/vhost_backend_popup_0337_browser_test.py` | PASS, 4 widths | Simulated Chromium admin API, not live Rust | +| Node `--check` (vhost editor), Python `compileall`, JSON parser (OpenAPI) | PASS | Syntax only | +| `./dev.sh check`, `./dev.sh test` | BLOCKED, exit 127 | Rust toolchain missing; no Rust unit/build acceptance | +| Old supplied binary, `ab`/nginx configuration A/B | COMPLETED, DIAGNOSTIC | 1,040-byte H1 payload; shared-CPU and no new code exercised | + + ## Later 0.34.0 reverse-proxy optimization revision The refreshed source archive additionally reuses immutable route handles, diff --git a/docs/TRANSPORT.md b/docs/TRANSPORT.md index 7259513..59d1fa0 100644 --- a/docs/TRANSPORT.md +++ b/docs/TRANSPORT.md @@ -182,7 +182,7 @@ Downstream H2 idle retirement is activity-aware: RustProxy tracks transport I/O | Backend response-header deadline | 120 seconds, including upload until headers | | HTTP body idle timeout | 60 seconds | | WebSocket idle timeout / upgrade completion | 300 seconds / 10 seconds | -| Idle pooled upstream connections | 4 per backend origin, 30-second idle timeout | +| Idle pooled upstream connections | up to 64 per backend origin by default for new vhosts (1..64 configurable), 30-second idle timeout; existing explicit values preserved | | Configuration writers / log-viewer streams | 8 / 8 | CLI serve flags expose connection/in-flight counts and HTTP body, WebSocket idle, diff --git a/docs/VHOSTS.md b/docs/VHOSTS.md index 117279e..03aef56 100644 --- a/docs/VHOSTS.md +++ b/docs/VHOSTS.md @@ -228,12 +228,14 @@ origin do not expose a selected backend or stale origin timing. |---|---|---| | `enabled` | true | Boolean | | `idle_timeout_seconds` | 30 | 1..3600 | -| `max_idle_per_host` | 4 | 1..64 | +| `max_idle_per_host` | 64 | 1..64 | | `tcp_keepalive_seconds` | 30 | 1..3600 | | `pool_recycle_requests` | 25000 | 0 (off) or 1000..10000000 | | `pool_recycle_seconds` | 3600 | 0 (off) or 60..604800 | | `http1_max_buffer_bytes` | 131072 | 8192..1048576 | +The new default of 64 applies when this field is absent in a newly created or deserialized vhost; existing saved values (including 4) remain unchanged. Each idle upstream connection consumes a file descriptor and memory, so use a smaller value for resource-constrained deployments with many origins. See `docs/PROXY_1KB_HOTPATH_DEV_0.34.0.md` for the live configuration A/B evidence. + These configure HTTP idle reuse and TCP keepalive; HTTP/2 also uses pings for active connections, with a 10-second ping timeout and no pinging solely to keep idle connections alive. `pool_recycle_requests` and `pool_recycle_seconds` bound the lifetime diff --git a/scripts/performance/README.md b/scripts/performance/README.md index 44c1c3c..6cc610c 100644 --- a/scripts/performance/README.md +++ b/scripts/performance/README.md @@ -6,6 +6,15 @@ controllable test **upstream**, used to verify streaming, non-replayable writes, headers, cache policy and WebSocket frames. Performance measurements use nginx as the shared upstream instead of Python. +## DEV 1 KiB follow-up on 0.34.0 (newer source) + +See `docs/PROXY_1KB_HOTPATH_DEV_0.34.0.md`. The previous executable's 4-vs-64 +idle-connection tuning experiment is real loopback evidence, but the *edited* +source has not been compiled. Its new default is 64 for new vhosts, whereas +explicitly saved `4` remains `4`. Keep the idle limit equal between before/after +*code* benchmarks; measure configuration tuning in a separate labelled series. +The source release is not eligible for a claim of 100k RPS or 80% nginx yet. + ## Reverse-proxy optimization revision 0.34.0 After compiling the refreshed candidate, measure the same unmodified 0.33.8 diff --git a/scripts/tests/proxy_hotpath_034_static_test.py b/scripts/tests/proxy_hotpath_034_static_test.py index afdd690..e2978e1 100755 --- a/scripts/tests/proxy_hotpath_034_static_test.py +++ b/scripts/tests/proxy_hotpath_034_static_test.py @@ -42,6 +42,6 @@ for path in (ROOT / "src").rglob("*.rs"): continue assert len(path.read_text().splitlines()) <= 500, path assert 'version = "0.34.0"' in src("Cargo.toml") -assert "max_idle_per_host: 4" in src("src/balance/model.rs") +assert "max_idle_per_host: 64" in src("src/balance/model.rs") assert "pool_recycle_requests: 25_000" in src("src/balance/model.rs") -print("PASS 0.34.0 proxy hot-path source wiring, observability, preserved defaults and source-size limits (STATIC ONLY)") +print("PASS 0.34.0 proxy hot-path wiring, observability, bounded tuned defaults and source-size limits (STATIC ONLY)") diff --git a/scripts/tests/rps_hotpath_034_static_test.py b/scripts/tests/rps_hotpath_034_static_test.py old mode 100644 new mode 100755 index 88f18cb..c9499af --- a/scripts/tests/rps_hotpath_034_static_test.py +++ b/scripts/tests/rps_hotpath_034_static_test.py @@ -5,6 +5,7 @@ These guards reject accidental removal of important branch/safety conditions. They must be paired with ``cargo test`` and live black-box HTTP acceptance. """ from pathlib import Path +import json ROOT = Path(__file__).resolve().parents[2] @@ -88,8 +89,22 @@ assert "upstream_uri(&backend, &origin_suffix)" in route assert "headers::strip_hop_by_hop" in route assert "pool.select_wait(context.client_ip" in route or ".select_wait(context.client_ip" in route assert "pool.select_member_wait(id)" in route -assert "max_idle_per_host: 4" in source("src/balance/model.rs") +assert "max_idle_per_host: 64" in source("src/balance/model.rs") assert "pool_recycle_requests: 25_000" in source("src/balance/model.rs") +assert "(1..=64).contains(&k.max_idle_per_host)" in source("src/balance/model.rs") +assert "keepalive.max_idle_per_host ?? 64" in source("src/admin/web/vhosts/editor.js") +openapi = json.loads(source("src/admin/openapi.json")) +api_keepalive = openapi["components"]["schemas"] +assert any(isinstance(schema, dict) and "keepalive" in schema.get("properties", {}) + and schema["properties"]["keepalive"].get("properties", {}) + .get("max_idle_per_host", {}).get("default") == 64 + for schema in api_keepalive.values()) +assert "| `max_idle_per_host` | 64 | 1..64 |" in source("docs/VHOSTS.md") +assert '"keepalive": { "max_idle_per_host": 4 }' in source("src/balance/tests.rs") +assert "self.route.get_mut()" in source("src/proxy/body.rs") +assert "let client_ip = self" in source("src/proxy/body.rs") +assert "if !headers.contains_key(http::header::COOKIE)" in source("src/proxy/headers.rs") +assert "if !headers.contains_key(http::header::SET_COOKIE)" in source("src/proxy/headers.rs") assert 'version = "0.34.0"' in source("Cargo.toml") for file in (ROOT / "src").rglob("*.rs"): diff --git a/src/admin/openapi.json b/src/admin/openapi.json index e580ce8..d8a93bc 100644 --- a/src/admin/openapi.json +++ b/src/admin/openapi.json @@ -4193,7 +4193,7 @@ "type": "integer", "minimum": 1, "maximum": 64, - "default": 4 + "default": 64 }, "tcp_keepalive_seconds": { "type": "integer", diff --git a/src/admin/web/vhosts/editor.js b/src/admin/web/vhosts/editor.js index 5d626b4..ce6eb06 100644 --- a/src/admin/web/vhosts/editor.js +++ b/src/admin/web/vhosts/editor.js @@ -195,7 +195,7 @@ function load(value = defaults(), migrationIds = [], show = true) { note(g, "vhRetryHelp"); field(g, "keepalive", "vhKeepalive", keepalive.enabled !== false, "checkbox"); field(g, "idle-timeout", "vhIdleTimeout", keepalive.idle_timeout_seconds ?? 30, "number", { required: true, min: 1, max: 3600 }); - field(g, "max-idle", "vhMaxIdle", keepalive.max_idle_per_host ?? 4, "number", { required: true, min: 1, max: 64 }); + field(g, "max-idle", "vhMaxIdle", keepalive.max_idle_per_host ?? 64, "number", { required: true, min: 1, max: 64 }); field(g, "tcp-keepalive", "vhTcpKeepalive", keepalive.tcp_keepalive_seconds ?? 30, "number", { required: true, min: 1, max: 3600 }); field(g, "pool-recycle-requests", "vhPoolRecycleRequests", keepalive.pool_recycle_requests ?? 25000, "number", { required: true, min: 0, max: 10000000 }); field(g, "pool-recycle-seconds", "vhPoolRecycleSeconds", keepalive.pool_recycle_seconds ?? 3600, "number", { required: true, min: 0, max: 604800 }); diff --git a/src/balance/model.rs b/src/balance/model.rs index 5589acf..bfc14fd 100644 --- a/src/balance/model.rs +++ b/src/balance/model.rs @@ -70,7 +70,10 @@ impl Default for Keepalive { Self { enabled: true, idle_timeout_seconds: 30, - max_idle_per_host: 4, + // Retain enough reusable H1 upstream sockets under concurrent + // small-response traffic. The existing 1..=64 bound, idle + // timeout and pool recycling still limit resource retention. + max_idle_per_host: 64, tcp_keepalive_seconds: 30, pool_recycle_requests: 25_000, pool_recycle_seconds: 3_600, diff --git a/src/balance/tests.rs b/src/balance/tests.rs index 079dd67..216f44b 100644 --- a/src/balance/tests.rs +++ b/src/balance/tests.rs @@ -102,6 +102,11 @@ mod tests { assert!(parsed.retry.retry_connect_errors); assert!(parsed.retry.retry_timeouts); assert_eq!(parsed.retry.retry_statuses, vec![502, 503, 504]); + assert_eq!(parsed.keepalive.max_idle_per_host, 64); + let explicit: Settings = serde_json::from_value(serde_json::json!({ + "keepalive": { "max_idle_per_host": 4 } + })).unwrap(); + assert_eq!(explicit.keepalive.max_idle_per_host, 4); assert_eq!(parsed.keepalive.pool_recycle_requests, 25_000); assert_eq!(parsed.keepalive.pool_recycle_seconds, 3_600); assert_eq!(parsed.keepalive.http1_max_buffer_bytes, 131_072); diff --git a/src/proxy/body.rs b/src/proxy/body.rs index 0596d57..63de889 100644 --- a/src/proxy/body.rs +++ b/src/proxy/body.rs @@ -176,30 +176,28 @@ impl Drop for Exchange { _ => &self.metrics.status_5xx, } .fetch_add(1, Ordering::Relaxed); + // Final Arc drop has exclusive access: move strings without locking. let backend = self .backend - .lock() + .get_mut() .unwrap_or_else(|e| e.into_inner()) .as_ref() .map(|l| l.member.backend.id.clone()); - let websocket_phase = *self - .websocket_phase - .lock() - .unwrap_or_else(|e| e.into_inner()); - let route = self.route.lock().unwrap_or_else(|e| e.into_inner()).clone(); + let websocket_phase = *self.websocket_phase.get_mut().unwrap_or_else(|e| e.into_inner()); + let route = self.route.get_mut().unwrap_or_else(|e| e.into_inner()).take(); let source = ExchangeSource::name(self.source.load(Ordering::Relaxed)); let cache_effective_enabled = read_effective(self.cache_effective_enabled.load(Ordering::Relaxed)); let transform_effective_enabled = read_effective(self.transform_effective_enabled.load(Ordering::Relaxed)); let client_ip = self .client_ip - .lock() + .get_mut() .unwrap_or_else(|e| e.into_inner()) - .clone(); + .take(); let country = self .country - .lock() + .get_mut() .unwrap_or_else(|e| e.into_inner()) - .clone(); + .take(); let request_bytes = self.request_bytes.load(Ordering::Relaxed); let response_bytes = self.response_bytes.load(Ordering::Relaxed); let duration_ms = duration.as_millis() as u64; @@ -248,7 +246,7 @@ impl Drop for Exchange { sni: None, authority: None, matched_by: None, - cache_reason: *self.cache_reason.lock().unwrap_or_else(|e| e.into_inner()), + cache_reason: *self.cache_reason.get_mut().unwrap_or_else(|e| e.into_inner()), vhost: self.vhost.take(), route, cache_effective_enabled, @@ -266,18 +264,18 @@ impl Drop for Exchange { websocket_phase, websocket_error: *self .websocket_error - .lock() + .get_mut() .unwrap_or_else(|e| e.into_inner()), - h3_reset_code: *self.h3_reset_code.lock().unwrap_or_else(|e| e.into_inner()), + h3_reset_code: *self.h3_reset_code.get_mut().unwrap_or_else(|e| e.into_inner()), upstream_status: match self.upstream_status.load(Ordering::Relaxed) { 0 => None, value => Some(value), }, upstream_error: self .upstream_error - .lock() + .get_mut() .unwrap_or_else(|e| e.into_inner()) - .clone(), + .take(), client_ip, user_agent: self.user_agent.take(), country, @@ -290,6 +288,7 @@ impl Drop for Exchange { }); } } + #[derive(Clone, Copy)] pub enum Direction { Request, diff --git a/src/proxy/body/tests.rs b/src/proxy/body/tests.rs index 9d3c99b..03fa7e6 100644 --- a/src/proxy/body/tests.rs +++ b/src/proxy/body/tests.rs @@ -226,6 +226,30 @@ mod tests { } } + #[tokio::test] + async fn completion_moves_owned_fields_but_preserves_log_identity() { + let (exchange, slots) = observation().await; + let logs = exchange.logs.clone(); + *exchange.route.lock().unwrap() = Some("route-1".into()); + *exchange.client_ip.lock().unwrap() = Some("198.51.100.9".into()); + *exchange.country.lock().unwrap() = Some("DE".into()); + *exchange.upstream_error.lock().unwrap() = Some("upstream closed".into()); + *exchange.cache_reason.lock().unwrap() = "cache_disabled"; + *exchange.websocket_error.lock().unwrap() = Some("upstream_http_error"); + *exchange.h3_reset_code.lock().unwrap() = Some("h3_general_protocol_error"); + drop(exchange); + assert_eq!(slots.available_permits(), 1); + let entries = logs.recent(); + assert_eq!(entries.len(), 1); + assert_eq!(entries[0].route.as_deref(), Some("route-1")); + assert_eq!(entries[0].client_ip.as_deref(), Some("198.51.100.9")); + assert_eq!(entries[0].country.as_deref(), Some("DE")); + assert_eq!(entries[0].upstream_error.as_deref(), Some("upstream closed")); + assert_eq!(entries[0].cache_reason, "cache_disabled"); + assert_eq!(entries[0].websocket_error, Some("upstream_http_error")); + assert_eq!(entries[0].h3_reset_code, Some("h3_general_protocol_error")); + } + #[tokio::test] async fn atomic_exchange_tags_keep_original_observability_fields() { let (exchange, slots) = observation().await; diff --git a/src/proxy/headers.rs b/src/proxy/headers.rs index 06559d1..6ccc73a 100644 --- a/src/proxy/headers.rs +++ b/src/proxy/headers.rs @@ -45,6 +45,9 @@ include!("headers/tests.rs"); /// guarded self-admin reverse-proxy path may restore only those fragments after /// the actual backend has been selected and verified. pub fn strip_admin_cookie(headers: &mut HeaderMap) -> Vec { + if !headers.contains_key(http::header::COOKIE) { + return Vec::new(); + } let mut retained = Vec::new(); let mut admin = Vec::new(); for part in headers @@ -91,6 +94,9 @@ pub fn restore_admin_cookie(headers: &mut HeaderMap, admin: &[String]) { } /// Upstreams cannot overwrite the reserved admin cookie through this proxy listener. pub fn strip_admin_set_cookie(headers: &mut HeaderMap) { + if !headers.contains_key(http::header::SET_COOKIE) { + return; + } let retained: Vec<_> = headers .get_all(http::header::SET_COOKIE) .iter() diff --git a/src/proxy/headers/tests.rs b/src/proxy/headers/tests.rs index 5792b01..cbede77 100644 --- a/src/proxy/headers/tests.rs +++ b/src/proxy/headers/tests.rs @@ -19,6 +19,29 @@ mod tests { h.insert("connection", "keep-alive, Upgrade".parse().unwrap()); assert!(requests_upgrade(&h)); } + #[test] + fn absent_cookies_leave_headers_unchanged() { + let mut headers = HeaderMap::new(); + headers.insert("x-pass", "yes".parse().unwrap()); + assert!(strip_admin_cookie(&mut headers).is_empty()); + strip_admin_set_cookie(&mut headers); + assert_eq!(headers.get("x-pass").unwrap(), "yes"); + assert!(!headers.contains_key(http::header::COOKIE)); + assert!(!headers.contains_key(http::header::SET_COOKIE)); + } + + #[test] + fn set_cookie_keeps_valid_unreserved_values() { + let mut headers = HeaderMap::new(); + headers.append("set-cookie", "a=1; Secure".parse().unwrap()); + headers.append("set-cookie", "rustproxy_session=secret".parse().unwrap()); + headers.append("set-cookie", "b=2; HttpOnly".parse().unwrap()); + strip_admin_set_cookie(&mut headers); + let cookies: Vec<_> = headers.get_all("set-cookie").iter() + .map(|value| value.to_str().unwrap()).collect(); + assert_eq!(cookies, vec!["a=1; Secure", "b=2; HttpOnly"]); + } + #[test] fn admin_cookie_can_be_restored_only_from_captured_fragment() { let mut h = HeaderMap::new();