Skip to content

Seperate TransportLayer#41

Closed
st0o0 wants to merge 810 commits into
mainfrom
feature/seperate-transportlayer
Closed

Seperate TransportLayer#41
st0o0 wants to merge 810 commits into
mainfrom
feature/seperate-transportlayer

Conversation

@st0o0
Copy link
Copy Markdown
Member

@st0o0 st0o0 commented Apr 23, 2026

No description provided.

st0o0 added 30 commits March 28, 2026 18:04
…quest-to-frame conversion (RFC 9114 §4.1)

Implements Http30Request2FrameStage that converts HttpRequestMessage to Http3Frame sequences
using QPACK header compression. Produces HEADERS frames for all requests and DATA frames for
request bodies. Unlike HTTP/2, no stream ID is needed (QUIC handles multiplexing).
Replace NotSupportedException stub with complete HTTP/3 Akka.Streams pipeline:
Request2Frame → ConnectionStage → EncoderStage (outbound) and
DecoderStage → ConnectionStage → StreamStage (inbound), with
BatchWeighted consolidation for throughput.

Add H3EngineFakeConnectionStage test helper and 5 end-to-end engine
tests covering GET/POST round-trips, gzip decompression, SETTINGS
emission, and body content preservation.
…e pipeline

Wire the http30Factory parameter from Engine.CreateFlow through BuildExtendedPipeline
to ProtocolCoreGraphBuilder.Build, completing HTTP/3 version routing. Add EROUTE-005
test verifying HTTP/3 requests are dispatched to Http30Engine.
…C 9114 §3.2)

Add validation in QuicClientProvider to reject null/empty hostnames before
establishing QUIC connections, ensuring SNI extension is always present in the
TLS handshake. Add 11 unit tests covering hostname propagation, missing SNI
rejection, ALPN protocol verification, and certificate callback forwarding.
…9114 §10.3

- Enhanced Http3FieldValidator with token character validation (reject spaces,
  control chars, separators, high-byte chars in field names) and field value
  validation (reject NUL, CR, LF to prevent response splitting)
- Added Http3OriginValidator to reject prohibited origins (userinfo in authority,
  fragment identifiers in path)
- Integrated origin validation into Http3RequestEncoder.Encode()
- 20 new unit tests in 29_IntermediaryEncapsulationTests.cs, all passing
- Build: 0 errors, 685 RFC9114 tests green
Add Http3PushLimiter to enforce configurable ceiling on server push
promises per connection. Exceeding the limit triggers H3_EXCESSIVE_LOAD
connection error. Includes RecommendedMaxPushId for aligning MAX_PUSH_ID
with the DoS limit. 17 unit tests covering construction, enforcement,
integration with Http3PushPromiseValidator, and flood scenarios.
…red (RFC 9114 §9)

Fix DecodeAll to filter null frames from unknown types instead of adding
nulls to the result list. Add 34 unit tests covering GREASE patterns
(0x1f*N+0x21), HTTP/2 reserved frame types, unknown settings preservation,
partial reassembly, and mixed known/unknown frame streams.
Wire RFC 9114 §4.2 field validation into the HTTP/3 response header
pipeline. Http3FieldValidator.Validate() is now called after QPACK
decode and before status/header extraction, rejecting uppercase field
names, connection-specific headers, forbidden characters (NUL/CR/LF),
and TE with non-trailers values. Added 6 stream tests covering all
validation paths.
…Stage

Wire Http3OriginValidator.Validate() into Http30Request2FrameStage.OnPush()
before request encoding to prevent intermediary encapsulation attacks per
RFC 9114 §10.3. CONNECT method detection passes isConnect=true for relaxed
path validation. Invalid URIs (userinfo, empty scheme, empty path, fragments)
throw Http3ConnectionException which propagates as stage failure.
…ider

After QuicConnection.ConnectAsync(), validate server certificate hostname
coverage via Http3CertificateValidator.CoversHostname() per RFC 9114 §3.3.
Ensures connection coalescing safety with SAN/CN matching and wildcard
support. Validation skipped when custom ServerCertificateValidationCallback
is configured. On failure, connection is closed and Http3ConnectionException
thrown with GeneralProtocolError.
…Stage

Wire Http3IdleTimeoutHandler into Http30ConnectionStage to track idle
connections per RFC 9114 §5.1. The stage now detects stale QUIC connections
via periodic ScheduleOnce timer checks and sends GOAWAY when idle timeout
expires with zero active streams.
ConnectionReuseStage now checks response.Version.Major >= 3 and routes
HTTP/3 responses to Http3ConnectionReuseEvaluator.Evaluate() instead of
the HTTP/1.x ConnectionReuseEvaluator. Parameters (scheme, host, port)
are sourced from RequestMessage.RequestUri. serverCertificate and
isGoingAway are not yet available in the response context — documented
in XML remarks with guidance on how to thread them through the pipeline.
HTTP/1.x and HTTP/2 behavior is unchanged (78 existing tests pass).
…PUSH_ID=0)

