Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[wasm][http] Improve compatibility of abort and cancelation of BrowserHttpHandler #55084

Merged
merged 3 commits into from
Jul 13, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -928,6 +928,7 @@ public static IEnumerable<object[]> RemoteServersAndRedirectStatusCodes()

[OuterLoop("Uses external servers")]
[Theory, MemberData(nameof(RemoteServersAndRedirectStatusCodes))]
[ActiveIssue("https://github.com/dotnet/runtime/issues/55083", TestPlatforms.Browser)]
public async Task GetAsync_AllowAutoRedirectFalse_RedirectFromHttpToHttp_StatusCodeRedirect(Configuration.Http.RemoteServer remoteServer, int statusCode)
{
if (statusCode == 308 && (IsWinHttpHandler && PlatformDetection.WindowsVersion < 10))
Expand Down Expand Up @@ -955,6 +956,7 @@ public async Task GetAsync_AllowAutoRedirectFalse_RedirectFromHttpToHttp_StatusC

[OuterLoop("Uses external servers")]
[Theory, MemberData(nameof(RemoteServersAndRedirectStatusCodes))]
[ActiveIssue("https://github.com/dotnet/runtime/issues/55083", TestPlatforms.Browser)]
public async Task GetAsync_AllowAutoRedirectTrue_RedirectFromHttpToHttp_StatusCodeOK(Configuration.Http.RemoteServer remoteServer, int statusCode)
{
if (statusCode == 308 && (IsWinHttpHandler && PlatformDetection.WindowsVersion < 10))
Expand Down Expand Up @@ -982,6 +984,7 @@ public async Task GetAsync_AllowAutoRedirectTrue_RedirectFromHttpToHttp_StatusCo

[OuterLoop("Uses external servers")]
[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/55083", TestPlatforms.Browser)]
public async Task GetAsync_AllowAutoRedirectTrue_RedirectFromHttpToHttps_StatusCodeOK()
{
HttpClientHandler handler = CreateHttpClientHandler();
Expand All @@ -1003,6 +1006,7 @@ public async Task GetAsync_AllowAutoRedirectTrue_RedirectFromHttpToHttps_StatusC

[OuterLoop("Uses external servers")]
[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/55083", TestPlatforms.Browser)]
public async Task GetAsync_AllowAutoRedirectTrue_RedirectFromHttpsToHttp_StatusCodeRedirect()
{
HttpClientHandler handler = CreateHttpClientHandler();
Expand All @@ -1025,6 +1029,7 @@ public async Task GetAsync_AllowAutoRedirectTrue_RedirectFromHttpsToHttp_StatusC

[OuterLoop("Uses external servers")]
[Theory, MemberData(nameof(RemoteServersMemberData))]
[ActiveIssue("https://github.com/dotnet/runtime/issues/55083", TestPlatforms.Browser)]
public async Task GetAsync_AllowAutoRedirectTrue_RedirectToUriWithParams_RequestMsgUriSet(Configuration.Http.RemoteServer remoteServer)
{
HttpClientHandler handler = CreateHttpClientHandler();
Expand All @@ -1050,6 +1055,7 @@ public async Task GetAsync_AllowAutoRedirectTrue_RedirectToUriWithParams_Request
[InlineData(3, 2)]
[InlineData(3, 3)]
[InlineData(3, 4)]
[SkipOnPlatform(TestPlatforms.Browser, "MaxConnectionsPerServer not supported on Browser")]
public async Task GetAsync_MaxAutomaticRedirectionsNServerHops_ThrowsIfTooMany(int maxHops, int hops)
{
if (IsWinHttpHandler && !PlatformDetection.IsWindows10Version1703OrGreater)
Expand Down Expand Up @@ -1095,6 +1101,7 @@ public async Task GetAsync_MaxAutomaticRedirectionsNServerHops_ThrowsIfTooMany(i

[OuterLoop("Uses external servers")]
[Theory, MemberData(nameof(RemoteServersMemberData))]
[ActiveIssue("https://github.com/dotnet/runtime/issues/55083", TestPlatforms.Browser)]
public async Task GetAsync_AllowAutoRedirectTrue_RedirectWithRelativeLocation(Configuration.Http.RemoteServer remoteServer)
{
HttpClientHandler handler = CreateHttpClientHandler();
Expand All @@ -1118,6 +1125,7 @@ public async Task GetAsync_AllowAutoRedirectTrue_RedirectWithRelativeLocation(Co

[Theory, MemberData(nameof(RemoteServersMemberData))]
[OuterLoop("Uses external servers")]
[SkipOnPlatform(TestPlatforms.Browser, "Credentials is not supported on Browser")]
public async Task GetAsync_CredentialIsNetworkCredentialUriRedirect_StatusCodeUnauthorized(Configuration.Http.RemoteServer remoteServer)
{
HttpClientHandler handler = CreateHttpClientHandler();
Expand All @@ -1137,6 +1145,7 @@ public async Task GetAsync_CredentialIsNetworkCredentialUriRedirect_StatusCodeUn

[Theory, MemberData(nameof(RemoteServersMemberData))]
[OuterLoop("Uses external servers")]
[SkipOnPlatform(TestPlatforms.Browser, "Credentials is not supported on Browser")]
public async Task HttpClientHandler_CredentialIsNotCredentialCacheAfterRedirect_StatusCodeOK(Configuration.Http.RemoteServer remoteServer)
{
HttpClientHandler handler = CreateHttpClientHandler();
Expand All @@ -1163,6 +1172,7 @@ public async Task HttpClientHandler_CredentialIsNotCredentialCacheAfterRedirect_

[OuterLoop("Uses external servers")]
[Theory, MemberData(nameof(RemoteServersAndRedirectStatusCodes))]
[SkipOnPlatform(TestPlatforms.Browser, "Credentials is not supported on Browser")]
public async Task GetAsync_CredentialIsCredentialCacheUriRedirect_StatusCodeOK(Configuration.Http.RemoteServer remoteServer, int statusCode)
{
if (statusCode == 308 && (IsWinHttpHandler && PlatformDetection.WindowsVersion < 10))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ public SslClientAuthenticationOptions SslOptions

protected internal override HttpResponseMessage Send(HttpRequestMessage request, CancellationToken cancellationToken)
{
throw new PlatformNotSupportedException ();
throw new PlatformNotSupportedException();
}

protected internal override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
Expand Down Expand Up @@ -323,10 +323,27 @@ protected internal override async Task<HttpResponseMessage> SendAsync(HttpReques
return httpResponse;

}
catch (JSException jsExc)
catch (OperationCanceledException oce) when (cancellationToken.IsCancellationRequested)
{
throw new System.Net.Http.HttpRequestException(jsExc.Message);
throw CancellationHelper.CreateOperationCanceledException(oce, cancellationToken);
}
catch (JSException jse)
{
throw TranslateJSException(jse, cancellationToken);
}
}

private static Exception TranslateJSException(JSException jse, CancellationToken cancellationToken)
{
if (jse.Message.StartsWith("AbortError", StringComparison.Ordinal))
{
return CancellationHelper.CreateOperationCanceledException(jse, CancellationToken.None);
}
if (cancellationToken.IsCancellationRequested)
{
return CancellationHelper.CreateOperationCanceledException(jse, cancellationToken);
}
return new HttpRequestException(jse.Message, jse);
}

private sealed class WasmFetchResponse : IDisposable
Expand Down Expand Up @@ -366,7 +383,6 @@ public void Dispose()

_isDisposed = true;

_abortCts.Cancel();
_abortCts.Dispose();
_abortRegistration.Dispose();

Expand All @@ -385,36 +401,42 @@ public BrowserHttpContent(WasmFetchResponse status)
_status = status ?? throw new ArgumentNullException(nameof(status));
}

private async Task<byte[]> GetResponseData()
private async Task<byte[]> GetResponseData(CancellationToken cancellationToken)
{
if (_data != null)
{
return _data;
}

using (System.Runtime.InteropServices.JavaScript.ArrayBuffer dataBuffer = (System.Runtime.InteropServices.JavaScript.ArrayBuffer)await _status.ArrayBuffer().ConfigureAwait(continueOnCapturedContext: true))
try
{
using (Uint8Array dataBinView = new Uint8Array(dataBuffer))
using (System.Runtime.InteropServices.JavaScript.ArrayBuffer dataBuffer = (System.Runtime.InteropServices.JavaScript.ArrayBuffer)await _status.ArrayBuffer().ConfigureAwait(continueOnCapturedContext: true))
{
_data = dataBinView.ToArray();
_status.Dispose();
using (Uint8Array dataBinView = new Uint8Array(dataBuffer))
{
_data = dataBinView.ToArray();
_status.Dispose();
}
}
}
catch (JSException jse)
{
throw TranslateJSException(jse, cancellationToken);
}

return _data;
}

protected override async Task<Stream> CreateContentReadStreamAsync()
{
byte[] data = await GetResponseData().ConfigureAwait(continueOnCapturedContext: true);
byte[] data = await GetResponseData(CancellationToken.None).ConfigureAwait(continueOnCapturedContext: true);
return new MemoryStream(data, writable: false);
}

protected override Task SerializeToStreamAsync(Stream stream, TransportContext? context) =>
SerializeToStreamAsync(stream, context, CancellationToken.None);
protected override async Task SerializeToStreamAsync(Stream stream, TransportContext? context, CancellationToken cancellationToken)
{
byte[] data = await GetResponseData().ConfigureAwait(continueOnCapturedContext: true);
byte[] data = await GetResponseData(cancellationToken).ConfigureAwait(continueOnCapturedContext: true);
await stream.WriteAsync(data, cancellationToken).ConfigureAwait(continueOnCapturedContext: true);
}
protected internal override bool TryComputeLength(out long length)
Expand Down Expand Up @@ -482,10 +504,13 @@ public override async ValueTask<int> ReadAsync(Memory<byte> buffer, Cancellation
_reader = (JSObject)body.Invoke("getReader");
}
}
catch (JSException)
catch (OperationCanceledException oce) when (cancellationToken.IsCancellationRequested)
{
cancellationToken.ThrowIfCancellationRequested();
throw;
throw CancellationHelper.CreateOperationCanceledException(oce, cancellationToken);
}
catch (JSException jse)
{
throw TranslateJSException(jse, cancellationToken);
}
}

Expand Down Expand Up @@ -515,10 +540,13 @@ public override async ValueTask<int> ReadAsync(Memory<byte> buffer, Cancellation
_bufferedBytes = binValue.ToArray();
}
}
catch (JSException)
catch (OperationCanceledException oce) when (cancellationToken.IsCancellationRequested)
{
throw CancellationHelper.CreateOperationCanceledException(oce, cancellationToken);
}
catch (JSException jse)
{
cancellationToken.ThrowIfCancellationRequested();
throw;
throw TranslateJSException(jse, cancellationToken);
}

return ReadBuffered();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,6 @@ await LoopbackServer.CreateClientAndServerAsync(
}

[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/54270", TestPlatforms.Browser)]
public async Task GetStringAsync_CanBeCanceled_AlreadyCanceledCts()
{
var onClientFinished = new SemaphoreSlim(0, 1);
Expand All @@ -410,7 +409,6 @@ await LoopbackServer.CreateClientAndServerAsync(
}

[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/54270", TestPlatforms.Browser)]
public async Task GetStringAsync_CanBeCanceled()
{
var cts = new CancellationTokenSource();
Expand Down Expand Up @@ -445,7 +443,6 @@ await server.AcceptConnectionAsync(async connection =>
[InlineData(1, 0)]
[InlineData(1, 1)]
[InlineData(1, 2)]
[ActiveIssue("https://github.com/dotnet/runtime/issues/54270", TestPlatforms.Browser)]
public async Task GetAsync_ContentCanBeCanceled(int getMode, int cancelMode)
{
// cancelMode:
Expand Down Expand Up @@ -555,7 +552,6 @@ await LoopbackServer.CreateClientAndServerAsync(
}

[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/54270", TestPlatforms.Browser)]
public async Task GetByteArrayAsync_CanBeCanceled_AlreadyCanceledCts()
{
var onClientFinished = new SemaphoreSlim(0, 1);
Expand All @@ -580,7 +576,6 @@ await LoopbackServer.CreateClientAndServerAsync(
}

[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/54270", TestPlatforms.Browser)]
public async Task GetByteArrayAsync_CanBeCanceled()
{
var cts = new CancellationTokenSource();
Expand Down Expand Up @@ -631,7 +626,6 @@ await LoopbackServer.CreateClientAndServerAsync(
}

[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/54270", TestPlatforms.Browser)]
public async Task GetStreamAsync_CanBeCanceled_AlreadyCanceledCts()
{
var onClientFinished = new SemaphoreSlim(0, 1);
Expand All @@ -656,7 +650,6 @@ await LoopbackServer.CreateClientAndServerAsync(
}

[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/54270", TestPlatforms.Browser)]
public async Task GetStreamAsync_CanBeCanceled()
{
var cts = new CancellationTokenSource();
Expand Down