Skip to content

Commit

Permalink
Fix ReadWriteTimeout_CancelsResponse test (dotnet#47737)
Browse files Browse the repository at this point in the history
  • Loading branch information
stephentoub authored Feb 2, 2021
1 parent 4df29c9 commit 39dd381
Showing 1 changed file with 31 additions and 5 deletions.
36 changes: 31 additions & 5 deletions src/libraries/System.Net.Requests/tests/HttpWebRequestTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,13 @@ public sealed class HttpWebRequestTest_Sync : HttpWebRequestTest
{
public HttpWebRequestTest_Sync(ITestOutputHelper output) : base(output) { }
protected override Task<WebResponse> GetResponseAsync(HttpWebRequest request) => Task.Run(() => request.GetResponse());
protected override bool IsAsync => false;
}

public abstract partial class HttpWebRequestTest
{
protected virtual bool IsAsync => true;

public class HttpWebRequestParameters
{
public DecompressionMethods AutomaticDecompression { get; set; }
Expand Down Expand Up @@ -1063,25 +1066,45 @@ public void ReadWriteTimeout_NegativeOrZeroValue_Fail()
Assert.Throws<ArgumentOutOfRangeException>(() => { request.ReadWriteTimeout = -10; });
}

[Fact]
public async Task ReadWriteTimeout_CancelsResponse()
[Theory]
[InlineData(false)]
[InlineData(true)]
public async Task ReadWriteTimeout_CancelsResponse(bool forceTimeoutDuringHeaders)
{
if (forceTimeoutDuringHeaders && IsAsync)
{
// ReadWriteTimeout doesn't apply to asynchronous operations, so when doing async
// internally, this test is only relevant when we then perform synchronous operations
// on the response stream.
return;
}

var tcs = new TaskCompletionSource();
await LoopbackServer.CreateClientAndServerAsync(uri => Task.Run(async () =>
{
try
{
HttpWebRequest request = WebRequest.CreateHttp(uri);
request.ReadWriteTimeout = 10;
IOException e = await Assert.ThrowsAsync<IOException>(async () => // exception type is WebException on .NET Framework
Exception e = await Assert.ThrowsAnyAsync<Exception>(async () =>
{
using WebResponse response = await GetResponseAsync(request);
using (Stream myStream = response.GetResponseStream())
{
while (myStream.ReadByte() != -1) ;
}
});
Assert.True(e.InnerException is SocketException se && se.SocketErrorCode == SocketError.TimedOut);

// If the timeout occurs while we're reading on the stream, we'll get an IOException.
// If the timeout occurs while we're reading/writing the request/response headers,
// that IOException will be wrapped in an HttpRequestException wrapped in a WebException.
// (Note that this differs slightly from .NET Framework, where exceptions from the stream
// are wrapped in a WebException as well, but in .NET Core, HttpClient's response Stream
// is passed back through the WebResponse without being wrapped.)
Assert.True(
e is WebException { InnerException: HttpRequestException { InnerException: IOException { InnerException: SocketException { SocketErrorCode: SocketError.TimedOut } } } } ||
e is IOException { InnerException: SocketException { SocketErrorCode: SocketError.TimedOut } },
e.ToString());
}
finally
{
Expand All @@ -1094,7 +1117,10 @@ await LoopbackServer.CreateClientAndServerAsync(uri => Task.Run(async () =>
await server.AcceptConnectionAsync(async connection =>
{
await connection.ReadRequestHeaderAsync();
await connection.WriteStringAsync("HTTP/1.1 200 OK\r\nContent-Length: 10\r\n\r\nHello Wor");
if (!forceTimeoutDuringHeaders)
{
await connection.WriteStringAsync("HTTP/1.1 200 OK\r\nContent-Length: 10\r\n\r\nHello Wor");
}
await tcs.Task;
});
}
Expand Down

0 comments on commit 39dd381

Please sign in to comment.