Wire Http3MaxPushIdHandler, Http3PushLimiter, Http3CancelPushHandler, and
Http3PushPromiseValidator into Http30ConnectionStage to defensively reject
all server pushes per RFC 9114 §10.5. On PreStart, send MAX_PUSH_ID=0 on
the control stream; any incoming PUSH_PROMISE triggers ExcessiveLoad error;
CANCEL_PUSH frames are recorded via the cancel handler. GOAWAY-state
prevents new MAX_PUSH_ID frames by design (only sent once at startup).
…ontrolStream and Http3SettingId

Http3SettingsExchange was a thin wrapper around Http3ControlStream with no
additional state. Migrated unique methods: ValidateFieldSectionSize and
CalculateFieldSectionSize to Http3ControlStream, RejectForbiddenH2Settings
to Http3SettingId. All 25 tests in 22_SettingsExchangeTests.cs updated to
use the target classes directly.
Add 6 new test files in TurboHttp.StreamTests/RFC9114/ covering
field validation, origin validation, certificate validation,
idle timeout, connection reuse, and push rejection stages.

- 07_Http30FieldValidationStageTests.cs (8 tests) — uppercase rejection, connection-specific headers, TE validation, forbidden chars
- 08_Http30OriginValidationStageTests.cs (5 tests) — userinfo rejection, valid URI pass-through
- 09_Http30CertificateValidationTests.cs (11 tests) — SAN match, wildcard, CN fallback, reuse evaluator integration
- 10_Http30IdleTimeoutStageTests.cs (6 tests) — GOAWAY on idle expiry, timeout disabled, negative timeout, effective timeout
- 11_Http30ConnectionReuseTests.cs (6 tests) — HTTP/3 version dispatch, endpoint key, mixed version boundary
- 12_Http30PushRejectionStageTests.cs (6 tests) — MAX_PUSH_ID=0 at startup, PUSH_PROMISE ExcessiveLoad, CANCEL_PUSH absorption
All acceptance criteria verified:
- Build: 0 errors, 0 warnings
- Tests: 2,679/2,681 pass (2 pre-existing failures in HTTP/1.1 infrastructure)
- Port naming: 33 stages, 91 ports, 0 violations
- Zero Http3SettingsExchange references in production code
- All 9 active HTTP/3 handlers integrated in production stages
- No new [Obsolete] markers introduced
- Add `SupportsMultipleStreams` default interface property to `IClientProvider` (false for TCP/TLS, true for QUIC)
- Refactor `QuicClientProvider.GetStreamAsync()` to use lazy connection establishment via `SemaphoreSlim`-guarded `EnsureConnectedAsync()`
- First call connects + opens stream; subsequent calls reuse connection and open new streams
- Catch `QuicException` on dead connection, clear connection ref, wrap as reconnectable `InvalidOperationException`
- Use `Volatile.Read`/`Volatile.Write` and `Interlocked.CompareExchange` for thread-safe connection field access
- Add 13 unit tests covering: SupportsMultipleStreams property (4), SNI validation (2), Close safety (2), RemoteEndPoint (1), multi-stream reuse (1), concurrent thread-safety (1), reconnect on dead connection (1), error wrapping (1)
…tProvider implementations

- IClientProvider now extends IAsyncDisposable
- QuicClientProvider.DisposeAsync() properly awaits QuicConnection.DisposeAsync()
- TcpClientProvider.DisposeAsync() closes socket synchronously (wrapped in ValueTask)
- TlsClientProvider.DisposeAsync() awaits SslStream.DisposeAsync() then delegates to TCP
- Removed all fire-and-forget `_ = connection.DisposeAsync()` patterns from QuicClientProvider
- ClientRunner.PostStop() now calls DisposeAsync() instead of Close()
- ValidateCertificateHostname made async to properly await connection disposal on validation failure
- Added unit test verifying DisposeAsync completes before actor terminates
- Updated all fake IClientProvider implementations in test projects
…exing

Add QUIC-aware connection pooling to HostPool and ConnectionActor so HTTP/3
requests multiplex over a single QUIC connection via OpenNewStream messages,
while HTTP/1.x and HTTP/2 retain existing direct-handle behavior.

Production changes:
- ConnectionState: add SupportsMultipleStreams property (true for HTTP/3)
- ConnectionActor: add OpenNewStream message, shared provider management,
  multi-runner lifecycle with BecomeStacked routing, pending stream queue
- HostPool: version-aware HandleEnsureHost (QUIC sends OpenNewStream to
  connection actor), limiter bypass for QUIC, QUIC-aware HandleConnectionReady
  and ServeQueuedRequesters, suppress extra connection spawns while QUIC
  connection is still connecting
- ClientRunner: skip disposal for shared QUIC providers (SupportsMultipleStreams)
- IOActorTestBase: add Key30/QuicOptions, FakeConnectionActor message forwarding

Test coverage (14 new tests):
- 7 HostPool QUIC tests (QUIC-001 through QUIC-007): spawn, reuse, limiter
  bypass, HTTP/1.1+HTTP/2 regression, queued requesters, StreamCompleted
