Repository navigation
test(darling): live HTTP proof of the web host's gates (#4128a) - #4132
Merged
Merged
Conversation
Extracts everything after builder.Build() through UseStaticFiles into an internal ConfigurePipeline(WebApplication app, ...) method that TryStartServerAsync calls with the same values in the same order, then adds DarlingWebHostGateLiveTests: six TestServer-driven cases covering network-mode no-token (login page), right-token+in-CIDR (passes), right-token+out-of-CIDR (403), foreign Host in both modes (400), and loopback no-token (reaches past the gates). HostHeaderGuardTests' EachHost_RunsTheGuardInBothModes_NotOnlyWhenNetworkExposed is updated to search for the auth-gating 'if (networkMode)' starting from the guard's own position, since the extraction moved TryStartServerAsync's unrelated post-start 'if (networkMode)' branch ahead of ConfigurePipeline in the file.
…pins, and make TestServer.CreateClient prose, not a cref
erikdarlingdata
marked this pull request as ready for review
September 24, 2026 04:09
erikdarlingdata
enabled auto-merge (squash)
September 24, 2026 04:09
This was referenced Sep 24, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Part of #4128 (the web host; the MCP host and /core follow after #4121).
What changed
Package. Added
Microsoft.AspNetCore.TestHosttoDirectory.Packages.propsat 10.0.12 (matching theMicrosoft.Extensions.*pins already at that version for the net10.0 TFM), and a<PackageReference>inDarling/Darling.Tests/Darling.Tests.csproj.Extracted the pipeline seam.
DarlingWebHostService.TryStartServerAsyncused to build the wholemiddleware pipeline inline after
builder.Build(). That block (the Host-allowlist/DNS-rebinding guard,the network-mode auth middleware,
DarlingWebEndpoints.MapAll→UseDefaultFiles→UseStaticFiles) isnow
internal void ConfigurePipeline(WebApplication app, NpgsqlDataSource postgres, bool networkMode, IPAddress? networkListenIp, IPNetwork allowedCidr, string accessToken, DarlingWebOidcClient? oidcClient).TryStartServerAsynccalls it right after_app = builder.Build();, passing exactly the same locals itused inline, in the same order — I diffed the extracted body against the original inline block (git diff
on this PR shows only the extraction, no logic reordering) to confirm the call sequence is unchanged.
It stayed an instance method (not static) because the gates call back into
HandleAuthFlowAsyncandReportSignInRefusal, and read_logger/_collectorState/_baselineCache— exactly as before, justwith the test's own
DarlingWebHostServiceinstance as the receiver instead of production's.New live test class
Darling/Darling.Tests/DarlingWebHostGateLiveTests.cs: builds aWebApplicationwith
UseTestServer(), constructs a throwawayDarlingWebHostService, calls the REALConfigurePipelineon it, starts it, and drives it through
TestServer.SendAsync(notCreateClient, since the gates readRemoteIpAddress, which onlySendAsynclets a test set). Six cases:WebRequestAction.ShowLoginby design)Updated
HostHeaderGuardTests.EachHost_RunsTheGuardInBothModes_NotOnlyWhenNetworkExposedforDarlingWebHostService.cs: the extraction movedTryStartServerAsync's own unrelated post-startif (networkMode)logging branch ahead ofConfigurePipelinein the file text, so the FIRSTif (networkMode)afterbuilder.Build()is no longer necessarily the auth-gating one the test means topin. Now searches from the guard's own index instead of from
Build(), which finds the conditional thatactually follows the guard in the same method — the same claim (guard registered before the network-only
auth block), evaluated correctly under the new file shape.
ReadHostSource's anchor changed from"_app.Use("to"app.Use("(a substring of the former) so it matches both the MCP host's still-direct_app.Useand the web host'sConfigurePipeline, which now callsapp.Useon its parameter.What I ran
dotnet buildon the service project andDarling.Tests(-p:EnableWindowsTargeting=true): both green.Darling.Tests.DarlingWebHostGateLiveTestsalone: 6/6 pass.Darling.Tests.HostHeaderGuardTestsalone: 42/42 pass (after the fix above).DarlingWebAuthTests,DarlingWebSupervisorTests,DarlingWebOidcTests,DarlingWebTlsTests,DarlingWebEditorAttributionTests(every other class touchingDarlingWebHostService): 254/254 pass.Darling.Testssuite once:Total: 13403, Errors: 0, Failed: 218, Skipped: 715. All 218 failures areoutside anything this PR touches (checked by name — none mention
DarlingWebHostGateLiveTests,HostHeaderGuardTests, orDarlingWebHostService); this Mac's known baseline is ~214 Windows-onlyfailures (WPF/registry/etc.), and the 218 here is in that same neighborhood.
What I did NOT verify
Lite.Testswas not built or run (per lane rules — WPF, CI-only on this Mac).count.
DarlingMcpHostService.csis untouched (PR Darling MCP: a /core endpoint serves the tools analysis points to (#3898 D7) #4121's territory) and none of my edits touch it.Coordinator verification (branch head e6a88a8)
Behaviour-preserving, checked mechanically. Every line removed from
TryStartServerAsyncreappears inConfigurePipeline, with the receiver_appbecoming theappparameter. The only other additions are the method signature, its doc comment, and the one call that replaces the inline block. The gate order is unchanged: the Host guard, then the network-mode auth, thenMapAll,UseDefaultFilesandUseStaticFiles.HostHeaderGuardTests' changed source pin still claims that the guard is the firstapp.UseafterBuild(), with the network-mode block after it. The six live TestServer cases prove the same thing in behaviour.The full Darling suite on macOS, compared with dev on the same rig: 4 new failures, all mechanical and fixed in e6a88a8:
MapAll(_app, ...)(FleetSweepWebFeedTests,SharedBaselineCacheTests);creftoTestServer.CreateClient, which resolves to nothing the repo spells (DocCommentHygieneTests×2).Every affected class passes.
No separate security review round: the gate code is provably unchanged (line-identical), and this PR adds tests of it.
CHANGELOG entry
through a real Kestrel pipeline, and extracted the gate-wiring code into a testable
ConfigurePipelinemethod with production behavior unchanged.