diff --git a/src/libraries/Common/tests/System/Net/Http/GenericLoopbackServer.cs b/src/libraries/Common/tests/System/Net/Http/GenericLoopbackServer.cs index 779055b921e4d..760e84a5dc0ca 100644 --- a/src/libraries/Common/tests/System/Net/Http/GenericLoopbackServer.cs +++ b/src/libraries/Common/tests/System/Net/Http/GenericLoopbackServer.cs @@ -126,6 +126,36 @@ public HttpRequestData() Headers = new List(); } + public static async Task FromHttpRequestMessageAsync(System.Net.Http.HttpRequestMessage request) + { + var result = new HttpRequestData(); + result.Method = request.Method.ToString(); + result.Path = request.RequestUri.AbsolutePath; + + foreach (var header in request.Headers) + { + foreach (var value in header.Value) + { + result.Headers.Add(new HttpHeaderData(header.Key, value)); + } + } + + if (request.Content != null) + { + result.Body = await request.Content.ReadAsByteArrayAsync().ConfigureAwait(false); + + foreach (var header in request.Content.Headers) + { + foreach (var value in header.Value) + { + result.Headers.Add(new HttpHeaderData(header.Key, value)); + } + } + } + + return result; + } + public string[] GetHeaderValues(string headerName) { return Headers.Where(h => h.Name.Equals(headerName, StringComparison.OrdinalIgnoreCase)) diff --git a/src/libraries/Common/tests/System/Net/Http/HttpMessageHandlerLoopbackServer.cs b/src/libraries/Common/tests/System/Net/Http/HttpMessageHandlerLoopbackServer.cs new file mode 100644 index 0000000000000..22355aff157d7 --- /dev/null +++ b/src/libraries/Common/tests/System/Net/Http/HttpMessageHandlerLoopbackServer.cs @@ -0,0 +1,96 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Generic; +using System.IO; +using System.Net.Http; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using Xunit; + +namespace System.Net.Test.Common +{ + public class HttpMessageHandlerLoopbackServer : GenericLoopbackServer + { + HttpRequestMessage _request; + public HttpStatusCode ResponseStatusCode; + public IList ResponseHeaders; + public string ReponseContentString; + public byte[] ReponseContentBytes; + + private HttpMessageHandlerLoopbackServer(HttpRequestMessage request) + { + _request = request; + } + + public static async Task CreateClientAndServerAsync(Func clientFunc, Func serverFunc) + { + await clientFunc(new LoopbackServerHttpMessageHandler(serverFunc), new Uri("http://example.com")).ConfigureAwait(false); + } + + public async override Task HandleRequestAsync(HttpStatusCode statusCode = HttpStatusCode.OK, IList headers = null, string content = "") + { + ResponseStatusCode = statusCode; + ResponseHeaders = headers; + ReponseContentString = content; + return await HttpRequestData.FromHttpRequestMessageAsync(_request).ConfigureAwait(false); + } + + public async Task HandleRequestAsync(HttpStatusCode statusCode, IList headers, byte[] bytes) + { + ResponseStatusCode = statusCode; + ResponseHeaders = headers; + ReponseContentBytes = bytes; + return await HttpRequestData.FromHttpRequestMessageAsync(_request).ConfigureAwait(false); + } + + public override Task AcceptConnectionAsync(Func funcAsync) => throw new NotImplementedException(); + + public override Task EstablishGenericConnectionAsync() => throw new NotImplementedException(); + + public override void Dispose() { } + + class LoopbackServerHttpMessageHandler : HttpMessageHandler + { + Func _serverFunc; + + public LoopbackServerHttpMessageHandler(Func serverFunc) + { + _serverFunc = serverFunc; + } + + protected override async Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) + { + var server = new HttpMessageHandlerLoopbackServer(request); + await _serverFunc(server).ConfigureAwait(false); + + var response = new HttpResponseMessage(server.ResponseStatusCode); + if (server.ReponseContentString != null) + { + response.Content = new StringContent(server.ReponseContentString); + } + else + { + response.Content = new ByteArrayContent(server.ReponseContentBytes); + } + + foreach (var header in server.ResponseHeaders ?? Array.Empty()) + { + if (String.Equals(header.Name, "Content-Type", StringComparison.InvariantCultureIgnoreCase)) + { + response.Content.Headers.Remove("Content-Type"); + response.Content.Headers.TryAddWithoutValidation("Content-Type", header.Value); + } + else + { + response.Headers.Add(header.Name, header.Value); + } + } + + return response; + } + } + } +} diff --git a/src/libraries/System.Net.Http.Json/tests/FunctionalTests/AssemblyInfo.cs b/src/libraries/System.Net.Http.Json/tests/FunctionalTests/AssemblyInfo.cs deleted file mode 100644 index f124e7754138a..0000000000000 --- a/src/libraries/System.Net.Http.Json/tests/FunctionalTests/AssemblyInfo.cs +++ /dev/null @@ -1,7 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using Xunit; - -[assembly: ActiveIssue("https://github.com/dotnet/runtime/issues/34690", TestPlatforms.Windows, TargetFrameworkMonikers.Netcoreapp, TestRuntimes.Mono)] diff --git a/src/libraries/System.Net.Http.Json/tests/FunctionalTests/HttpClientJsonExtensionsTests.cs b/src/libraries/System.Net.Http.Json/tests/FunctionalTests/HttpClientJsonExtensionsTests.cs index 4186235c864be..8dfcbe4d3f2cb 100644 --- a/src/libraries/System.Net.Http.Json/tests/FunctionalTests/HttpClientJsonExtensionsTests.cs +++ b/src/libraries/System.Net.Http.Json/tests/FunctionalTests/HttpClientJsonExtensionsTests.cs @@ -25,14 +25,13 @@ private static readonly JsonSerializerOptions s_defaultSerializerOptions public async Task TestGetFromJsonAsync() { const string json = @"{""Name"":""David"",""Age"":24}"; - const int NumRequests = 4; HttpHeaderData header = new HttpHeaderData("Content-Type", "application/json"); List headers = new List { header }; - await LoopbackServer.CreateClientAndServerAsync( - async uri => + await HttpMessageHandlerLoopbackServer.CreateClientAndServerAsync( + async (handler, uri) => { - using (HttpClient client = new HttpClient()) + using (HttpClient client = new HttpClient(handler)) { Person per = (Person)await client.GetFromJsonAsync(uri, typeof(Person)); per.Validate(); @@ -47,45 +46,31 @@ await LoopbackServer.CreateClientAndServerAsync( per.Validate(); } }, - async server => - { - for (int i = 0; i < NumRequests; i++) - { - await server.HandleRequestAsync(content: json, headers: headers); - } - }); + server => server.HandleRequestAsync(content: json, headers: headers)); } [Fact] public async Task TestGetFromJsonAsyncUnsuccessfulResponseAsync() { - const int NumRequests = 2; - await LoopbackServer.CreateClientAndServerAsync( - async uri => + await HttpMessageHandlerLoopbackServer.CreateClientAndServerAsync( + async (handler, uri) => { - using (HttpClient client = new HttpClient()) + using (HttpClient client = new HttpClient(handler)) { await Assert.ThrowsAsync(() => client.GetFromJsonAsync(uri, typeof(Person))); await Assert.ThrowsAsync(() => client.GetFromJsonAsync(uri)); } }, - async server => - { - for (int i = 0; i < NumRequests; i++) - { - await server.HandleRequestAsync(statusCode: HttpStatusCode.InternalServerError); - } - }); + server => server.HandleRequestAsync(statusCode: HttpStatusCode.InternalServerError)); } [Fact] public async Task TestPostAsJsonAsync() { - const int NumRequests = 4; - await LoopbackServer.CreateClientAndServerAsync( - async uri => + await HttpMessageHandlerLoopbackServer.CreateClientAndServerAsync( + async (handler, uri) => { - using (HttpClient client = new HttpClient()) + using (HttpClient client = new HttpClient(handler)) { Person person = Person.Create(); @@ -103,24 +88,20 @@ await LoopbackServer.CreateClientAndServerAsync( } }, async server => { - for (int i = 0; i < NumRequests; i++) - { - HttpRequestData request = await server.HandleRequestAsync(); - ValidateRequest(request); - Person per = JsonSerializer.Deserialize(request.Body, s_defaultSerializerOptions); - per.Validate(); - } + HttpRequestData request = await server.HandleRequestAsync(); + ValidateRequest(request); + Person per = JsonSerializer.Deserialize(request.Body, s_defaultSerializerOptions); + per.Validate(); }); } [Fact] public async Task TestPutAsJsonAsync() { - const int NumRequests = 4; - await LoopbackServer.CreateClientAndServerAsync( - async uri => + await HttpMessageHandlerLoopbackServer.CreateClientAndServerAsync( + async (handler, uri) => { - using (HttpClient client = new HttpClient()) + using (HttpClient client = new HttpClient(handler)) { Person person = Person.Create(); Type typePerson = typeof(Person); @@ -139,13 +120,10 @@ await LoopbackServer.CreateClientAndServerAsync( } }, async server => { - for (int i = 0; i < NumRequests; i++) - { - HttpRequestData request = await server.HandleRequestAsync(); - ValidateRequest(request); - Person obj = JsonSerializer.Deserialize(request.Body, s_defaultSerializerOptions); - obj.Validate(); - } + HttpRequestData request = await server.HandleRequestAsync(); + ValidateRequest(request); + Person obj = JsonSerializer.Deserialize(request.Body, s_defaultSerializerOptions); + obj.Validate(); }); } @@ -177,11 +155,10 @@ private void ValidateRequest(HttpRequestData requestData) [Fact] public async Task AllowNullRequesturlAsync() { - const int NumRequests = 4; - await LoopbackServer.CreateClientAndServerAsync( - async uri => + await HttpMessageHandlerLoopbackServer.CreateClientAndServerAsync( + async (handler, uri) => { - using (HttpClient client = new HttpClient()) + using (HttpClient client = new HttpClient(handler)) { client.BaseAddress = uri; @@ -196,10 +173,7 @@ await LoopbackServer.CreateClientAndServerAsync( List headers = new List { new HttpHeaderData("Content-Type", "application/json") }; string json = Person.Create().Serialize(); - for (int i = 0; i < NumRequests; i++) - { - await server.HandleRequestAsync(content: json, headers: headers); - } + await server.HandleRequestAsync(content: json, headers: headers); }); } } diff --git a/src/libraries/System.Net.Http.Json/tests/FunctionalTests/HttpContentJsonExtensionsTests.cs b/src/libraries/System.Net.Http.Json/tests/FunctionalTests/HttpContentJsonExtensionsTests.cs index d381247878f2d..c17fdc10b93b5 100644 --- a/src/libraries/System.Net.Http.Json/tests/FunctionalTests/HttpContentJsonExtensionsTests.cs +++ b/src/libraries/System.Net.Http.Json/tests/FunctionalTests/HttpContentJsonExtensionsTests.cs @@ -28,11 +28,10 @@ public void ThrowOnNull() [Fact] public async Task HttpContentGetThenReadFromJsonAsync() { - const int NumRequests = 2; - await LoopbackServer.CreateClientAndServerAsync( - async uri => + await HttpMessageHandlerLoopbackServer.CreateClientAndServerAsync( + async (handler, uri) => { - using (HttpClient client = new HttpClient()) + using (HttpClient client = new HttpClient(handler)) { var request = new HttpRequestMessage(HttpMethod.Get, uri); HttpResponseMessage response = await client.SendAsync(request); @@ -46,22 +45,16 @@ await LoopbackServer.CreateClientAndServerAsync( per.Validate(); } }, - async server => { - for (int i = 0; i < NumRequests; i++) - { - HttpRequestData req = await server.HandleRequestAsync(headers: _headers, content: Person.Create().Serialize()); - } - }); + server => server.HandleRequestAsync(headers: _headers, content: Person.Create().Serialize())); } [Fact] public async Task HttpContentReturnValueIsNull() { - const int NumRequests = 2; - await LoopbackServer.CreateClientAndServerAsync( - async uri => + await HttpMessageHandlerLoopbackServer.CreateClientAndServerAsync( + async (handler, uri) => { - using (HttpClient client = new HttpClient()) + using (HttpClient client = new HttpClient(handler)) { var request = new HttpRequestMessage(HttpMethod.Get, uri); HttpResponseMessage response = await client.SendAsync(request); @@ -74,21 +67,16 @@ await LoopbackServer.CreateClientAndServerAsync( Assert.Null(per); } }, - async server => { - for (int i = 0; i < NumRequests; i++) - { - HttpRequestData req = await server.HandleRequestAsync(headers: _headers, content: "null"); - } - }); + server => server.HandleRequestAsync(headers: _headers, content: "null")); } [Fact] public async Task TestReadFromJsonNoMessageBodyAsync() { - await LoopbackServer.CreateClientAndServerAsync( - async uri => + await HttpMessageHandlerLoopbackServer.CreateClientAndServerAsync( + async (handler, uri) => { - using (HttpClient client = new HttpClient()) + using (HttpClient client = new HttpClient(handler)) { var request = new HttpRequestMessage(HttpMethod.Get, uri); HttpResponseMessage response = await client.SendAsync(request); @@ -104,10 +92,10 @@ await LoopbackServer.CreateClientAndServerAsync( [Fact] public async Task TestReadFromJsonNoContentTypeAsync() { - await LoopbackServer.CreateClientAndServerAsync( - async uri => + await HttpMessageHandlerLoopbackServer.CreateClientAndServerAsync( + async (handler, uri) => { - using (HttpClient client = new HttpClient()) + using (HttpClient client = new HttpClient(handler)) { var request = new HttpRequestMessage(HttpMethod.Get, uri); HttpResponseMessage response = await client.SendAsync(request); @@ -126,10 +114,10 @@ public async Task TestGetFromJsonQuotedCharSetAsync() new HttpHeaderData("Content-Type", "application/json; charset=\"utf-8\"") }; - await LoopbackServer.CreateClientAndServerAsync( - async uri => + await HttpMessageHandlerLoopbackServer.CreateClientAndServerAsync( + async (handler, uri) => { - using (HttpClient client = new HttpClient()) + using (HttpClient client = new HttpClient(handler)) { var request = new HttpRequestMessage(HttpMethod.Get, uri); HttpResponseMessage response = await client.SendAsync(request); @@ -149,10 +137,10 @@ public async Task TestGetFromJsonThrowOnInvalidCharSetAsync() new HttpHeaderData("Content-Type", "application/json; charset=\"foo-bar\"") }; - await LoopbackServer.CreateClientAndServerAsync( - async uri => + await HttpMessageHandlerLoopbackServer.CreateClientAndServerAsync( + async (handler, uri) => { - using (HttpClient client = new HttpClient()) + using (HttpClient client = new HttpClient(handler)) { var request = new HttpRequestMessage(HttpMethod.Get, uri); HttpResponseMessage response = await client.SendAsync(request); @@ -168,11 +156,10 @@ await LoopbackServer.CreateClientAndServerAsync( public async Task TestGetFromJsonAsyncTextPlainUtf16Async() { const string json = @"{""Name"":""David"",""Age"":24}"; - const int NumRequests = 2; - await LoopbackServer.CreateClientAndServerAsync( - async uri => + await HttpMessageHandlerLoopbackServer.CreateClientAndServerAsync( + async (handler, uri) => { - using (HttpClient client = new HttpClient()) + using (HttpClient client = new HttpClient(handler)) { var request = new HttpRequestMessage(HttpMethod.Get, uri); HttpResponseMessage response = await client.SendAsync(request); @@ -189,33 +176,17 @@ await LoopbackServer.CreateClientAndServerAsync( }, async server => { - byte[] utf16Content = Encoding.Unicode.GetBytes(json); - byte[] bytes = - Encoding.ASCII.GetBytes( - $"HTTP/1.1 200 OK" + - $"\r\nContent-Type: application/json; charset=utf-16\r\n" + - $"Content-Length: {utf16Content.Length}\r\n" + - $"Connection:close\r\n\r\n"); - - - var buffer = new MemoryStream(); - buffer.Write(bytes, 0, bytes.Length); - buffer.Write(utf16Content, 0, utf16Content.Length); - - for (int i = 0; i < NumRequests; i++) - { - await server.AcceptConnectionSendCustomResponseAndCloseAsync(buffer.ToArray()); - } + var headers = new List { new HttpHeaderData("Content-Type", "application/json; charset=utf-16") }; + await server.HandleRequestAsync(statusCode: HttpStatusCode.OK, headers: headers, bytes: Encoding.Unicode.GetBytes(json)); }); } - [Fact] public async Task EnsureDefaultJsonSerializerOptionsAsync() { - await LoopbackServer.CreateClientAndServerAsync( - async uri => + await HttpMessageHandlerLoopbackServer.CreateClientAndServerAsync( + async (handler, uri) => { - using (HttpClient client = new HttpClient()) + using (HttpClient client = new HttpClient(handler)) { var request = new HttpRequestMessage(HttpMethod.Get, uri); HttpResponseMessage response = await client.SendAsync(request); @@ -238,10 +209,10 @@ public async Task TestValidMediaTypes(string mediaType) new HttpHeaderData("Content-Type", $"{mediaType}; charset=\"utf-8\"") }; - await LoopbackServer.CreateClientAndServerAsync( - async uri => + await HttpMessageHandlerLoopbackServer.CreateClientAndServerAsync( + async (handler, uri) => { - using (HttpClient client = new HttpClient()) + using (HttpClient client = new HttpClient(handler)) { var request = new HttpRequestMessage(HttpMethod.Get, uri); HttpResponseMessage response = await client.SendAsync(request); @@ -268,10 +239,10 @@ public async Task TestInvalidMediaTypeAsync(string mediaType) new HttpHeaderData("Content-Type", $"{mediaType}; charset=\"utf-8\"") }; - await LoopbackServer.CreateClientAndServerAsync( - async uri => + await HttpMessageHandlerLoopbackServer.CreateClientAndServerAsync( + async (handler, uri) => { - using (HttpClient client = new HttpClient()) + using (HttpClient client = new HttpClient(handler)) { var request = new HttpRequestMessage(HttpMethod.Get, uri); HttpResponseMessage response = await client.SendAsync(request); diff --git a/src/libraries/System.Net.Http.Json/tests/FunctionalTests/JsonContentTests.cs b/src/libraries/System.Net.Http.Json/tests/FunctionalTests/JsonContentTests.cs index 243f303f49cf5..73ac444999f59 100644 --- a/src/libraries/System.Net.Http.Json/tests/FunctionalTests/JsonContentTests.cs +++ b/src/libraries/System.Net.Http.Json/tests/FunctionalTests/JsonContentTests.cs @@ -71,11 +71,10 @@ public void TestJsonContentMediaType() [Fact] public async Task SendQuotedCharsetAsync() { - - await LoopbackServer.CreateClientAndServerAsync( - async uri => + await HttpMessageHandlerLoopbackServer.CreateClientAndServerAsync( + async (handler, uri) => { - using (HttpClient client = new HttpClient()) + using (HttpClient client = new HttpClient(handler)) { JsonContent content = JsonContent.Create(null); content.Headers.ContentType.CharSet = "\"utf-8\""; @@ -106,10 +105,10 @@ public void TestJsonContentContentTypeIsNotTheSameOnMultipleInstances() [Fact] public async Task JsonContentMediaTypeValidateOnServerAsync() { - await LoopbackServer.CreateClientAndServerAsync( - async uri => + await HttpMessageHandlerLoopbackServer.CreateClientAndServerAsync( + async (handler, uri) => { - using (HttpClient client = new HttpClient()) + using (HttpClient client = new HttpClient(handler)) { var request = new HttpRequestMessage(HttpMethod.Post, uri); MediaTypeHeaderValue mediaType = MediaTypeHeaderValue.Parse("foo/bar; charset=utf-8"); @@ -163,10 +162,10 @@ public void JsonContentThrowsOnIncompatibleTypeAsync() [Fact] public static async Task ValidateUtf16IsTranscodedAsync() { - await LoopbackServer.CreateClientAndServerAsync( - async uri => + await HttpMessageHandlerLoopbackServer.CreateClientAndServerAsync( + async (handler, uri) => { - using (HttpClient client = new HttpClient()) + using (HttpClient client = new HttpClient(handler)) { var request = new HttpRequestMessage(HttpMethod.Post, uri); MediaTypeHeaderValue mediaType = MediaTypeHeaderValue.Parse("application/json; charset=utf-16"); @@ -186,10 +185,10 @@ await LoopbackServer.CreateClientAndServerAsync( [Fact] public async Task EnsureDefaultJsonSerializerOptionsAsync() { - await LoopbackServer.CreateClientAndServerAsync( - async uri => + await HttpMessageHandlerLoopbackServer.CreateClientAndServerAsync( + async (handler, uri) => { - using (HttpClient client = new HttpClient()) + using (HttpClient client = new HttpClient(handler)) { // EnsureDefaultOptions uses a JsonConverter where we validate the JsonSerializerOptions when not provided to JsonContent.Create. EnsureDefaultOptions dummyObj = new EnsureDefaultOptions(); @@ -204,10 +203,10 @@ await LoopbackServer.CreateClientAndServerAsync( [Fact] public async Task TestJsonContentNullContentTypeAsync() { - await LoopbackServer.CreateClientAndServerAsync( - async uri => + await HttpMessageHandlerLoopbackServer.CreateClientAndServerAsync( + async (handler, uri) => { - using (HttpClient client = new HttpClient()) + using (HttpClient client = new HttpClient(handler)) { var request = new HttpRequestMessage(HttpMethod.Post, uri); MediaTypeHeaderValue mediaType = MediaTypeHeaderValue.Parse("application/json; charset=utf-16"); diff --git a/src/libraries/System.Net.Http.Json/tests/FunctionalTests/System.Net.Http.Json.Functional.Tests.csproj b/src/libraries/System.Net.Http.Json/tests/FunctionalTests/System.Net.Http.Json.Functional.Tests.csproj index ed58820d081f1..8d3e902f6a656 100644 --- a/src/libraries/System.Net.Http.Json/tests/FunctionalTests/System.Net.Http.Json.Functional.Tests.csproj +++ b/src/libraries/System.Net.Http.Json/tests/FunctionalTests/System.Net.Http.Json.Functional.Tests.csproj @@ -3,7 +3,6 @@ $(NetCoreAppCurrent);$(NetFrameworkCurrent) - @@ -20,10 +19,8 @@ Link="Common\System\Net\Configuration.Http.cs" /> - - + -