Skip to content

Commit 8ca6917

Browse files
committed
Add pipe test
1 parent 992dacf commit 8ca6917

File tree

1 file changed

+81
-0
lines changed

1 file changed

+81
-0
lines changed

src/Servers/Kestrel/test/InMemory.FunctionalTests/Http2/Http2StreamTests.cs

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3712,6 +3712,87 @@ await ExpectAsync(Http2FrameType.DATA,
37123712
Assert.Equal("Hello World", Encoding.UTF8.GetString(bodyFrame.Payload.Span));
37133713
}
37143714

3715+
[Fact]
3716+
public async Task CompleteAsync_AfterPipeWrite_WithTrailers_SendsBodyAndTrailersWithEndStream()
3717+
{
3718+
var startingTcs = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
3719+
var appTcs = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
3720+
var clientTcs = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
3721+
var headers = new[]
3722+
{
3723+
new KeyValuePair<string, string>(HeaderNames.Method, "GET"),
3724+
new KeyValuePair<string, string>(HeaderNames.Path, "/"),
3725+
new KeyValuePair<string, string>(HeaderNames.Scheme, "http"),
3726+
};
3727+
await InitializeConnectionAsync(async context =>
3728+
{
3729+
try
3730+
{
3731+
context.Response.OnStarting(() => { startingTcs.SetResult(0); return Task.CompletedTask; });
3732+
var completionFeature = context.Features.Get<IHttpResponseCompletionFeature>();
3733+
Assert.NotNull(completionFeature);
3734+
3735+
var buffer = context.Response.BodyWriter.GetMemory();
3736+
var length = Encoding.UTF8.GetBytes("Hello World", buffer.Span);
3737+
context.Response.BodyWriter.Advance(length);
3738+
3739+
Assert.False(startingTcs.Task.IsCompletedSuccessfully); // OnStarting did not get called.
3740+
Assert.False(context.Response.Headers.IsReadOnly);
3741+
3742+
context.Response.AppendTrailer("CustomName", "Custom Value");
3743+
3744+
await completionFeature.CompleteAsync().DefaultTimeout();
3745+
Assert.True(startingTcs.Task.IsCompletedSuccessfully); // OnStarting got called.
3746+
Assert.True(context.Response.Headers.IsReadOnly);
3747+
3748+
Assert.True(context.Features.Get<IHttpResponseTrailersFeature>().Trailers.IsReadOnly);
3749+
3750+
// Make sure the client gets our results from CompleteAsync instead of from the request delegate exiting.
3751+
await clientTcs.Task.DefaultTimeout();
3752+
appTcs.SetResult(0);
3753+
}
3754+
catch (Exception ex)
3755+
{
3756+
appTcs.SetException(ex);
3757+
}
3758+
});
3759+
3760+
await StartStreamAsync(1, headers, endStream: true);
3761+
3762+
var headersFrame = await ExpectAsync(Http2FrameType.HEADERS,
3763+
withLength: 37,
3764+
withFlags: (byte)(Http2HeadersFrameFlags.END_HEADERS),
3765+
withStreamId: 1);
3766+
var bodyFrame = await ExpectAsync(Http2FrameType.DATA,
3767+
withLength: 11,
3768+
withFlags: (byte)(Http2HeadersFrameFlags.NONE),
3769+
withStreamId: 1);
3770+
var trailersFrame = await ExpectAsync(Http2FrameType.HEADERS,
3771+
withLength: 25,
3772+
withFlags: (byte)(Http2HeadersFrameFlags.END_HEADERS | Http2HeadersFrameFlags.END_STREAM),
3773+
withStreamId: 1);
3774+
3775+
clientTcs.SetResult(0);
3776+
await appTcs.Task;
3777+
3778+
await StopConnectionAsync(expectedLastStreamId: 1, ignoreNonGoAwayFrames: false);
3779+
3780+
_hpackDecoder.Decode(headersFrame.PayloadSequence, endHeaders: false, handler: this);
3781+
3782+
Assert.Equal(2, _decodedHeaders.Count);
3783+
Assert.Contains("date", _decodedHeaders.Keys, StringComparer.OrdinalIgnoreCase);
3784+
Assert.Equal("200", _decodedHeaders[HeaderNames.Status]);
3785+
3786+
Assert.Equal("Hello World", Encoding.UTF8.GetString(bodyFrame.Payload.Span));
3787+
3788+
_decodedHeaders.Clear();
3789+
3790+
_hpackDecoder.Decode(trailersFrame.PayloadSequence, endHeaders: true, handler: this);
3791+
3792+
Assert.Single(_decodedHeaders);
3793+
Assert.Equal("Custom Value", _decodedHeaders["CustomName"]);
3794+
}
3795+
37153796
[Fact]
37163797
public async Task CompleteAsync_AfterBodyStarted_WithTrailers_SendsBodyAndTrailersWithEndStream()
37173798
{

0 commit comments

Comments
 (0)