Visitar URL original
.NET: fix(dotnet): bound declarative HTTP response reads by baywet · Pull Request #10344 · microsoft/agent-framework · GitHub
Skip to content

.NET: fix(dotnet): bound declarative HTTP response reads - #10344

Open
Vincent Biret (baywet) wants to merge 4 commits into
mainfrom
fix/bound-workflow-http-responses
Open

Vincent Biret (baywet) wants to merge 4 commits into
mainfrom
fix/bound-workflow-http-responses

Conversation

@baywet

@baywet Vincent Biret (baywet) commented Nov 13, 2026 •

Copy link
Copy Markdown
Member

Motivation & Context

Keep declarative workflow HTTP response reads within a consistent size boundary while preserving response decoding and request deadlines.

Description & Review Guide

  • What are the major changes? Bound response buffering to 10 MiB before string decoding. Validate the actual buffered byte count without allocating another body buffer, including responses already buffered by the pipeline. Dispose older-target cancellation waits after each read and check cancellation after validation and decoding. Preserve bodyless HEAD and 304 responses without reading their content. Add coverage for known, absent, and underreported lengths, pre-buffered and decoded content, empty bodies, the exact boundary, and bodyless-response metadata and cancellation.
  • What is the impact of these changes? Responses with bodies above 10 MiB after pipeline decompression throw HttpRequestException. Responses within the boundary retain the existing decoding behavior. HEAD and 304 responses retain their headers even when Content-Length describes a larger representation. Public API signatures are unchanged.
  • What do you want reviewers to focus on? Boundary enforcement and cancellation across target frameworks.

Validation from dotnet:

  • dotnet run --project tests\Microsoft.Agents.AI.Workflows.Declarative.UnitTests -f net10.0 --no-build -- --filter-class '*DefaultHttpRequestHandlerTests' --filter-method '*LimitAsync' --progress off: before the fix, three rejection cases failed because no exception was thrown; two boundary controls passed.
  • dotnet run --project tests\Microsoft.Agents.AI.Workflows.Declarative.UnitTests -f net10.0 --no-build -- --filter-class '*DefaultHttpRequestHandlerTests' --filter-method '*SendAsyncRejectsBufferedResponseBodyAboveLimitAsync' --progress off: both pre-buffered regression cases failed before the follow-up correction because no exception was thrown.
  • dotnet run --project tests\Microsoft.Agents.AI.Workflows.Declarative.UnitTests -f net10.0 --no-restore -- --filter-class '*DefaultHttpRequestHandlerTests' --filter-method '*LimitAsync' --progress off: passed all eight regression cases after the fix.
  • dotnet run --project tests\Microsoft.Agents.AI.Workflows.Declarative.UnitTests -f net10.0 --no-restore -- --filter-class '*DefaultHttpRequestHandlerTests' --filter-method '*SendAsyncPreservesBodylessResponsesWithLargeContentLengthAsync' --progress off: both HEAD and 304 cases failed before the compatibility correction because the representation length was treated as a response-body length.
  • dotnet run --project tests\Microsoft.Agents.AI.Workflows.Declarative.UnitTests -f net10.0 --no-restore -- --filter-class '*DefaultHttpRequestHandlerTests' --filter-method '*Bodyless*' --progress off: passed all four metadata and cancellation cases after the correction.
  • dotnet run --project tests\Microsoft.Agents.AI.Workflows.Declarative.UnitTests -f net10.0 --no-restore -- --progress off: before the final cancellation-check follow-up, 1,388 passed; one unchanged PowerFx trace-capture test failed with a StringBuilder.ToString() exception.
  • dotnet run --project tests\Microsoft.Agents.AI.Workflows.Declarative.UnitTests -f net10.0 --no-build -- --progress off: unchanged rerun before the final cancellation-check follow-up passed all 1,389 project tests.
  • dotnet run --project tests\Microsoft.Agents.AI.Workflows.Declarative.UnitTests -f net10.0 --no-restore -- --filter-class '*DefaultHttpRequestHandlerTests' --progress off: passed all 120 handler tests after the final cancellation-check follow-up.
  • dotnet run --project tests\Microsoft.Agents.AI.Workflows.Declarative.UnitTests -f net472 --no-restore -- --filter-class '*DefaultHttpRequestHandlerTests' --progress off: passed all 117 handler tests.
  • dotnet build src\Microsoft.Agents.AI.Workflows.Declarative --no-restore --tl:off: passed for all five target frameworks, with no warnings or errors.
  • dotnet format src\Microsoft.Agents.AI.Workflows.Declarative --no-restore: passed.
  • dotnet format tests\Microsoft.Agents.AI.Workflows.Declarative.UnitTests --no-restore: passed.

