@push.rocks/smartproxy
Version:
A powerful proxy package with unified route-based configuration for high traffic management. Features include SSL/TLS support, flexible routing patterns, WebSocket handling, advanced security options, and automatic ACME certificate management.
813 lines (573 loc) • 97.1 kB
Markdown
# Changelog
## 2026-06-05 - 27.13.0
### Features
- add route challenge enforcement (challenge)
- Add smartchallenge provider registration and relay wiring between TypeScript and the Rust proxy runtime
- Enforce route-level browser challenges with pending and clearance cookies plus reserved verification endpoints
- Document challenge configuration and add integration tests for protected routes
## 2026-06-05 - 27.12.8
### BREAKING CHANGES
- require explicit inbound PROXY protocol listener policies (proxy-protocol)
- Replace global inbound `proxyIPs`/`acceptProxyProtocol` config with exact `trustedProxyIPs` trust lists and listener-scoped `match.inboundProxyProtocol` policies.
- Default listeners now reject inbound PROXY protocol unless `mode: 'optional'` or `mode: 'required'` is declared.
- Apply explicit inbound policy resolution, validation, and TCP/UDP/QUIC handling while keeping outbound `sendProxyProtocol` separate.
## 2026-06-04 - 27.12.7
### Fixes
- relay greetings before client data (socket-handler)
- Enable fast-path handling for simple port-only socket-handler routes without TLS.
- Add relay setup timeouts and cancellation while connecting to the socket-handler relay and sending setup data.
- Add regression coverage for socket-handler greetings sent before client data.
- exclude assets from npm package contents (package)
- Removes assets/**/* from the package files allowlist.
## 2026-06-03 - 27.12.6
### Fixes
- allow source-scoped catch-all routes with fallback routes (route-validator)
- Exclude source-scoped catch-all matches from duplicate catch-all conflict detection
- Add regression tests for source-scoped fallback routing and duplicate unscoped catch-all conflicts
## 2026-06-02 - 27.12.5
### Fixes
- preserve binary socket relay data and harden HTTP/1.1 backend pooling (proxy)
- Keep socket handler relay metadata parsing buffer-based so payload bytes after the metadata line are forwarded unchanged.
- Return HTTP/1.1 backend connections to the pool only after response bodies complete and skip pooling for close or upgrade responses.
- Retry stale pooled HTTP/1.1 backend connections for bodyless requests.
## 2026-06-01 - 27.12.4
### Fixes
- enforce route maxConnections across active HTTP streams and WebSocket tunnels (rustproxy-http)
- Adds route-level connection guards so maxConnections slots remain held until streamed response bodies or upgraded WebSocket tunnels close.
- Returns 429 for matched routes when maxConnections is exceeded without considering lower-priority fallback routes.
- Prunes stale route connection counters while preserving active slots across route updates.
- Adds coverage for streaming responses, route fallback behavior, and WebSocket tunnel limits.
## 2026-06-01 - 27.12.3
### Fixes
- add half-close integration tests for delayed backend responses (rustproxy-tests)
- Covers TCP, TLS passthrough, TLS termination, and terminate-and-reencrypt routes.
- Verifies backend responses are still delivered after the client sends FIN/EOF.
## 2026-05-31 - 27.12.2
### Fixes
- enforce per-IP limits using effective client IPs (rustproxy-passthrough)
- Reserve active connection slots atomically to prevent concurrent per-IP limit races.
- Apply per-IP and rate limits after PROXY protocol parsing for trusted proxy peers.
- Wait for complete PROXY protocol v1/v2 headers before parsing partial peeks.
- Preserve rate-limit timestamps after the last connection closes until normal cleanup.
## 2026-05-30 - 27.12.1
### Fixes
- export active connection snapshot types from package entry point (types)
- Expose IActiveConnectionSnapshot and IActiveConnectionSnapshotOptions through the root TypeScript exports.
## 2026-05-30 - 27.12.0
### Features
- expose active connection snapshots (smart-proxy)
- Add SmartProxy.getActiveConnectionSnapshots() with limit and routeId filters.
- Expose sanitized active connection metadata through the Rust management API.
- Track per-connection byte counters and target/protocol metadata for active TCP/TLS/QUIC connections.
## 2026-05-30 - 27.11.3
### Fixes
- preserve CA chains for provisioned certificates (certificates)
- Pass optional CA PEM from certProvisionFunction results to runtime certificate loading and certStore.save().
- Carry CA PEM through Rust TLS certificate configs so served certificates include intermediate chains.
- Treat CA chain changes as certificate updates for TLS hot-swap handling.
- Add regression coverage for CA chain preservation during load and storage.
## 2026-05-30 - 27.11.2
### Fixes
- support mixed port ranges in route matching (route-utils)
- Added reusable helpers to expand port ranges and check whether a range includes a port.
- Updated routeMatchesPort to support mixed arrays of individual ports and port range objects.
- Bumped development dependencies for tsbuild and Node.js types.
## 2026-05-29 - 27.11.1
### Fixes
- keep upgraded WebSocket tunnels on dedicated WebSocket lifecycle timeouts instead of the HTTP socket timeout (rustproxy)
- keep upgraded WebSocket tunnels on dedicated lifecycle timeouts (websocket)
- Track active upgraded tunnels so HTTP idle and max-lifetime watchdogs do not terminate WebSocket connections
- Use dedicated default WebSocket inactivity and max-lifetime timeouts in rustproxy passthrough listeners
- Add end-to-end coverage for idle WebSockets surviving short HTTP socket timeouts
## 2026-05-24 - 27.11.0
### Features
- add authenticated VPN route security from trusted PROXY v2 metadata (rustproxy)
- parses SmartVPN metadata TLVs alongside real client source IPs
- adds VPN client ID and assigned-IP allow lists separate from source-IP policy
- exposes authenticated VPN identity to TypeScript socket-handler route context
## 2026-05-20 - 27.10.3
### Fixes
- enable static CRT linking for Linux Rust targets (rust)
- adds crt-static rustflags for x86_64-unknown-linux-gnu
- adds crt-static rustflags alongside the existing aarch64 Linux cross-compilation linker configuration
## 2026-05-12 - 27.10.2
### Fixes
- no code changes to release (repo)
## 2026-05-12 - 27.10.1
### Fixes
- handle HTTP/3 backend forwarding failures with protocol fallback and pool cleanup (proxy-service)
- Retry bodyless requests over HTTP/1.1 when HTTP/3 forwarding fails in auto backend protocol mode
- Remove broken HTTP/3 pooled connections and record protocol cache failures to avoid repeated H3 reuse
- Add regression coverage for backends that advertise an unavailable Alt-Svc HTTP/3 endpoint
- Refresh documentation examples and API notes to reflect target-level load balancing and certificate provisioning event hooks
## 2026-04-30 - 27.10.0 - feat(exports)
export datagram handler types and align tests with updated nftables and route security APIs
- Exports TDatagramHandler and IDatagramInfo from the public index.
- Updates nftables integration tests for the new grouped status shape and null result after shutdown.
- Moves route IP allow list configuration to security and awaits the asynchronous listening ports API.
- Enables stricter TypeScript checks with noImplicitAny and safer error handling in tests.
## 2026-04-26 - 27.9.0 - feat(smart-proxy)
add hot-reloadable global ingress security policy across Rust and TypeScript proxy layers
- adds global securityPolicy config with blocked IP and CIDR support to SmartProxy and RustProxy options
- introduces management IPC support to update the security policy at runtime via setSecurityPolicy
- enforces the global block list early for TCP, UDP, and QUIC traffic before route selection and backend handling
## 2026-04-26 - 27.8.2 - fix(rustproxy-metrics)
retain inactive per-IP metric buckets briefly to capture final throughput before pruning
- adds a bounded retention window for closed IP buckets so short-lived transfers are still included in per-IP throughput sampling
- prunes expired inactive IP tracking by TTL and hard cap to prevent unbounded metric map growth
- updates Rust and throughput tests to expect zero active connections during the temporary retention period
## 2026-04-26 - 27.8.1 - fix(rustproxy-metrics)
preserve high-throughput IPs in metrics snapshots when active-connection rankings are saturated
- Select snapshot IPs using a blend of active-connection and throughput rankings instead of only active connections
- Adds a regression test to ensure a high-bandwidth IP remains included when many other IPs have more active connections
## 2026-04-14 - 27.8.0 - feat(metrics)
add per-domain HTTP request rate metrics
- Record canonicalized HTTP request rates per domain in the Rust metrics collector and expose per-second and last-minute values in snapshots.
- Add TypeScript metrics interfaces and adapter support for requests.byDomain().
- Cover HTTP domain rate tracking and ensure TLS passthrough SNI traffic does not affect HTTP request rate metrics.
## 2026-04-14 - 27.7.4 - fix(rustproxy metrics)
use stable route metrics keys across HTTP and passthrough listeners
- adds a shared RouteConfig::metrics_key helper that prefers route name and falls back to route id
- updates HTTP, TCP, UDP, and QUIC metrics labeling to use the shared route metrics key consistently
- keeps route cancellation and rate limiter indexing bound to route config ids where required
- adds tests covering metrics key selection behavior
## 2026-04-14 - 27.7.3 - fix(repo)
no changes detected
## 2026-04-14 - 27.7.2 - fix(docs)
clarify metrics documentation for domain normalization and saturating gauges
- Document that per-IP domain keys are normalized to lowercase and have trailing dots stripped before counting.
- Clarify that the saturating close pattern also applies to connection and UDP active gauges.
## 2026-04-14 - 27.7.1 - fix(rustproxy-http,rustproxy-metrics)
fix domain-scoped request host detection and harden connection metrics cleanup
- use a shared request host extractor that falls back to URI authority so domain-scoped IP allow lists work for HTTP/2 and HTTP/3 requests without a Host header
- add request filter and host extraction tests covering domain-scoped ACL behavior
- prevent connection counters from underflowing during close handling and clean up per-IP metrics entries more safely
- normalize tracked domain keys in metrics to reduce duplicate entries caused by case or trailing-dot variations
## 2026-04-13 - 27.7.0 - feat(smart-proxy)
add typed Rust config serialization and regex header contract coverage
- serialize SmartProxy routes and top-level options into explicit Rust-safe types, including header regex literals, UDP field normalization, ACME, defaults, and proxy settings
- support JS-style regex header literals with flags in Rust header matching and add cross-contract tests for route preprocessing and config deserialization
- improve TypeScript safety for Rust bridge and metrics integration by replacing loose any-based payloads with dedicated Rust type definitions
## 2026-04-13 - 27.6.0 - feat(metrics)
track per-IP domain request metrics across HTTP and TCP passthrough traffic
- records domain request counts per frontend IP from HTTP Host headers and TCP SNI
- exposes per-IP domain maps and top IP-domain request pairs through the TypeScript metrics adapter
- bounds per-IP domain tracking and prunes stale entries to limit memory growth
- adds metrics system documentation covering architecture, collected data, and known gaps
## 2026-04-06 - 27.5.0 - feat(security)
add domain-scoped IP allow list support across HTTP and passthrough filtering
- extend route security types to accept IP allow entries scoped to specific domains
- apply domain-aware IP checks using Host headers for HTTP and SNI context for QUIC and passthrough connections
- preserve compatibility for existing plain allow list entries and add validation and tests for scoped matching
## 2026-04-04 - 27.4.0 - feat(rustproxy)
add HTTP/3 proxy service wiring for QUIC listeners
- registers H3ProxyService with the UDP listener manager so QUIC connections can serve HTTP/3
- keeps proxy IP configuration intact while enabling HTTP/3 handling during listener setup
## 2026-04-04 - 27.3.1 - fix(metrics)
correct frontend and backend protocol connection tracking across h1, h2, h3, and websocket traffic
- move frontend protocol accounting from per-request to connection lifetime tracking for HTTP/1, HTTP/2, and HTTP/3
- add backend protocol guards to connection drivers so active protocol metrics reflect live upstream connections
- prevent protocol counter underflow by using atomic saturating decrements in the metrics collector
- read backend protocol distribution directly from cached aggregate counters in the Rust metrics adapter
## 2026-04-04 - 27.3.0 - feat(test)
add end-to-end WebSocket proxy test coverage
- add comprehensive WebSocket e2e tests for upgrade handling, bidirectional messaging, header forwarding, close propagation, and large payloads
- add ws and @types/ws as development dependencies to support the new test suite
## 2026-04-04 - 27.2.0 - feat(metrics)
add frontend and backend protocol distribution metrics
- track active and total frontend protocol counts for h1, h2, h3, websocket, and other traffic
- add backend protocol counters with RAII guards to ensure metrics are decremented on all exit paths
- expose protocol distribution through the TypeScript metrics interfaces and Rust metrics adapter
## 2026-03-27 - 27.1.0 - feat(rustproxy-passthrough)
add selective connection recycling for route, security, and certificate updates
- introduce a shared connection registry to track active TCP and QUIC connections by route, source IP, and domain
- recycle only affected connections when route actions or security rules change instead of broadly invalidating traffic
- gracefully recycle existing connections when TLS certificates change for a domain
- apply route-level IP security checks to QUIC connections and share route cancellation state with UDP listeners
## 2026-03-26 - 27.0.0 - BREAKING CHANGE(smart-proxy)
remove route helper APIs and standardize route configuration on plain route objects
- Removes TypeScript route helper exports and related Rust config helpers in favor of defining routes directly with match and action properties.
- Updates documentation and tests to use plain IRouteConfig objects and SocketHandlers imports instead of helper factory functions.
- Moves socket handlers to a top-level utils export and keeps direct socket-handler route configuration as the supported pattern.
## 2026-03-26 - 26.3.0 - feat(nftables)
move NFTables forwarding management from the Rust engine to @push.rocks/smartnftables
- add @push.rocks/smartnftables as a runtime dependency and export it via the plugin layer
- remove the internal rustproxy-nftables crate along with Rust-side NFTables rule application and status management
- apply and clean up NFTables port-forwarding rules in the TypeScript SmartProxy lifecycle and route update flow
- change getNfTablesStatus to return local smartnftables status instead of querying the Rust bridge
- update README documentation to describe NFTables support as provided through @push.rocks/smartnftables
## 2026-03-26 - 26.2.4 - fix(rustproxy-http)
improve HTTP/3 connection reuse and clean up stale proxy state
- Reuse pooled HTTP/3 SendRequest handles to skip repeated SETTINGS handshakes and reduce request overhead on QUIC pool hits
- Add periodic cleanup for per-route rate limiters and orphaned backend metrics to prevent unbounded memory growth after traffic or backend errors stop
- Enforce HTTP max connection lifetime alongside idle timeouts and apply configured lifetime values from the TCP listener
- Reduce HTTP/3 body copying by using owned Bytes paths for request and response streaming, and replace the custom response body adapter with a stream-based implementation
- Harden auxiliary proxy components by capping datagram handler buffer growth and removing duplicate RustProxy exit listeners
## 2026-03-25 - 26.2.3 - fix(repo)
no changes to commit
## 2026-03-25 - 26.2.2 - fix(proxy)
improve connection cleanup and route validation handling
- add timeouts for HTTP/1 upstream connection drivers to prevent lingering tasks
- ensure QUIC relay sessions cancel and abort background tasks on drop
- avoid registering unnamed routes as duplicates and label unnamed catch-all conflicts clearly
- fix offset mapping route helper to forward only remaining route options without overriding derived values
- update project config filename and toolchain versions for the current build setup
## 2026-03-23 - 26.2.1 - fix(rustproxy-http)
include the upstream request URL when caching H3 Alt-Svc discoveries
- Tracks the request path that triggered Alt-Svc discovery in connection activity state
- Adds request URL context to Alt-Svc debug logging and protocol cache insertion reasons for better traceability
## 2026-03-23 - 26.2.0 - feat(protocol-cache)
add sliding TTL re-probing and eviction for backend protocol detection
- extend protocol cache entries and metrics with last accessed and last probed timestamps
- trigger periodic ALPN re-probes for cached H1/H2 entries while keeping active entries alive with a sliding 1 day TTL
- log protocol transitions with reasons and evict cache entries when all protocol fallback attempts fail
## 2026-03-22 - 26.1.0 - feat(rustproxy-http)
add protocol failure suppression, h3 fallback escalation, and protocol cache metrics exposure
- introduces escalating cooldowns for failed H2/H3 protocol detection to prevent repeated upgrades to unstable backends
- adds within-request escalation to cached HTTP/3 when TCP or TLS backend connections fail in auto-detect mode
- exposes detected protocol cache entries and suppression state through Rust metrics and the TypeScript metrics adapter
## 2026-03-21 - 26.0.0 - BREAKING CHANGE(ts-api,rustproxy)
remove deprecated TypeScript protocol and utility exports while hardening QUIC, HTTP/3, WebSocket, and rate limiter cleanup paths
- Removes large parts of the public TypeScript surface including detection, TLS, router, websocket, proxy/common protocol, and multiple core utility exports and files.
- Adds parent-child cancellation handling for HTTP/3 and QUIC stream forwarding to stop orphaned tasks and close idle or overlong streams.
- Improves cleanup reliability with RAII guards for WebSocket upstream tracking and QUIC connection metrics, plus periodic cleanup for rate limiter and proxy address maps.
- Cleans backend metrics state when active backend connections drop to zero and tracks passthrough backend sockets for shutdown cleanup.
## 2026-03-20 - 25.17.10 - fix(rustproxy-http)
reuse the shared HTTP proxy service for HTTP/3 request handling
- Refactors H3ProxyService to delegate requests to the shared HttpProxyService instead of maintaining separate routing and backend forwarding logic.
- Aligns HTTP/3 with the TCP/HTTP path for route matching, connection pooling, and ALPN-based upstream protocol detection.
- Generalizes request handling and filters to accept boxed/generic HTTP bodies so both HTTP/3 and existing HTTP paths share the same proxy pipeline.
- Updates the HTTP/3 integration route matcher to allow transport matching across shared HTTP and QUIC handling.
## 2026-03-20 - 25.17.9 - fix(rustproxy-http)
correct HTTP/3 host extraction and avoid protocol filtering during UDP route lookup
- Use the URI host or strip the port from the Host header so HTTP/3 requests match routes consistently with TCP/HTTP handling.
- Remove protocol filtering from HTTP/3 route lookup because QUIC transport already constrains routing to UDP and protocol validation happens earlier.
## 2026-03-20 - 25.17.8 - fix(rustproxy)
use SNI-based certificate resolution for QUIC TLS connections
- Replaces static first-certificate selection with the shared CertResolver used by the TCP/TLS path.
- Ensures QUIC connections can present the correct certificate per requested domain.
- Keeps HTTP/3 ALPN configuration while improving multi-domain TLS handling.
## 2026-03-20 - 25.17.7 - fix(readme)
document QUIC and HTTP/3 compatibility caveats
- Add notes explaining that GREASE frames are disabled on both server and client HTTP/3 paths to avoid interoperability issues
- Document that the current HTTP/3 stack depends on pre-1.0 h3 ecosystem components and may still have rough edges
## 2026-03-20 - 25.17.6 - fix(rustproxy-http)
disable HTTP/3 GREASE for client and server connections
- Switch the HTTP/3 server connection setup to use the builder API with send_grease(false)
- Switch the HTTP/3 client handshake to use the builder API with send_grease(false) to improve compatibility
## 2026-03-20 - 25.17.5 - fix(rustproxy)
add HTTP/3 integration test for QUIC response stream FIN handling
- adds an integration test covering HTTP/3 proxying over QUIC with TLS termination
- verifies response bodies fully arrive and the client receives stream termination instead of hanging
- adds test-only dependencies for quinn, h3, h3-quinn, rustls, bytes, and http
## 2026-03-20 - 25.17.4 - fix(rustproxy-http)
prevent HTTP/3 response body streaming from hanging on backend completion
- extract and track Content-Length before consuming the response body
- stop the HTTP/3 body loop when the stream reports end-of-stream or the expected byte count has been sent
- add a per-frame idle timeout to avoid indefinite waits on stalled or close-delimited backend bodies
## 2026-03-20 - 25.17.3 - fix(repository)
no changes detected
## 2026-03-20 - 25.17.2 - fix(rustproxy-http)
enable TLS connections for HTTP/3 upstream requests when backend re-encryption or TLS is configured
- Pass backend TLS client configuration into the HTTP/3 request handler.
- Detect TLS-required upstream targets using route and target TLS settings before connecting.
- Build backend request URIs with the correct http or https scheme to match the upstream connection.
## 2026-03-20 - 25.17.1 - fix(rustproxy-routing)
allow QUIC UDP TLS connections without SNI to match domain-restricted routes
- Exempts UDP transport from the no-SNI rejection logic because QUIC encrypts the TLS ClientHello and SNI is unavailable at accept time
- Adds regression tests to confirm QUIC route matching succeeds without SNI while TCP TLS without SNI remains rejected
## 2026-03-19 - 25.17.0 - feat(rustproxy-passthrough)
add PROXY protocol v2 client IP handling for UDP and QUIC listeners
- propagate trusted proxy IP configuration into UDP and QUIC listener managers
- extract and preserve real client addresses from PROXY protocol v2 headers for HTTP/3 and QUIC stream handling
- apply rate limiting, session limits, routing, and metrics using the resolved client IP while preserving correct proxy return-path routing
## 2026-03-19 - 25.16.3 - fix(rustproxy)
upgrade fallback UDP listeners to QUIC when TLS certificates become available
- Rebuild and apply QUIC TLS configuration during route and certificate updates instead of only when adding new UDP ports.
- Add logic to drain UDP sessions, stop raw fallback listeners, and start QUIC endpoints on existing ports once TLS is available.
- Retry QUIC endpoint creation during upgrade and fall back to rebinding raw UDP if the upgrade cannot complete.
## 2026-03-19 - 25.16.2 - fix(rustproxy-http)
cache backend Alt-Svc only from original upstream responses during protocol auto-detection
- Moves Alt-Svc discovery into streaming response construction so it reads backend headers before response filters inject client-facing Alt-Svc values
- Stores the protocol cache key in connection activity during auto-detect mode and clears it after HTTP/3 connection failure to avoid re-caching failed H3 routes
- Prevents fallback requests from reintroducing stale or self-injected Alt-Svc entries that could cause repeated H3 retry loops
## 2026-03-19 - 25.16.1 - fix(http-proxy)
avoid repeated HTTP/3 recaching after QUIC fallback and document backend protocol selection
- Suppress Alt-Svc HTTP/3 recaching after a failed QUIC backend connection to prevent repeated H3 timeout fallback loops
- Force an ALPN probe on TCP fallback so auto detection correctly reselects HTTP/2 or HTTP/1.1 after H3 connection failure
- Add README documentation for best-effort backendProtocol selection and supported protocol modes
## 2026-03-19 - 25.16.0 - feat(quic,http3)
add HTTP/3 proxy handling and hot-reload QUIC TLS configuration
- initialize and wire H3ProxyService into QUIC listeners so HTTP/3 requests are handled instead of being kept as placeholder connections
- add backend HTTP/3 support with protocol caching that stores Alt-Svc advertised H3 ports for auto-detection
- hot-swap TLS certificates across active QUIC endpoints and require terminating TLS for QUIC route validation
- document QUIC route setup with required TLS and ACME configuration
## 2026-03-19 - 25.15.0 - feat(readme)
document UDP, QUIC, and HTTP/3 support in the README
- Adds README examples for UDP datagram handlers, QUIC/HTTP3 forwarding, and dual-stack TCP/UDP routes
- Expands configuration and API reference sections to cover transport matching, UDP/QUIC options, backend transport selection, and UDP metrics
- Updates architecture and feature descriptions to reflect UDP, QUIC, HTTP/3, and datagram handler capabilities
## 2026-03-19 - 25.14.1 - fix(deps)
update build and runtime dependencies and align route validation test expectations
- split the test preparation step into a dedicated test:before script while keeping test execution separate
- bump development tooling and runtime package versions in package.json
- adjust the route validation test to match the current generic handler error message
## 2026-03-19 - 25.14.0 - feat(udp,http3)
add UDP datagram handler relay support and stream HTTP/3 request bodies to backends
- establish a persistent Unix socket relay for UDP datagram handlers and process handler replies back to clients
- update route validation and smart proxy route reload logic to support datagramHandler routes
- record UDP, QUIC, and HTTP/3 byte metrics more accurately, including request bytes in and UDP session cleanup connection tracking
- add integration tests for UDP forwarding, datagram handlers, and UDP metrics
## 2026-03-19 - 25.13.0 - feat(smart-proxy)
add UDP transport support with QUIC/HTTP3 routing and datagram handler relay
- adds UDP listener and session tracking infrastructure in the Rust proxy, including UDP metrics and hot-reload support for transport-specific ports
- introduces QUIC and HTTP/3 support in routing and HTTP handling, including Alt-Svc advertisement and QUIC TLS configuration
- extends route configuration types in Rust and TypeScript with transport, UDP, QUIC, backend transport, and mixed port range support
- adds a TypeScript datagram handler relay server and bridge command so UDP socket-handler routes can dispatch datagrams to application callbacks
- updates nftables rule generation so protocol=all creates both TCP and UDP rules
## 2026-03-19 - 25.12.0 - feat(proxy-protocol)
add PROXY protocol v2 support to the Rust passthrough listener and streamline TypeScript proxy protocol exports
- detect and parse PROXY protocol v2 headers in the Rust TCP listener, including TCP and UDP address families
- add Rust v2 header generation, incomplete-header handling, and broader parser test coverage
- remove deprecated TypeScript proxy protocol parser exports and tests, leaving shared type definitions only
## 2026-03-17 - 25.11.24 - fix(rustproxy-http)
improve async static file serving, websocket handshake buffering, and shared metric metadata handling
- convert static file serving to async filesystem operations and await directory/file checks
- preserve and forward bytes read past the WebSocket handshake header terminator to avoid dropping buffered upstream data
- reuse Arc<str> values for route and source identifiers across counting bodies and metric reporting
- standardize backend key propagation across H1/H2 forwarding, retry, and fallback paths for consistent logging and metrics
## 2026-03-17 - 25.11.23 - fix(rustproxy-http,rustproxy-metrics)
reduce per-frame metrics overhead by batching body byte accounting
- Buffer HTTP body byte counts and flush them every 64 KB, at end of stream, and on drop to keep totals accurate while preserving throughput sampling.
- Skip zero-value counter updates in metrics collection to avoid unnecessary atomic and DashMap operations for the unused direction.
## 2026-03-17 - 25.11.22 - fix(rustproxy-http)
reuse healthy HTTP/2 upstream connections after requests with bodies
- Registers successful HTTP/2 connections in the pool regardless of whether the proxied request included a body
- Continues to avoid pooling upstream connections that returned 502 Bad Gateway responses
## 2026-03-17 - 25.11.21 - fix(rustproxy-http)
reuse pooled HTTP/2 connections for requests with and without bodies
- remove the bodyless-request restriction from HTTP/2 pool checkout
- always return successful HTTP/2 senders to the connection pool after requests
## 2026-03-17 - 25.11.20 - fix(rustproxy-http)
avoid downgrading cached backend protocol on H2 stream errors
- Treat HTTP/2 stream-level failures as retryable request errors instead of evidence that the backend only supports HTTP/1.1
- Keep protocol cache entries unchanged after successful H2 handshakes so future requests continue using HTTP/2
- Lower log severity for this fallback path from warning to debug while still recording backend H2 failure metrics
## 2026-03-16 - 25.11.19 - fix(rustproxy-http)
avoid reusing pooled HTTP/2 connections for requests with bodies to prevent upload flow-control stalls
- Limit HTTP/2 pool checkout to bodyless requests such as GET, HEAD, and DELETE
- Skip re-registering HTTP/2 connections in the pool after requests that send a body
- Prevent stalled uploads caused by depleted connection-level flow control windows on reused HTTP/2 connections
## 2026-03-16 - 25.11.18 - fix(repo)
no changes to commit
## 2026-03-16 - 25.11.17 - fix(rustproxy-http)
prevent stale HTTP/2 connection drivers from evicting newer pooled connections
- add generation IDs to pooled HTTP/2 senders so pool removal only affects the matching connection
- update HTTP/2 proxy and retry paths to register generation-tagged connections and skip eviction before registration completes
## 2026-03-16 - 25.11.16 - fix(repo)
no changes to commit
## 2026-03-16 - 25.11.15 - fix(rustproxy-http)
implement vectored write support for backend streams
- Add poll_write_vectored forwarding for both plain and TLS backend stream variants
- Expose is_write_vectored so the proxy can correctly report vectored write capability
## 2026-03-16 - 25.11.14 - fix(rustproxy-http)
forward vectored write support in ShutdownOnDrop AsyncWrite wrapper
- Implements poll_write_vectored by delegating to the wrapped writer
- Exposes is_write_vectored so the wrapper preserves underlying AsyncWrite capabilities
## 2026-03-16 - 25.11.13 - fix(rustproxy-http)
remove hot-path debug logging from HTTP/1 connection pool hits
- Stops emitting debug logs when reusing HTTP/1 idle connections in the connection pool.
- Keeps pool hit behavior unchanged while reducing overhead on a frequently executed path.
## 2026-03-16 - 25.11.12 - fix(rustproxy-http)
remove connection pool hit logging and keep logging limited to actual failures
- Removes debug and warning logs for HTTP/2 connection pool hits and age checks.
- Keeps pool behavior unchanged while reducing noisy per-request logging in the Rust HTTP proxy layer.
## 2026-03-16 - 25.11.11 - fix(rustproxy-http)
improve HTTP/2 proxy error logging with warning-level connection failures and debug error details
- Adds debug-formatted error fields to HTTP/2 handshake, retry, fallback, and request failure logs
- Promotes upstream HTTP/2 connection error logs from debug to warn to improve operational visibility
## 2026-03-16 - 25.11.10 - fix(rustproxy-http)
validate pooled HTTP/2 connections asynchronously before reuse and evict stale senders
- Add an async ready() check with a 500ms timeout before reusing pooled HTTP/2 senders to catch GOAWAY/RST states before forwarding requests
- Return connection age from the HTTP/2 pool checkout path and log warnings for older pooled connections
- Evict pooled HTTP/2 senders when they are closed, exceed max age, fail readiness validation, or time out during readiness checks
## 2026-03-16 - 25.11.9 - fix(rustproxy-routing)
reduce hot-path allocations in routing, metrics, and proxy protocol handling
- skip HTTP header map construction unless a route on the current port uses header matching
- reuse computed client IP strings during HTTP route matching to avoid redundant allocations
- optimize per-route and per-IP metric updates with get-first lookups to avoid unnecessary String creation on existing entries
- replace heap-allocated PROXY protocol peek and discard buffers with stack-allocated buffers in the TCP listener
- improve domain matcher case-insensitive wildcard checks while preserving glob fallback behavior
## 2026-03-16 - 25.11.8 - fix(rustproxy-http)
prevent premature idle timeouts during streamed HTTP responses and ensure TLS close_notify is sent on dropped connections
- track active streaming response bodies so the HTTP idle watchdog does not close connections mid-transfer
- add a ShutdownOnDrop wrapper for TLS-terminated HTTP connections to send shutdown on drop and avoid improperly terminated TLS sessions
- apply the shutdown wrapper in passthrough TLS terminate and terminate+reencrypt HTTP handling
## 2026-03-16 - 25.11.7 - fix(rustproxy)
prevent TLS route reload certificate mismatches and tighten passthrough connection handling
- Load updated TLS configs before swapping the route manager so newly visible routes always have their certificates available.
- Add timeouts when peeking initial decrypted data after TLS handshake to avoid leaked idle connections.
- Raise dropped, blocked, unmatched, and errored passthrough connection events from debug to warn for better operational visibility.
## 2026-03-16 - 25.11.6 - fix(rustproxy-http,rustproxy-passthrough)
improve upstream connection cleanup and graceful tunnel shutdown
- Evict pooled HTTP/2 connections when their driver exits and shorten the maximum pooled H2 age to reduce reuse of stale upstream connections.
- Strip hop-by-hop headers from backend responses before forwarding to HTTP/2 clients to avoid invalid H2 response handling.
- Replace immediate task aborts in WebSocket and TCP tunnel watchdogs with cancellation-driven graceful shutdown plus timed fallback aborts.
- Use non-blocking semaphore acquisition in the TCP listener so connection limits do not stall the accept loop for the entire port.
## 2026-03-16 - 25.11.5 - fix(repo)
no changes to commit
## 2026-03-15 - 25.11.4 - fix(rustproxy-http)
report streamed HTTP and WebSocket bytes per chunk for real-time throughput metrics
- Update CountingBody to record bytes immediately on each data frame instead of aggregating until completion or drop
- Record WebSocket tunnel traffic inside both copy loops and remove the final aggregate byte report to keep throughput metrics current
## 2026-03-15 - 25.11.3 - fix(repo)
no changes to commit
## 2026-03-15 - 25.11.2 - fix(rustproxy-http)
avoid reusing HTTP/1 senders during streaming responses and relax HTTP/2 keep-alive timeouts
- Stop returning HTTP/1 senders to the connection pool before upstream response bodies finish streaming to prevent unsafe reuse on active connections.
- Increase HTTP/2 keep-alive timeout from 5 seconds to 30 seconds in proxy connection builders to better support longer-lived backend streams.
- Improves reliability for large streaming payloads and backend fallback request handling.
## 2026-03-15 - 25.11.1 - fix(rustproxy-http)
keep connection idle tracking alive during streaming and tune HTTP/2 connection lifetimes
- Propagate connection activity tracking through HTTP/1, HTTP/2, and WebSocket forwarding so active request and response body streams do not trigger the idle watchdog.
- Update CountingBody to refresh connection activity timestamps while data frames are polled during uploads and downloads.
- Increase pooled HTTP/2 max age and set explicit HTTP/2 connection window sizes to improve long-lived streaming behavior.
## 2026-03-15 - 25.11.0 - feat(rustproxy-http)
add HTTP/2 Extended CONNECT WebSocket proxy support
- Enable HTTP/2 CONNECT protocol support on the Hyper auto connection builder
- Detect WebSocket requests for both HTTP/1 Upgrade and HTTP/2 Extended CONNECT flows
- Translate HTTP/2 WebSocket requests to an HTTP/1.1 backend handshake and return RFC-compliant client responses
## 2026-03-12 - 25.10.7 - fix(rustproxy-http)
remove Host header from HTTP/2 upstream requests while preserving it for HTTP/1 retries
- strips the Host header before sending HTTP/2 upstream requests so :authority from the URI is used instead
- avoids 400 responses from nginx caused by sending both Host and :authority headers
- keeps a cloned header set for bodyless request retries so HTTP/1 fallback still retains the Host header
## 2026-03-12 - 25.10.6 - fix(rustproxy-http)
use the requested domain as HTTP/2 authority instead of the backend host and port
- build HTTP/2 absolute URIs from the client-facing domain so the :authority pseudo-header matches the Host header
- remove backend port from generated HTTP/2 request URIs and fall back to the upstream host only when no domain is available
- apply the authority handling consistently across pooled, inline, and generic upstream request paths
## 2026-03-12 - 25.10.5 - fix(rustproxy-http)
configure HTTP/2 client builders with a Tokio timer for keep-alive handling
- Adds TokioTimer to all HTTP/2 client builder instances in proxy_service.
- Ensures configured HTTP/2 keep-alive interval and timeout settings have the required timer runtime support.
## 2026-03-12 - 25.10.4 - fix(rustproxy-http)
stabilize upstream HTTP/2 forwarding and fallback behavior
- Remove hop-by-hop headers before forwarding requests to HTTP/2 backends to comply with RFC 9113.
- Use ALPN-enabled TLS configuration whenever HTTP/2 is possible, including explicit H2 connections and retries.
- Add HTTP/2 handshake timeouts, tuned connection settings, and fallback to HTTP/1 when H2 negotiation times out or fails.
- Register pooled HTTP/2 senders only after a successful first request to avoid reusing broken connections.
- Build absolute URIs for HTTP/2 upstream requests so pseudo-headers such as scheme and authority are derived correctly.
## 2026-03-12 - 25.10.3 - fix(rustproxy-http)
include request domain in backend proxy error and protocol detection logs
- Adds domain context to backend TCP/TLS connect, handshake, request failure, retry, and fallback log entries in the Rust HTTP proxy service.
- Propagates the resolved host/domain through H1, H2, pooled, and fallback forwarding paths so backend-level diagnostics can be correlated with the original request domain.
## 2026-03-12 - 25.10.2 - fix(repo)
no code changes to release
## 2026-03-12 - 25.10.1 - fix(repo)
no changes to commit
## 2026-03-12 - 25.10.0 - feat(metrics)
add per-backend connection, error, protocol, and pool metrics with stale backend pruning
- tracks backend connection lifecycle, connect timing, protocol detection, pool hit/miss rates, handshake/request errors, and h2 fallback failures in Rust metrics
- exposes backend metrics through the TypeScript metrics adapter with backend listings, protocol lookup, and top error summaries
- prunes backend metrics for backends no longer referenced by active routes, including preserved-port targets expanded across listening ports
## 2026-03-11 - 25.9.3 - fix(rustproxy-http)
Evict stale HTTP/2 pooled senders and retry bodyless requests with fresh backend connections to avoid 502s
- Introduce MAX_H2_AGE (120s) and evict HTTP/2 senders older than this or closed
- Check MAX_H2_AGE on checkout and during background eviction to prevent reuse of stale h2 connections
- Add connection_pool.remove_h2() to explicitly remove dead H2 senders from the pool
- When a pooled H2 request returns a 502 and the original request had an empty body, retry using a fresh H2 connection (retry_h2_with_fresh_connection)
- On H2 auto-detect failures, retry as HTTP/1.1 for bodyless requests via forward_h1_empty_body; return 502 for requests with bodies
- Evict dead H2 senders on backend request failures in reconnect_backend so subsequent attempts create fresh connections
## 2026-03-08 - 25.9.2 - fix(protocol-cache)
Include requested_host in protocol detection cache key to avoid cache oscillation when multiple frontend domains share the same backend
- Add ProtocolCacheKey.requested_host: Option<String> to distinguish cache entries by incoming request Host/:authority
- Update protocol cache lookups/inserts in proxy_service to populate requested_host
- Enhance debug logging to show requested_host on cache hits
- Fixes repeated ALPN probing / cache oscillation when different frontend domains share a backend with differing HTTP/2 support
## 2026-03-03 - 25.9.1 - fix(rustproxy)
Cancel connections for routes removed/disabled by adding per-route cancellation tokens and make RouteManager swappable (ArcSwap) for runtime updates
- Add per-route CancellationToken map (DashMap) to TcpListenerManager and call token.cancel() when routes are removed (invalidate_removed_routes)
- Propagate Arc<ArcSwap<RouteManager>> into HttpProxyService and passthrough listener so the route manager can be hot-swapped without restarting listeners
- Use per-route child cancellation tokens in accept/connection handling and forwarders to terminate existing connections when a route is removed
- Prune HTTP proxy caches and retain/cleanup per-route tokens when routes are active/removed
- Update test.test.sni-requirement.node.ts to allocate unique free ports via findFreePorts to avoid port conflicts during tests
## 2026-03-03 - 25.9.0 - feat(rustproxy-http)
add HTTP/2 auto-detection via ALPN with TTL-backed protocol cache and h1-only/h2 ALPN client configs
- Add protocol_cache module: bounded, TTL-based cache (5min TTL), max entries (4096), background cleanup task and clear() to discard stale detections.
- Introduce BackendProtocol::Auto and expose 'auto' in TypeScript route types to allow ALPN-based protocol auto-detection.
- Add build_tls_acceptor_h1_only() to create a TLS acceptor that advertises only http/1.1 (used for backends/tests that speak plain HTTP/1.1).
- Add shared_backend_tls_config_alpn() and default_backend_tls_config_with_alpn() to provide client TLS configs advertising h2+http/1.1 for auto-detection.
- Wire backend_tls_config_alpn and protocol_cache into proxy_service, tcp_listener and passthrough paths; add set_backend_tls_config_alpn() and prune protocol_cache on route updates.
- Update passthrough tests to use h1-only acceptor to avoid false HTTP/2 detection when backends speak plain HTTP/1.1.
- Include reconnection/fallback handling and ensure ALPN-enabled client config is used for auto-detection mode.
## 2026-02-26 - 25.8.5 - fix(release)
bump patch version (no source changes)
- No changes detected in git diff
- Current version: 25.8.4
- Recommend patch bump to 25.8.5 to record release without code changes
## 2026-02-26 - 25.8.4 - fix(proxy)
adjust default proxy timeouts and keep-alive behavior to shorter, more consistent values
- Increase connection timeout default from 30,000ms to 60,000ms (30s -> 60s).
- Reduce socket timeout default from 3,600,000ms to 60,000ms (1h -> 60s).
- Reduce max connection lifetime default from 86,400,000ms to 3,600,000ms (24h -> 1h).
- Change inactivity timeout default from 14,400,000ms to 75,000ms (4h -> 75s).
- Update keep-alive defaults: keepAliveTreatment 'extended' -> 'standard', keepAliveInactivityMultiplier 6 -> 4, extendedKeepAliveLifetime 604800000 -> 3,600,000ms (7d -> 1h).
- Apply these consistent default values across Rust crates (rustproxy-config, rustproxy-passthrough) and the TypeScript smart-proxy implementation.
- Update unit test expectations to match the new defaults.
## 2026-02-26 - 25.8.3 - fix(smartproxy)
no code or dependency changes detected; no version bump required
- No files changed in the provided diff (No changes).
- package.json version remains 25.8.2.
- No dependency or source updates detected; skip release.
## 2026-02-26 - 25.8.2 - fix(connection)
improve connection handling and timeouts
- Flush logs on process beforeExit and avoid calling process.exit in SIGINT/SIGTERM handlers to preserve host graceful shutdown
- Store protocol entries with a createdAt timestamp in ProtocolDetector and remove stale entries older than 30s to prevent leaked state from abandoned handshakes or port scanners
- Add backend connect timeout (30s) and idle timeouts (5 minutes) for dynamic forwards; destroy sockets on timeout and emit logs for timeout events
## 2026-02-25 - 25.8.1 - fix(allocator)
switch global allocator from tikv-jemallocator to mimalloc
- Replaced tikv-jemallocator with mimalloc in rust/Cargo.toml workspace dependencies.
- Updated rust/crates/rustproxy/Cargo.toml to use mimalloc as a workspace dependency.
- Updated rust/Cargo.lock: added mimalloc and libmimalloc-sys entries and removed tikv-jemallocator and tikv-jemalloc-sys entries.
- Changed the global allocator in crates/rustproxy/src/main.rs from tikv_jemallocator::Jemalloc to mimalloc::MiMalloc.
- Impact: runtime memory allocator is changed which may affect memory usage and performance; no public API changes but recommend testing memory/performance in deployments.
## 2026-02-24 - 25.8.0 - feat(rustproxy)
use tikv-jemallocator as the global allocator to reduce glibc fragmentation and slow RSS growth; add allocator dependency and enable it in rustproxy, update lockfile, and run tsrust before tests
- Added tikv-jemallocator dependency to rust/Cargo.toml and rust/crates/rustproxy/Cargo.toml
- Enabled tikv_jemallocator as the global allocator in rust/crates/rustproxy/src/main.rs
- Updated rust/Cargo.lock with tikv-jemallocator and tikv-jemalloc-sys entries
- Modified package.json test script to run tsrust before tstest
## 2026-02-24 - 25.7.10 - fix(rustproxy)
Use cooperative cancellation for background tasks, prune stale caches and metric entries, and switch tests to dynamic port allocation to avoid port conflicts
- Introduce tokio_util::sync::CancellationToken to coordinate graceful shutdown of sampling and renewal tasks; await handles on stop and reset the token so the proxy can be restarted.
- Add safety Drop impls (RustProxy, TcpListenerManager) as a last-resort abort path when stop() is not called.
- MetricsCollector: avoid creating per-IP metric entries when the IP has no active connections; prune orphaned per-IP metric maps during sampling; add tests covering late record_bytes races and pruning behavior.
- Passthrough/ConnectionTracker: remove per-connection record/zombie-scanner complexity, add cleanup_stale_timestamps to prune rate-limit timestamp entries, and add an RAII ConnectionTrackerGuard to guarantee connection_closed is invoked.
- HTTP proxy improvements: add prune_stale_routes and reset_round_robin to clear caches (rate limiters, regex cache, round-robin counters) on route updates.
- Tests: add test/helpers/port-allocator.ts and update many tests to use findFreePorts/assertPortsFree (dynamic ports + post-test port assertions) to avoid flakiness and port collisions in CI.
## 2026-02-21 - 25.7.9 - fix(tests)
use high non-privileged ports in tests to avoid conflicts and CI failures
- Updated multiple test files to use high-range, non-privileged ports instead of well-known or conflicting ports.
- Files changed: test/test.acme-http01-challenge.ts, test/test.connection-forwarding.ts, test/test.forwarding-regression.ts, test/test.http-port8080-forwarding.ts, test/test.port-mapping.ts, test/test.smartproxy.ts, test/test.socket-handler.ts.
- Notable port remappings: 8080/8081 -> 47730/47731 (and other proxy ports like 47710), 8443 -> 47711, 7001/7002 -> 47712/47713, 9090 -> 47721, 8181/8182 -> 47732/47733, 9999 -> 47780, TEST_PORT_START/PROXY_PORT_START -> 47750/48750, and TEST_SERVER_PORT/PROXY_PORT -> 47770/47771.
## 2026-02-19 - 25.7.8 - fix(no-changes)
no changes detected; nothing to release
- Current package version: 25.7.7
- Git diff: no changes
- No files modified; no release necessary
## 2026-02-19 - 25.7.7 - fix(proxy)
restrict PROXY protocol parsing to configured trusted proxy IPs and parse PROXY headers before metrics/fast-path so client IPs reflect the real source
- Add proxy_ips: Vec<std::net::IpAddr> to ConnectionConfig with a default empty Vec
- Populate proxy_ips from options.proxy_ips strings in rust/crates/rustproxy/src/lib.rs, parsing each to IpAddr
- Only peek for and parse PROXY v1 headers when the remote IP is contained in proxy_ips (prevents untrusted clients from injecting PROXY headers)
- Move PROXY protocol parsing earlier so metrics and fast-path logic use the effective (real client) IP after PROXY parsing
- If proxy_ips is empty, behavior remains unchanged (no PROXY parsing)
## 2026-02-19 - 25.7.6 - fix(throughput)
add tests for per-IP connection tracking and throughput history; assert per-IP eviction after connection close to prevent memory leak
- Adds runtime assertions for per-IP TCP connection tracking (m.connections.byIP) while a connection is active
- Adds checks for throughput history (m.throughput.history) to ensure history length and timestamps are recorded
- Asserts that per-IP tracking data is evicted after connection close (byIP.size === 0) to verify memory leak fix
- Reorders test checks so per-IP and history metrics are validated during the active connection and totals are validated after close
## 2026-02-19 - 25.7.5 - fix(rustproxy)
prune stale per-route metrics, add per-