Extract strip_port_from_host into shared utils module and update normalize_host to properly strip brackets from IPv6 addresses like [::1]:443 -> ::1 instead of incorrectly using split(':').next().
Change ConfigReloadHandle.static_config from StaticConfig to ArcSwap<StaticConfig>
so that after each reload, the stored static config is updated with the new value.
This prevents repeated stale warnings about the same static config fields on
every reload.
Change http_port type from u16 to u32 to allow out-of-range values to be
caught by validation. Add HttpPortInvalid error variant and validation check
for http_port > 65535. Add test for http_port=65536 producing HttpPortInvalid.
http_port=0 (disabled) remains valid per existing test.
Add admin socket module that binds to a configurable Unix domain socket
path (default /run/reverse-proxy/admin.sock) supporting reload and status
commands. Reload re-reads config and swaps DynamicConfig via ArcSwap with
serialized access using the same Mutex as SIGHUP. Status returns uptime
and site count. Unknown commands and invalid input return structured
JSON error responses. Stale socket files are removed at startup; if the
socket is occupied by another process, a warning is logged and the socket
is disabled. Empty admin_socket_path disables the socket entirely.
Also adds FullConfig struct to config module for parsing complete config
files during reload, and adds serde_json dependency for JSON responses.
Add routing table (HashMap<String, SiteConfig>) to DynamicConfig for
O(1) host lookup. Implement normalize_host (lowercase + strip port)
per RFC 7230 §2.7.3. Add proxy_handler that routes /health to 200,
missing Host to 400, unknown host to 404, and known host to 200.
Routing table updates atomically via ArcSwap.
Add ConfigReloadHandle with Arc<ArcSwap<DynamicConfig>> for lock-free reads
on the request hot path and tokio::sync::Mutex-serialized reload. Add static
config change detection via diff_static_config(). Add DynamicConfig validation
(rate_limit, body_limit, site checks). Add PartialEq derives to config types.
Include unit tests for ArcSwap swap visibility, invalid config rejection, and
concurrent reload serialization.
- Add health.rs module with start_health_check_listener() that binds to
127.0.0.1:{health_check_port} and serves GET /health returning 200 OK
with empty body
- Add health_route() in proxy/handler.rs for HTTPS listener fallback
- Add port conflict detection in config validation: health_check_port
must not conflict with listener ports on 127.0.0.1/localhost/0.0.0.0
- health_check_port = 0 disables the separate listener (handled at call
site)
- Add unit and integration tests for health check functionality
- Add [lib] target to enable integration test imports
- Add rcgen and reqwest dev-dependencies for TLS and HTTP test helpers
- Create src/config/test_fixtures.rs with test_static_config() and test_dynamic_config()
- Create tests/ with integration tests, HTTP test helper (TestUpstream), and TLS test helper (SelfSignedCert)
- Add Clone derives to StaticConfig and related structs for test fixture construction
- All existing tests continue to pass
Add Clone derive to StaticConfig, ListenerConfig, TlsConfig, and
LoggingConfig to support immutable-after-startup pattern. Add unit
tests verifying TOML deserialization for multi-config (dedicated-IP)
and shared-IP (SAN certificate) deployment formats, default value
application, logging config, and site defaults.