Skip to content

Release 7.0.18-beta - #1077

Merged
justcoding121 merged 12 commits into
betafrom
develop
Oct 5, 2026
Merged

justcoding121 merged 12 commits into
betafrom
develop

Conversation

@justcoding121

Copy link
Copy Markdown
Owner

Summary

  • Cut v7.0.18-beta from develop (43f4fb64). VersionPrefix is 7.0.18.
  • Inspector streams unknown-length bodies instead of buffering them against the abort budget, and stops UI freezes on large binary bodies and heavy live/diff actions.
  • H2/H3 bridges and oversize WebSocket streams stream bodies instead of aborting on MaxBufferedBodyBytes. Tiny-GET stays allocation-free; H2 padding credit is returned; oversize WebSocket opcodes are validated.
  • Chocolatey publishes 7.0.18-beta (SKIP_CATALOG_PUBLISH is unset). No winget changes.

Test plan

  • .NET / build, ui-portable and cli-e2e on Windows, Linux, and macOS
  • RPS compare-spot on ubuntu-latest, windows-latest, and macos-15
  • Path guard
  • Sonar quality gate OK
  • After merge: NuGet 7.0.18-beta, GitHub prerelease v7.0.18-beta, Chocolatey 7.0.18-beta

justcoding121 and others added 12 commits October 5, 2026 05:53
…budget

Inspector buffered any body without a Content-Length (chunked, H2 without
CL) up to ProxyServer.MaxBufferedBodyBytes (32 MiB), which is a hard abort
limit: larger transfers (e.g. git clone packs) were RST/closed mid-stream.
Root cause is the sizing policy, not any content type or host.

- ShouldBufferBody: buffer only when the length is known and within the
  budget (or the budget is non-positive); unknown length is relayed.
- Unknown-length responses and requests are marked Streaming and previewed
  through the existing body-write hook into a bounded 2 MiB tee; add the
  missing request-side tee.
- Decode the tee preview per Content-Encoding (gzip/deflate/br, tolerant of
  truncation) so chunked compressed JSON stays readable.
- Re-derive gRPC/protobuf/multipart views when a streamed preview is final.
- Remove the content-type/URL special cases (git pack helper, SSE buffering
  denylist); SSE detection remains only for UI flags.
- Tests for policy, request/response tee, decoding, truncation, gRPC views.
…body budget

HTTP/2 origin pipes, HTTP/3 frame reads, and oversize WebSocket frames were still bounded by MaxBufferedBodyBytes even when the body was never buffered.
…e oversize WS opcodes

Review follow-up to the bridge body streaming change:
- Http2OriginConnection no longer allocates a closure and two delegates per request to wire up
  stream credit. PendingStream implements IBodyConsumptionSink, so the InlineBody tiny-GET path
  attaches credit with two field stores.
- DATA padding and the pad-length byte are returned to the stream window on receipt. Only real
  body bytes wait on the consumer, so a padded stream cannot stall at the stream window.
- Observe-mode oversize WebSocket relay is limited to data opcodes. A control frame or reserved
  opcode with an oversize length closes with 1002, as the buffered path does.
- Unit tests that reflect on the private Http2OriginConnection and PendingStream constructors
  now match the new signatures.
…ould add

- InterceptionService: drop the unused isRequest parameter from ShouldBufferBody and move the
  finite-unbuffered response branch into its own method (S1172, S3776).
- SessionStreamBuffer: invoke SessionAdded through the captured delegate directly so Sonar sees the
  invocation (S3264); the per-batch snapshot of the handler is unchanged.
- Http11ToHttp2BridgeHandler: remove the now-unused SessionEventArgs parameter from the seed offer
  and the redundant null-forgiving operators (S1172, S8969).
- Http3FrameTests: remove an unnecessary ulong cast (S1905).
…/diff actions

Selecting the Body tab for a 2 MiB git upload-pack response froze the window
for seconds: ~256K characters of U+FFFD/control characters were laid out in a
wrapped Avalonia TextBox on the UI thread (headless repro: Body 5012 ms,
Hex 105-274 ms; now 105 ms / 10 ms).

- InspectorDisplayText.ForTextBox: display-only cap (128K chars; 16K when the
  content is binary-looking), control/replacement characters shown as '.',
  trailing note pointing to Save body / Hex. Applied to Body, Frames, SSE,
  Protobuf and Diff text boxes. Captured bytes, Save, Hex and clipboard keep
  the full data.
- SessionInspectors.TryDecompress gains a maxOutputBytes bound; Body decode
  is capped at MaxBodyBytes and Hex decodes only MaxHexBytes+1, so a small
  compressed body can no longer expand without limit on the UI thread.
- SessionDiff: bound the 8-line lookahead search to its window (was a scan to
  the end of the body per mismatch, quadratic); output is identical.
- Session Diff command computes off the UI thread when a UI exists, shows a
  bounded text and still copies the full report.
- Live updates of the selected session (chatty WebSocket, streaming body)
  coalesce Inspect refreshes to 200 ms with a trailing refresh instead of
  rebuilding every text box per event.

Inspector-only; the proxy library and RPS paths are untouched. Adds unit tests
for the bounds and a headless real-window regression test.
- S107: ProxyPolicyModes.Create had grown to 8 parameters. Restore the shipped
  7-parameter signature (also repairs the binary break that had been recorded
  as *REMOVED* in PublicAPI.Unshipped.txt); WebSocketFrameBudget still defaults
  to Enforce and is changed through the existing With(family, mode). The CLI
  config applier uses With for the WebSocket family. Config-time only, not a
  request-path change.
- CA1846: use StringBuilder.Append(string, int, int) / CompareOrdinal instead of
  Substring in the chunked-body test helper.
@sonarqubecloud

sonarqubecloud Bot commented Oct 5, 2026

Copy link
Copy Markdown

@justcoding121
justcoding121 merged commit 26e9b20 into beta Oct 5, 2026
26 of 27 checks passed
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