});
}
+ [ConditionalFact(nameof(SupportsAlpn))]
+ public async Task Http2Connection_Should_Wrap_HttpContent_InvalidOperationException()
+ {
+ // test for #39295
+ var throwingContent = new ThrowingContent(() => new InvalidOperationException());
+
+ var tcs = new TaskCompletionSource<bool>();
+ await Http2LoopbackServer.CreateClientAndServerAsync(async url =>
+ {
+ using (HttpClient client = CreateHttpClient())
+ {
+ var request = new HttpRequestMessage(HttpMethod.Post, url);
+ request.Version = new Version(2, 0);
+ request.Content = throwingContent;
+
+ HttpRequestException exn = await Assert.ThrowsAnyAsync<HttpRequestException>(async () => await client.SendAsync(request));
+ Assert.IsType<InvalidOperationException>(exn.InnerException);
+ await tcs.Task; // prevent disposal of client until server has completed operations
+ }
+ },
+ async server =>
+ {
+ await server.EstablishConnectionAsync();
+ tcs.SetResult(false);
+ });
+ }
+
+ [ConditionalFact(nameof(SupportsAlpn))]
+ public async Task Http2Connection_Should_Not_Wrap_HttpContent_CustomException()
+ {
+ // Assert existing HttpConnection behaviour in which custom HttpContent exception types are surfaced as-is
+ // c.f. https://github.com/dotnet/corefx/issues/39295#issuecomment-510569836
+
+ var throwingContent = new ThrowingContent(() => new CustomException());
+
+ var tcs = new TaskCompletionSource<bool>();
+ await Http2LoopbackServer.CreateClientAndServerAsync(async url =>
+ {
+ using (HttpClient client = CreateHttpClient())
+ {
+ var request = new HttpRequestMessage(HttpMethod.Post, url);
+ request.Version = new Version(2, 0);
+ request.Content = throwingContent;
+
+ await Assert.ThrowsAnyAsync<CustomException>(async () => await client.SendAsync(request));
+ await tcs.Task; // prevent disposal of client until server has completed operations
+ }
+ },
+ async server =>
+ {
+ await server.EstablishConnectionAsync();
+ tcs.SetResult(false);
+ });
+ }
+
+ private class CustomException : Exception { }
+
[Theory]
[InlineData(true)]
[InlineData(false)]
--- /dev/null
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace System.Net.Http.Functional.Tests
+{
+ /// <summary>HttpContent that mocks exceptions on serialization.</summary>
+ public class ThrowingContent : HttpContent
+ {
+ private readonly Func<Exception> _exnFactory;
+ private readonly int _length;
+
+ public ThrowingContent(Func<Exception> exnFactory, int length = 10)
+ {
+ _exnFactory = exnFactory;
+ _length = length;
+ }
+
+ protected override Task SerializeToStreamAsync(Stream stream, TransportContext context)
+ {
+ throw _exnFactory();
+ }
+
+ protected override bool TryComputeLength(out long length)
+ {
+ length = _length;
+ return true;
+ }
+ }
+}