The full repository solution and integration tests were not run locally.

Related Issue

N/A - maintainer-directed bugfix; no public issue. Checked for competing open pull requests before implementation.

AI Assistance

  • No material AI assistance was used.
  • This is an AI-assisted contribution. I reviewed, understood, and verified all submitted content and accept responsibility for it.

AI assistance details: Copilot assisted with implementation, regression tests, validation, and this description.

Contribution Checklist

  • The code builds clean without any errors or warnings
  • All unit tests pass, and I have added new tests where possible
  • The PR follows the Contribution Guidelines
  • This PR links to an agreed issue with no competing open PR, or the Related Issue section documents a trivial-change or repository-automation exception.
  • This is not a breaking change. If it is a breaking change, add the breaking change label (or add "[BREAKING]" to the title prefix, before or after any language prefix) — a workflow keeps the label and title prefix in sync automatically.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 228910b7-ed10-4ed9-a5ad-e29d4107b707
Copilot AI balanced review requested due to automatic review settings November 13, 2026 15:43
@agent-framework-automation agent-framework-automation Bot added .NET Usage: [Issues, PRs], Target: .Net workflows Usage: [Issues, PRs], Target: Workflows labels Nov 13, 2026
@github-actions github-actions Bot changed the title fix(dotnet): bound declarative HTTP response reads .NET: fix(dotnet): bound declarative HTTP response reads Nov 13, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Already-buffered responses can bypass the 10 MiB limit and reach string decoding, requiring checks against the actual buffered byte count in both branches and a regression test.

1 open issue
What changed in this PR

This PR adds bounded response buffering to the .NET declarative workflow HTTP handler, aiming to enforce a 10 MiB limit before string decoding while preserving request deadlines and decoding behavior.

Changes:

  • Adds size-limited buffering with target-specific cancellation handling.
  • Documents the response limit after HTTP pipeline decompression.
  • Adds tests for oversized bodies, missing or underreported lengths, decompressed content, empty bodies, and the exact boundary.
File Description
dotnet/​tests/​Microsoft.Agents.AI.Workflows.Declarative.UnitTests/​DefaultHttpRequestHandlerTests.cs Adds response-size regression tests and a sized-content helper.
dotnet/​src/​Microsoft.Agents.AI.Workflows.Declarative/​DefaultHttpRequestHandler.cs Adds and documents bounded buffering before response decoding.

Review effort: Balanced

@github-code-quality

github-code-quality Bot commented Nov 13, 2026 •

Copy link
Copy Markdown
Contributor

Code coverage overview

Languages: C#

C# / code-coverage/dotnet

main 77d9306 fix/bound-workflow-h... f3d74ca +/-
86% 86% 0%
View coverage of the 10 most impacted files.
File main 77d9306 fix/bound-workflow-h... f3d74ca +/-
/home/runner/wo...SessionStore.cs 100% 56% -44%
/home/runner/wo...questHandler.cs 95% 85% -10%
/home/runner/wo...dTraceClient.cs 92% 92% 0%
/home/runner/wo...usExtensions.cs 100% 100% 0%
/home/runner/wo...sionStateBag.cs 100% 100% 0%
/home/runner/wo.../Codecs/Wire.cs 76% 76% 0%
/home/runner/wo...ckpointStore.cs 97% 97% 0%
/home/runner/wo...onsentParser.cs 98% 98% 0%
/home/runner/wo...FoundryEvals.cs 37% 37% 0%
/home/runner/wo...tInfoBuilder.cs 95% 95% 0%