- 3 ConnectionActor QUIC tests (CQ-001 through CQ-003): OpenNewStream
  ignored for TCP, message properties, ConnectionReady handle preservation
- 4 ConnectionState tests (TASK-9-003-017 through 020): SupportsMultipleStreams
  for HTTP/1.x/2/3, HTTP/3 MaxConcurrentStreams, HTTP/3 HasAvailableSlot
Split ContinueWith into OnlyOnRanToCompletion (pull next element) and
OnlyOnFaulted (FailStage with exception) branches so that write failures
on a closed outbound channel propagate cleanly instead of being silently
swallowed. Cancelled writes (stage shutdown) no longer trigger pull or fail.

Added CS-011 test verifying the stage fails fast when the outbound channel
is closed.
…or CloseSignalItem

Two ConnectionStage stream tests (CS-004, CS-010) needed updating to account
for the CloseSignalItem now emitted on inbound channel completion (introduced
in TASK-007-004). All 3831 tests pass, zero warnings, zero errors.
Introduce abstract base class `ConnectionActorBase` that encapsulates shared
connection lifecycle logic: channel management, exponential backoff reconnection,
and HostPool message forwarding. This is the foundation for splitting the
monolithic ConnectionActor into version-specific subclasses (Http1/Http2/Http3).
Simple single-connection actor inheriting from ConnectionActorBase,
encapsulating TCP connect/disconnect logic for HTTP/1.0 and HTTP/1.1
without any multi-stream branching.
Add Http2ConnectionActor inheriting from ConnectionActorBase with simple
TCP connect (no SharedProvider), stream lifecycle forwarding via base class
(StreamAcquired/StreamCompleted), and no MarkBusy — stream accounting is
handled exclusively by stage signals.
Extract QUIC-specific logic from the monolithic ConnectionActor into
Http3ConnectionActor, inheriting from ConnectionActorBase. Isolates
SharedProvider lifecycle, multi-runner tracking, pending stream queue,
and BecomeStacked stream spawning — eliminating all _isMultiStream
branches for QUIC handling.
HostPool.SpawnConnection() now creates the correct actor type based on
HTTP version (Http1ConnectionActor, Http2ConnectionActor, or
Http3ConnectionActor). All references to ConnectionActor.ConnectionReady
migrated to ConnectionActorBase.ConnectionReady; OpenNewStream migrated
to Http3ConnectionActor.OpenNewStream. The old monolithic ConnectionActor.cs
is deleted. All 3832 tests pass with 0 warnings.
All test files already correctly reference the new ConnectionActor hierarchy
(Http1ConnectionActor, Http2ConnectionActor, Http3ConnectionActor,
ConnectionActorBase) from prior tasks. Fixed typo in
ConnectionActorQuicTests doc comment (Http3Http3ConnectionActor →
Http3ConnectionActor). All 3,832 tests pass, 0 warnings, 0 errors.
…ging

Implement a FlowShape stage that assigns monotonically increasing client-initiated
bidirectional QUIC stream IDs (0, 4, 8, 12, …) to each HTTP/3 request per
RFC 9000 §2.1. Uses long for 62-bit QUIC stream IDs. Includes 10 stream tests
verifying ID sequence, divisibility, monotonicity, and reference passthrough.
…matching

Implements FanInShape stage that correlates HTTP/3 request/response pairs
by QUIC stream ID (long), following the Http20CorrelationStage pattern.
Sets HttpResponseMessage.RequestMessage for each correlated pair.
Includes 7 stream tests covering single correlation, out-of-order responses,
unmatched responses, reference equality, 10-request interleaving, upstream
lifecycle, and immediate match on interleaved push.
@st0o0 st0o0 self-assigned this Apr 23, 2026
@st0o0 st0o0 marked this pull request as draft April 23, 2026 19:01
@st0o0 st0o0 force-pushed the feature/seperate-transportlayer branch from 7dfb62e to db064fc Compare April 25, 2026 16:59
st0o0 added 3 commits April 25, 2026 20:58
Introduces `System.IO.Pipelines` for efficient byte movement, replacing direct `System.Threading.Channels` interactions in the core transport logic. This change streamlines buffer management, improves performance, and forms a key part of separating the transport layer.

- Migrates `ClientByteMover` to a `Pipe`-centric architecture, utilizing `IoBuffer` for `MemoryPool` integration.
- Updates `ClientState` to internally manage `Pipe` instances.
- Adjusts `ConnectionHandle` and `NetworkBuffer` to interoperate with the new `IoBuffer` and `Pipe` paradigm.
- Increases default HTTP/2 stream window size and max frame size, and HTTP/3 QPACK table capacity for improved performance.
- Removes `Servus.Akka` project reference from `TurboHTTP.csproj`.
- Adjust HTTP/2 flow control window update threshold for more efficient `WINDOW_UPDATE` frames.
- Optimize HPACK dynamic table lookups for header encoding by introducing an O(1) indexed cache.
- Batch multiple HTTP/2 outbound frames into a single network buffer write to reduce overhead.
- Improve HTTP/3 request body encoding to support streaming for unknown content lengths, preventing excessive memory allocation.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant