You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/.vitepress/config.ts
+2-2Lines changed: 2 additions & 2 deletions
Original file line number
Diff line number
Diff line change
@@ -5,10 +5,10 @@ export default defineConfig({
5
5
description: 'High-performance HTTP client library for .NET built on Akka.Streams — HTTP/1.0, HTTP/1.1, and HTTP/2 with automatic retries, caching, cookies, and connection pooling.',
Copy file name to clipboardExpand all lines: docs/architecture/pipeline.md
+26-12Lines changed: 26 additions & 12 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -15,25 +15,33 @@ Each `HttpRequestMessage` passes through the following stages before reaching th
15
15
| # | Stage | What it does |
16
16
|---|-------|--------------|
17
17
| 1 | Request Enrichment (`RequestEnricherStage`) | Applies your `BaseAddress`, default HTTP version, and default headers to every request |
18
-
| 2 | Cookie Injection (`CookieBidiStage`) | Looks up matching cookies for the target domain and path and adds a `Cookie` header |
19
-
| 3 | Cache Lookup (`CacheBidiStage`) | Checks the in-memory cache; on a **cache hit**, returns the cached response immediately — stages 4–5 are skipped entirely |
20
-
| 4 | Version Router (`Engine`) | Routes the request to the correct protocol handler based on the requested HTTP version |
21
-
| 5 | Protocol Encoder *(per version)*| Serialises the request to bytes and sends it over the network connection |
18
+
| 2 | Tracing (`TracingBidiStage`) | Starts an activity span for observability; records request method, URL, timing, and final status code |
19
+
| 3 | User Handlers (`HandlerBidiStage`) | Runs any custom middleware you registered — zero or more, applied outermost-first |
20
+
| 4 | Redirect (`RedirectBidiStage`) | Tracks the redirect chain; on a `301`–`308` response, re-enters the pipeline at the Cookie stage so new-URL cookies are injected |
21
+
| 5 | Cookie Injection (`CookieBidiStage`) | Looks up matching cookies for the target domain and path and adds a `Cookie` header |
22
+
| 6 | Retry (`RetryBidiStage`) | On the request side, attaches retry context; on a transient failure, re-enters below the Cookie stage (same URL, cookies already set) |
23
+
| 7 | Expect-Continue (`ExpectContinueBidiStage`) | For requests with large bodies, sends `Expect: 100-continue` and holds the body until the server confirms it will accept it |
24
+
| 8 | Cache Lookup (`CacheBidiStage`) | Checks the in-memory cache; on a **cache hit**, returns the cached response immediately — stages 9–10 are skipped entirely |
25
+
| 9 | Content Encoding (`ContentEncodingBidiStage`) | Compresses the request body if a compression policy is configured; on the response side, transparently decompresses `gzip`, `deflate`, or Brotli |
26
+
| 10 | Version Router (`Engine`) | Routes the request to the correct protocol handler based on the requested HTTP version |
27
+
| 11 | Protocol Encoder *(per version)*| Serialises the request to bytes and sends it over the network connection |
22
28
23
29
---
24
30
25
31
## Response Chain (right to left / bottom to top)
26
32
27
-
After bytes return from TCP, the response passes through these stages:
33
+
After bytes return from the network, the response passes back through the stages in reverse order:
28
34
29
35
| # | Stage | What it does |
30
36
|---|-------|--------------|
31
37
| 1 | Protocol Decoder *(per version)*| Parses raw bytes into an `HttpResponseMessage` and matches it to the original request |
| 6 | Redirect Following (`RedirectBidiStage`) | Follows `301`–`308` redirects automatically; rewrites the HTTP method where needed; detects loops and blocks HTTPS→HTTP downgrades |
42
+
| 6 | Cookie Storage (`CookieBidiStage`) | Reads `Set-Cookie` headers and stores cookies for future requests |
43
+
| 7 | Redirect Following (`RedirectBidiStage`) | Follows `301`–`308` redirects automatically; rewrites the HTTP method where needed; detects loops and blocks HTTPS→HTTP downgrades |
44
+
| 8 | Tracing (`TracingBidiStage`) | Closes the activity span, recording the final status code and any errors |
37
45
38
46
---
39
47
@@ -53,11 +61,17 @@ After each HTTP/1.1 response, a signal is sent back to the connection layer indi
53
61
54
62
This loop is invisible to the caller — the `Engine` and higher layers see only a continuous stream of `HttpResponseMessage` objects.
55
63
56
-
### 3. Retry / Redirect Re-entry (red)
64
+
### 3. Redirect Re-entry
57
65
58
-
When `RetryBidiStage` decides a request should be retried, or when `RedirectBidiStage` needs to follow a redirect, the new `HttpRequestMessage`is fed back into the **front of the pipeline**(before `RequestEnricherStage`). This ensures that retry enrichment, cookie injection, and cache lookup all apply again on the new attempt.
66
+
When `RedirectBidiStage` needs to follow a redirect, the new `HttpRequestMessage`re-enters the pipeline at the **Cookie stage**— not at the very beginning. This ensures cookie injection applies for the new URL while skipping the initial enrichment step (default headers are already applied). A redirect hop limit prevents infinite loops.
59
67
60
-
A maximum retry count and redirect hop limit prevent infinite loops.
68
+
### 4. Retry Re-entry
69
+
70
+
When `RetryBidiStage` decides a request should be retried, it re-enters the pipeline at the **Expect-Continue stage** — below Cookie injection, since the URL hasn't changed and cookies are already set. A maximum retry count prevents infinite loops.
71
+
72
+
### 5. QPACK Table Sync (HTTP/3 only)
73
+
74
+
HTTP/3 uses QPACK for header compression. The server sends decoder table updates on a dedicated QUIC stream; `QpackDecoderFeedbackStage` forwards these updates back to `Http30Request2FrameStage` to keep the encoder and decoder tables in sync.
0 commit comments