}
[ConditionalFact(nameof(SupportsAlpn))]
+ public async Task Http2_StreamResetByServerAfterHeadersSent_ResponseHeadersRead_ContentThrows()
+ {
+ using (Http2LoopbackServer server = Http2LoopbackServer.CreateServer())
+ using (HttpClient client = CreateHttpClient())
+ {
+ Task<HttpResponseMessage> sendTask = client.GetAsync(server.Address, HttpCompletionOption.ResponseHeadersRead);
+
+ Http2LoopbackConnection connection = await server.EstablishConnectionAsync();
+ int streamId = await connection.ReadRequestHeaderAsync();
+
+ // Send response headers and RST_STREAM combined
+ await connection.WriteFramesAsync(new Frame[] {
+ new HeadersFrame(new byte[] { 0x88 /* :status: 200 */}, FrameFlags.EndHeaders, 0, 0, 0, streamId),
+ new RstStreamFrame(FrameFlags.None, (int)ProtocolErrors.NO_ERROR, streamId)
+ });
+
+ // Headers should be received successfully
+ HttpResponseMessage response = await sendTask;
+
+ // Reading the actual content should throw
+ await AssertHttpProtocolException((await response.Content.ReadAsStreamAsync()).ReadAsync(new byte[10]).AsTask(), ProtocolErrors.NO_ERROR);
+ }
+ }
+
+ [ConditionalFact(nameof(SupportsAlpn))]
public async Task Http2_StreamResetByServerAfterPartialBodySent_RequestFails()
{
using (Http2LoopbackServer server = Http2LoopbackServer.CreateServer())
using (HttpClient client = CreateHttpClient())
{
var request = new HttpRequestMessage(HttpMethod.Post, url);
- request.Version = new Version(2,0);
+ request.Version = new Version(2, 0);
request.Content = new CustomContent(stream);
await Assert.ThrowsAnyAsync<OperationCanceledException>(async () => await client.SendAsync(request, cts.Token));
// Send another request to verify that connection is still functional.
request = new HttpRequestMessage(HttpMethod.Get, url);
- request.Version = new Version(2,0);
+ request.Version = new Version(2, 0);
await client.SendAsync(request);
}
{
Http2LoopbackConnection connection = await server.EstablishConnectionAsync();
- (int streamId, HttpRequestData requestData) = await connection.ReadAndParseRequestHeaderAsync(readBody : false);
+ (int streamId, HttpRequestData requestData) = await connection.ReadAndParseRequestHeaderAsync(readBody: false);
int frameCount = 0;
Frame frame;
do
{
- if (frameCount == (waitForData ? 1 : 0)) {
+ if (frameCount == (waitForData ? 1 : 0))
+ {
// Cancel client after receiving Headers or part of request body.
cts.Cancel();
}
Assert.NotNull(frame); // We should get Rst before closing connection.
Assert.Equal(0, (int)(frame.Flags & FrameFlags.EndStream));
frameCount++;
- } while (frame.Type != FrameType.RstStream);
+ } while (frame.Type != FrameType.RstStream);
Assert.Equal(1, frame.StreamId);
await Http2LoopbackServer.CreateClientAndServerAsync(async url =>
{
var request = new HttpRequestMessage(HttpMethod.Get, url);
- request.Version = new Version(2,0);
+ request.Version = new Version(2, 0);
response = await client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, cts.Token);
using (Stream stream = await response.Content.ReadAsStreamAsync())
{
Http2LoopbackConnection connection = await server.EstablishConnectionAsync();
- (int streamId, HttpRequestData requestData) = await connection.ReadAndParseRequestHeaderAsync(readBody : false);
+ (int streamId, HttpRequestData requestData) = await connection.ReadAndParseRequestHeaderAsync(readBody: false);
_output.WriteLine($"{DateTime.Now} Connection established");
await connection.SendResponseHeadersAsync(streamId, endStream: false, HttpStatusCode.OK);
using (HttpClient client = CreateHttpClient())
{
var request = new HttpRequestMessage(HttpMethod.Post, url);
- request.Version = new Version(2,0);
+ request.Version = new Version(2, 0);
request.Content = new StringContent(new string('*', 3000));
request.Headers.ExpectContinue = true;
request.Headers.Add("x-test", $"PostAsyncExpect100Continue_SendRequest_Ok({send100Continue}");
{
Http2LoopbackConnection connection = await server.EstablishConnectionAsync();
- (int streamId, HttpRequestData requestData) = await connection.ReadAndParseRequestHeaderAsync(readBody : false);
+ (int streamId, HttpRequestData requestData) = await connection.ReadAndParseRequestHeaderAsync(readBody: false);
Assert.Equal("100-continue", requestData.GetSingleHeaderValue("Expect"));
if (send100Continue)
handler.Expect100ContinueTimeout = TimeSpan.FromSeconds(300);
var request = new HttpRequestMessage(HttpMethod.Post, url);
- request.Version = new Version(2,0);
+ request.Version = new Version(2, 0);
request.VersionPolicy = HttpVersionPolicy.RequestVersionExact;
request.Content = new StringContent(new string('*', 3000));
request.Headers.ExpectContinue = true;
{
Http2LoopbackConnection connection = await server.EstablishConnectionAsync();
- (int streamId, HttpRequestData requestData) = await connection.ReadAndParseRequestHeaderAsync(readBody : false);
+ (int streamId, HttpRequestData requestData) = await connection.ReadAndParseRequestHeaderAsync(readBody: false);
Assert.Equal("100-continue", requestData.GetSingleHeaderValue("Expect"));
// Reject content with 403.
await connection.SendResponseBodyAsync(streamId, Encoding.ASCII.GetBytes(responseContent));
// Client should send empty request body
- byte[] requestBody = await connection.ReadBodyAsync(expectEndOfStream:true);
+ byte[] requestBody = await connection.ReadBodyAsync(expectEndOfStream: true);
Assert.Null(requestBody);
await connection.ShutdownIgnoringErrorsAsync(streamId);
Task<HttpResponseMessage> responseTask = client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);
connection = await server.EstablishConnectionAsync();
- // Client should have sent the request headers, and the request stream should now be available
+ // Client should have sent the request headers, and the request stream should now be available
Stream requestStream = await duplexContent.WaitForStreamAsync();
// Flush the content stream. Otherwise, the request headers are not guaranteed to be sent.
await requestStream.FlushAsync();
- (int streamId, HttpRequestData requestData) = await connection.ReadAndParseRequestHeaderAsync(readBody : false);
+ (int streamId, HttpRequestData requestData) = await connection.ReadAndParseRequestHeaderAsync(readBody: false);
// Client finished sending request headers and we received them.
// Send request body.
// Send trailing headers for good measure and close stream.
var headers = new HttpHeaderData[] { new HttpHeaderData("x-last", "done") };
- await connection.SendResponseHeadersAsync(streamId, endStream: true, isTrailingHeader : true, headers: headers);
+ await connection.SendResponseHeadersAsync(streamId, endStream: true, isTrailingHeader: true, headers: headers);
// Finish reading response body and verify it for all cases.
string responseBody = await response.Content.ReadAsStringAsync();
TaskCompletionSource<bool> tsc = new TaskCompletionSource<bool>();
string requestContent = new string('*', 300);
const string responseContent = "SendAsync_ConcurentSendReceive_Fail";
- var stream = new CustomContent.SlowTestStream(Encoding.UTF8.GetBytes(requestContent), tsc, trigger : 1, count : 50);
+ var stream = new CustomContent.SlowTestStream(Encoding.UTF8.GetBytes(requestContent), tsc, trigger: 1, count: 50);
bool stopSending = false;
await Http2LoopbackServer.CreateClientAndServerAsync(async url =>
using (HttpClient client = CreateHttpClient())
{
var request = new HttpRequestMessage(HttpMethod.Post, url);
- request.Version = new Version(2,0);
+ request.Version = new Version(2, 0);
request.Content = new CustomContent(stream);
// This should fail either while getting response headers or while reading response body.
{
Http2LoopbackConnection connection = await server.EstablishConnectionAsync();
- (int streamId, HttpRequestData requestData) = await connection.ReadAndParseRequestHeaderAsync(readBody : false);
+ (int streamId, HttpRequestData requestData) = await connection.ReadAndParseRequestHeaderAsync(readBody: false);
await connection.SendResponseHeadersAsync(streamId, endStream: false, HttpStatusCode.OK);
// Wait for client so start sending body.
int maxCount = 120;
while (!stopSending && maxCount != 0)
{
- try
+ try
{
await connection.SendResponseDataAsync(streamId, Encoding.ASCII.GetBytes(responseContent), endStream: false);
}
break;
}
await Task.Delay(500);
- maxCount --;
+ maxCount--;
}
// We should not reach retry limit without failing.
Assert.NotEqual(0, maxCount);
Http2LoopbackConnection connection = await server.EstablishConnectionAsync();
int streamId = await connection.ReadRequestHeaderAsync();
- await connection.SendResponseHeadersAsync(streamId, endStream : true, headers: headers);
+ await connection.SendResponseHeadersAsync(streamId, endStream: true, headers: headers);
await Assert.ThrowsAsync<HttpRequestException>(() => sendTask);
}
}
Http2LoopbackConnection connection = await server.EstablishConnectionAsync();
int streamId = await connection.ReadRequestHeaderAsync();
- await connection.SendResponseHeadersAsync(streamId, endStream : true, isTrailingHeader : true, headers: headers);
+ await connection.SendResponseHeadersAsync(streamId, endStream: true, isTrailingHeader: true, headers: headers);
await Assert.ThrowsAsync<HttpRequestException>(() => sendTask);
}
int streamId = await connection.ReadRequestHeaderAsync();
await connection.SendDefaultResponseHeadersAsync(streamId);
await connection.SendResponseDataAsync(streamId, "hello"u8.ToArray(), endStream: false);
- await connection.SendResponseHeadersAsync(streamId, endStream : true, isTrailingHeader : true, headers: headers);
+ await connection.SendResponseHeadersAsync(streamId, endStream: true, isTrailingHeader: true, headers: headers);
await Assert.ThrowsAsync<HttpRequestException>(() => sendTask);
}