ℹ️ Calculations represent line coverage. Results may change as calculations are updated.


Updated November 13, 2026 18:59 UTC

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MAF Automated Review — Iteration 1

Result: Findings reported
Scope: full PR (1 commit(s)): 69b997bc32c2
Model: gpt-5.6-sol

Overview

The PR adds a per-response 10 MiB buffering limit, verifies absent and misleading content lengths, tests the exact boundary and decompressed content, and preserves explicit cancellation handling across target frameworks. Two residual gaps remain: already-buffered content bypasses the new limit, and routing .NET 8 through the legacy cancellation race retains one cancellation registration after every successful read. These issues undermine the memory-safety objective for supported handler pipelines and long-lived .NET 8 workflows.

Reviewed the supplied pull-request change set across correctness, security/reliability, architecture, and failure behavior.
2 verified findings remained after source verification (1 high, 1 medium) across 1 file. Details are attached to the affected lines below.

Affected areas: dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/DefaultHttpRequestHandler.cs

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 228910b7-ed10-4ed9-a5ad-e29d4107b707

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

Valid HEAD and 304 responses with Content-Length above 10 MiB incorrectly throw despite having no body, requiring bodyless-response handling and regression tests in both buffering branches.

No open issues 🎉

1 previously missed issue

In code that hasn't changed since last review

Medium severity Skip body-size checks for bodyless HEAD and 304 responses

dotnet/​src/​Microsoft.Agents.AI.Workflows.Declarative/​DefaultHttpRequestHandler.cs:192

LoadIntoBufferAsync checks Content-Length before reading, so a valid HEAD or 304 response advertising a representation larger than 10 MiB now throws even though it has no body. In SendAsync, return an empty body for these responses based on httpRequest.Method and httpResponse.StatusCode, preserving headers and checking cancellation before bypassing the read. Add regression tests with oversized Content-Length values on bodyless responses; both buffering branches are affected.

1 resolved since last review

Review effort: Balanced

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 228910b7-ed10-4ed9-a5ad-e29d4107b707
@baywet

Copy link
Copy Markdown
Member Author

Addressed the HEAD/304 compatibility finding from Copilot review 5894369771 in 352f6bc. Bodyless responses preserve representation-length headers without reading content, and cancellation is checked before returning. Both large-length regressions failed before the correction; all four metadata/cancellation cases now pass on modern and legacy targets. Final validation: 1,389 .NET 10 project tests passed on an unchanged rerun, 117 .NET Framework handler tests passed, all five target builds and both project format checks passed. The first full run had an unrelated StringBuilder exception in the unchanged PowerFx trace-capture test; no unrelated code was changed.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

No active review issues were identified for the HTTP response-body size-limit change.

No open issues 🎉

Review effort: Balanced

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MAF Automated Review — Iteration 2

Result: Findings reported
Scope: 2 net-new commit(s): 0283eb0b5403, 352f6bcc5602
Model: gpt-5.6-sol

Overview

The change closes the already-buffered response-size bypass with an allocation-free counting sink, preserves HEAD/304 metadata without reading a body, and releases legacy cancellation registrations after each read. One Medium cancellation gap remains on netstandard2.0 and net472: the newly added validation pass and subsequent decoding can outlive a request deadline and still return a result.

Reviewed the supplied incremental change set across correctness, security/reliability, architecture, and failure behavior.
1 verified finding remained after source verification (1 medium) across 1 file. Details are attached to the affected lines below.

Affected areas: dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/DefaultHttpRequestHandler.cs

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 228910b7-ed10-4ed9-a5ad-e29d4107b707

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

No active review issues remain for the HTTP response-size limiting change.

No open issues 🎉

Review effort: Balanced

This branch was successfully deployed

1 active and 1 inactive deployments
github-app-auth — f3d74ca2 Deployed Nov 13, 2026 by baywet via add_label #27829
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

.NET Usage: [Issues, PRs], Target: .Net workflows Usage: [Issues, PRs], Target: Workflows

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants