diff --git a/KestrelHttpServer.sln b/KestrelHttpServer.sln index c1ba2b1753..56420c09fa 100644 --- a/KestrelHttpServer.sln +++ b/KestrelHttpServer.sln @@ -1,6 +1,6 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 -VisualStudioVersion = 15.0.26510.0 +VisualStudioVersion = 15.0.26621.2 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{7972A5D6-3385-4127-9277-428506DD44FF}" ProjectSection(SolutionItems) = preProject @@ -20,7 +20,6 @@ EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "shared", "shared", "{0EF2ACDF-012F-4472-A13A-4272419E2903}" ProjectSection(SolutionItems) = preProject test\shared\DummyApplication.cs = test\shared\DummyApplication.cs - test\shared\HttpClientSlim.cs = test\shared\HttpClientSlim.cs test\shared\HttpParsingData.cs = test\shared\HttpParsingData.cs test\shared\KestrelTestLoggerProvider.cs = test\shared\KestrelTestLoggerProvider.cs test\shared\LifetimeNotImplemented.cs = test\shared\LifetimeNotImplemented.cs @@ -270,4 +269,7 @@ Global {D95A7EC3-48AC-4D03-B2E2-0DA3E13BD3A4} = {D3273454-EA07-41D2-BF0B-FCC3675C2483} {4F1C30F8-CCAA-48D7-9DF6-2A84021F5BCC} = {D3273454-EA07-41D2-BF0B-FCC3675C2483} EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {2D10D020-6770-47CA-BB8D-2C23FE3AE071} + EndGlobalSection EndGlobal diff --git a/test/Microsoft.AspNetCore.Server.Kestrel.FunctionalTests/HttpClientSlimTests.cs b/test/Microsoft.AspNetCore.Server.Kestrel.FunctionalTests/HttpClientSlimTests.cs deleted file mode 100644 index 7410d7d656..0000000000 --- a/test/Microsoft.AspNetCore.Server.Kestrel.FunctionalTests/HttpClientSlimTests.cs +++ /dev/null @@ -1,109 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Net; -using System.Net.Http; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Testing; -using Xunit; - -namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests -{ - public class HttpClientSlimTests - { - [Fact] - public async Task GetStringAsyncHttp() - { - using (var host = StartHost()) - { - Assert.Equal("test", await HttpClientSlim.GetStringAsync(host.GetUri())); - } - } - - [Fact] - public async Task GetStringAsyncHttps() - { - using (var host = StartHost(protocol: "https")) - { - Assert.Equal("test", await HttpClientSlim.GetStringAsync(host.GetUri(isHttps: true), validateCertificate: false)); - } - } - - [Fact] - public async Task GetStringAsyncThrowsForErrorResponse() - { - using (var host = StartHost(statusCode: StatusCodes.Status500InternalServerError)) - { - await Assert.ThrowsAnyAsync(() => HttpClientSlim.GetStringAsync(host.GetUri())); - } - } - - [Fact] - public async Task PostAsyncHttp() - { - using (var host = StartHost(handler: (context) => context.Request.Body.CopyToAsync(context.Response.Body))) - { - Assert.Equal("test post", await HttpClientSlim.PostAsync(host.GetUri(), new StringContent("test post"))); - } - } - - [Fact] - public async Task PostAsyncHttps() - { - using (var host = StartHost(protocol: "https", - handler: (context) => context.Request.Body.CopyToAsync(context.Response.Body))) - { - Assert.Equal("test post", await HttpClientSlim.PostAsync(host.GetUri(isHttps: true), - new StringContent("test post"), validateCertificate: false)); - } - } - - [Fact] - public async Task PostAsyncThrowsForErrorResponse() - { - using (var host = StartHost(statusCode: StatusCodes.Status500InternalServerError)) - { - await Assert.ThrowsAnyAsync( - () => HttpClientSlim.PostAsync(host.GetUri(), new StringContent(""))); - } - } - - private IWebHost StartHost(string protocol = "http", int statusCode = StatusCodes.Status200OK, Func handler = null) - { - var host = new WebHostBuilder() - .UseKestrel(options => - { - options.Listen(new IPEndPoint(IPAddress.Loopback, 0), listenOptions => - { - if (protocol == "https") - { - listenOptions.UseHttps(TestResources.TestCertificatePath, "testPassword"); - } - }); - }) - .Configure((app) => - { - app.Run(context => - { - context.Response.StatusCode = statusCode; - if (handler == null) - { - return context.Response.WriteAsync("test"); - } - else - { - return handler(context); - } - }); - }) - .Build(); - - host.Start(); - return host; - } - } -} diff --git a/test/Microsoft.AspNetCore.Server.Kestrel.FunctionalTests/TestHelpers/IWebHostPortExtensions.cs b/test/Microsoft.AspNetCore.Server.Kestrel.FunctionalTests/TestHelpers/IWebHostPortExtensions.cs index 11e8f4fa0f..2f3ae47c24 100644 --- a/test/Microsoft.AspNetCore.Server.Kestrel.FunctionalTests/TestHelpers/IWebHostPortExtensions.cs +++ b/test/Microsoft.AspNetCore.Server.Kestrel.FunctionalTests/TestHelpers/IWebHostPortExtensions.cs @@ -10,24 +10,11 @@ namespace Microsoft.AspNetCore.Hosting { public static class IWebHostPortExtensions { - public static string GetHost(this IWebHost host, bool isHttps = false) - { - return host.GetUri(isHttps).Host; - } - public static int GetPort(this IWebHost host) { return host.GetPorts().First(); } - public static int GetPort(this IWebHost host, string scheme) - { - return host.GetUris() - .Where(u => u.Scheme.Equals(scheme, StringComparison.OrdinalIgnoreCase)) - .Select(u => u.Port) - .First(); - } - public static IEnumerable GetPorts(this IWebHost host) { return host.GetUris() @@ -39,27 +26,5 @@ namespace Microsoft.AspNetCore.Hosting return host.ServerFeatures.Get().Addresses .Select(a => new Uri(a)); } - - public static Uri GetUri(this IWebHost host, bool isHttps = false) - { - var uri = host.GetUris().First(); - - if (isHttps && uri.Scheme == "http") - { - var uriBuilder = new UriBuilder(uri) - { - Scheme = "https", - }; - - if (uri.Port == 80) - { - uriBuilder.Port = 443; - } - - return uriBuilder.Uri; - } - - return uri; - } } } diff --git a/test/shared/HttpClientSlim.cs b/test/shared/HttpClientSlim.cs deleted file mode 100644 index a85b03aa40..0000000000 --- a/test/shared/HttpClientSlim.cs +++ /dev/null @@ -1,130 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.IO; -using System.Net; -using System.Net.Http; -using System.Net.Security; -using System.Net.Sockets; -using System.Security.Authentication; -using System.Text; -using System.Threading.Tasks; - -namespace Microsoft.AspNetCore.Testing -{ - // Lightweight version of HttpClient implemented using Socket and SslStream - public static class HttpClientSlim - { - public static async Task GetStringAsync(string requestUri, bool validateCertificate = true) - => await GetStringAsync(new Uri(requestUri), validateCertificate).ConfigureAwait(false); - - public static async Task GetStringAsync(Uri requestUri, bool validateCertificate = true) - { - using (var stream = await GetStream(requestUri, validateCertificate).ConfigureAwait(false)) - { - using (var writer = new StreamWriter(stream, Encoding.ASCII, bufferSize: 1024, leaveOpen: true)) - { - await writer.WriteAsync($"GET {requestUri.PathAndQuery} HTTP/1.0\r\n").ConfigureAwait(false); - await writer.WriteAsync($"Host: {requestUri.Authority}\r\n").ConfigureAwait(false); - await writer.WriteAsync("\r\n").ConfigureAwait(false); - } - - return await ReadResponse(stream).ConfigureAwait(false); - } - } - - public static async Task PostAsync(string requestUri, HttpContent content, bool validateCertificate = true) - => await PostAsync(new Uri(requestUri), content, validateCertificate).ConfigureAwait(false); - - public static async Task PostAsync(Uri requestUri, HttpContent content, bool validateCertificate = true) - { - using (var stream = await GetStream(requestUri, validateCertificate)) - { - using (var writer = new StreamWriter(stream, Encoding.ASCII, bufferSize: 1024, leaveOpen: true)) - { - await writer.WriteAsync($"POST {requestUri.PathAndQuery} HTTP/1.0\r\n").ConfigureAwait(false); - await writer.WriteAsync($"Host: {requestUri.Authority}\r\n").ConfigureAwait(false); - await writer.WriteAsync($"Content-Type: {content.Headers.ContentType}\r\n").ConfigureAwait(false); - await writer.WriteAsync($"Content-Length: {content.Headers.ContentLength}\r\n").ConfigureAwait(false); - await writer.WriteAsync("\r\n").ConfigureAwait(false); - } - - await content.CopyToAsync(stream).ConfigureAwait(false); - - return await ReadResponse(stream).ConfigureAwait(false); - } - } - - private static async Task ReadResponse(Stream stream) - { - using (var reader = new StreamReader(stream, Encoding.ASCII, detectEncodingFromByteOrderMarks: true, - bufferSize: 1024, leaveOpen: true)) - { - var response = await reader.ReadToEndAsync().ConfigureAwait(false); - - var status = GetStatus(response); - new HttpResponseMessage(status).EnsureSuccessStatusCode(); - - var body = response.Substring(response.IndexOf("\r\n\r\n") + 4); - return body; - } - - } - - private static HttpStatusCode GetStatus(string response) - { - var statusStart = response.IndexOf(' ') + 1; - var statusEnd = response.IndexOf(' ', statusStart) - 1; - var statusLength = statusEnd - statusStart + 1; - return (HttpStatusCode)int.Parse(response.Substring(statusStart, statusLength)); - } - - private static async Task GetStream(Uri requestUri, bool validateCertificate) - { - var socket = await GetSocket(requestUri); - var stream = new NetworkStream(socket, ownsSocket: true); - - if (requestUri.Scheme.Equals("https", StringComparison.OrdinalIgnoreCase)) - { - var sslStream = new SslStream(stream, leaveInnerStreamOpen: false, userCertificateValidationCallback: - validateCertificate ? null : (RemoteCertificateValidationCallback)((a, b, c, d) => true)); - - await sslStream.AuthenticateAsClientAsync(requestUri.Host, clientCertificates: null, - enabledSslProtocols: SslProtocols.Tls11 | SslProtocols.Tls12, - checkCertificateRevocation: validateCertificate).ConfigureAwait(false); - return sslStream; - } - else - { - return stream; - } - } - - public static async Task GetSocket(Uri requestUri) - { - var tcs = new TaskCompletionSource(); - - var socketArgs = new SocketAsyncEventArgs(); - socketArgs.RemoteEndPoint = new DnsEndPoint(requestUri.DnsSafeHost, requestUri.Port); - socketArgs.Completed += (s, e) => tcs.TrySetResult(e.ConnectSocket); - - // Must use static ConnectAsync(), since instance Connect() does not support DNS names on OSX/Linux. - if (Socket.ConnectAsync(SocketType.Stream, ProtocolType.Tcp, socketArgs)) - { - await tcs.Task.ConfigureAwait(false); - } - - var socket = socketArgs.ConnectSocket; - - if (socket == null) - { - throw new SocketException((int)socketArgs.SocketError); - } - else - { - return socket; - } - } - } -}