Files
Flash5/flash
Zakaria El Orche cf16be08c0 fix(core): fix HTTP/2 rate-limiter false positives, connection-flood OOM, and a streaming-body leak
Targeted stress testing under this branch's HTTP/2 work surfaced four independent
production bugs, each verified with a before/after load test and a regression test:

- Http2Limits.MAX_STREAMS_CREATED_PER_INTERVAL (400/10s) rejected legitimate
  high-concurrency HTTP/2 clients as if they were CVE-2023-44487 rapid-reset abuse —
  h2load's default pattern alone triggered 40-92% request failure. Raised to 100,000,
  matching MAX_STREAMS_PER_CONNECTION's existing lifetime budget; the RST_STREAM-rate
  counter remains the precise defence against the actual attack signature.

- Flash had no connection-admission control anywhere: AcceptLoop accepted every TCP
  connection unconditionally, so a connection flood (h2load -c 400) ran the JVM out of
  heap and crashed with OutOfMemoryError, killing even unrelated daemon threads.
  TransportLimits.defaultMaxConnections() auto-scales a cap from Runtime.maxMemory();
  ConnectionRunner.accept() enforces it before any per-connection state (TLS handshake
  included) is created. Verified surviving 42x the admission limit under both cleartext
  and TLS load with bounded RSS.

- Http1ResponseWriter never closed a handler's streaming response body on a write
  failure (e.g. the client disconnecting mid-transfer) — only on a clean EOF. A handler
  whose stream releases a held resource (a pooled backend connection, for a reverse
  proxy) from close() leaks it under any real amount of client disconnects. Now closed
  on every exit path, matching InputStream#close()'s own idempotency contract.

- Http2StreamState.transition() called the enum's values() every state transition;
  values() clones a fresh array on every call. Cached once, removing ~10.76% of
  allocations measured live under load.

695 -> 698 tests (three new regression tests), all passing.
2026-08-14 18:12:46 +00:00
..