fix(inbound): in-memory request buffering; relaying standby skips audit capture (review 2026-10-21 05/M4)

This commit is contained in:
Joseph Doherty
2026-10-22 08:30:18 -04:00
parent 6c9dfaf700
commit 26baa5a170
3 changed files with 59 additions and 4 deletions
@@ -62,6 +62,36 @@ public class AuditWriteMiddlewareTests
if (localRows > 0) Assert.NotNull(writer.Events[0].ExecutionId);
}
/// <summary>Verifies that a relaying standby skips request buffering and response capture.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task M4_RelayingStandby_DoesNotBufferRequestOrCaptureResponse()
{
// Review 2026-10-21 05/M4: the standby neither executes nor audits a relayed call, so
// it must not buffer the body (the forwarder reads it once) or wrap the response.
var services = new ServiceCollection().AddLogging();
services.AddSingleton<IActiveNodeGate>(new StandbyGate());
services.AddSingleton<IStandbyRequestForwarder>(new ResultForwarder(Results.Ok()));
using var provider = services.BuildServiceProvider();
var context = BuildContext("echo", "{}");
context.RequestServices = provider;
var originalRequest = context.Request.Body;
var originalResponse = new MemoryStream();
context.Response.Body = originalResponse;
Stream? seenRequest = null, seenResponse = null;
var middleware = CreateMiddleware(ctx =>
{
seenRequest = ctx.Request.Body;
seenResponse = ctx.Response.Body;
return Task.CompletedTask;
}, new RecordingAuditWriter());
await middleware.InvokeAsync(context);
Assert.Same(originalRequest, seenRequest);
Assert.Same(originalResponse, seenResponse);
}
private sealed class StandbyGate : IActiveNodeGate
{
/// <inheritdoc />