Preserve request-stream ownership during server cleanup
Extract server stream ownership and cancellation cleanup from #3511. Each HTTP request closes its own streams, so an older connection cannot remove a successor's streams after request-ID reuse; legacy SSE also closes all owned memory streams.
Replay locking and buffering are left to the next PR. The router regressions run on both asyncio and trio without enabling Trio across the suite or requiring an HTTPX2 update.
Validation
macOS, Python 3.14, locked dependencies: ./scripts/test passes with 5,981 passed, 9 skipped, 1 xfailed, 100% line/branch coverage, and strict-no-cover passing. Ruff lint/format and Pyright pass.
Stack
Part 1 of 5, based on main. Merge the focused fixes before the final backend-enablement change in #3511.
AI Disclaimer
This PR was developed with the assistance of either Claude or Codex. I've reviewed and verified the changes.