Add unit tests for ConectionFilters and HTTPS
- Run all the EngineTests with and without a ConnectionFilter
This commit is contained in:
parent
2f3a00625a
commit
0844369f5f
|
|
@ -6,6 +6,12 @@ using Microsoft.AspNet.Builder;
|
||||||
using Microsoft.AspNet.Http;
|
using Microsoft.AspNet.Http;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
|
#if DNX451
|
||||||
|
using System.IO;
|
||||||
|
using System.Security.Cryptography.X509Certificates;
|
||||||
|
using Microsoft.AspNet.Server.Kestrel.Https;
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace SampleApp
|
namespace SampleApp
|
||||||
{
|
{
|
||||||
public class Startup
|
public class Startup
|
||||||
|
|
@ -16,6 +22,21 @@ namespace SampleApp
|
||||||
|
|
||||||
loggerFactory.AddConsole(LogLevel.Debug);
|
loggerFactory.AddConsole(LogLevel.Debug);
|
||||||
|
|
||||||
|
#if DNX451
|
||||||
|
var testCertPath = Path.Combine(
|
||||||
|
Environment.CurrentDirectory,
|
||||||
|
@"../../test/Microsoft.AspNet.Server.KestrelTests/TestResources/testCert.cer");
|
||||||
|
|
||||||
|
if (File.Exists(testCertPath))
|
||||||
|
{
|
||||||
|
app.UseKestrelHttps(new X509Certificate2(testCertPath));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Console.WriteLine("Could not find certificate at '{0}'. HTTPS is not enabled.", testCertPath);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
app.Run(async context =>
|
app.Run(async context =>
|
||||||
{
|
{
|
||||||
Console.WriteLine("{0} {1}{2}{3}",
|
Console.WriteLine("{0} {1}{2}{3}",
|
||||||
|
|
|
||||||
|
|
@ -17,9 +17,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"commands": {
|
"commands": {
|
||||||
"web": "Microsoft.AspNet.Hosting --server Microsoft.AspNet.Server.Kestrel",
|
"web": "Microsoft.AspNet.Hosting --server Microsoft.AspNet.Server.Kestrel --server.urls http://localhost:5000;https://localhost:5001",
|
||||||
"run": "Microsoft.AspNet.Server.Kestrel",
|
"kestrel": "Microsoft.AspNet.Server.Kestrel --server.urls http://localhost:5000;https://localhost:5001",
|
||||||
"run-socket": "Microsoft.AspNet.Server.Kestrel --server.urls http://unix:/tmp/kestrel-test.sock",
|
"run-socket": "Microsoft.AspNet.Server.Kestrel --server.urls http://unix:/tmp/kestrel-test.sock"
|
||||||
"kestrel": "Microsoft.AspNet.Server.Kestrel --server.urls http://localhost:5000;https://localhost:5001"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,178 @@
|
||||||
|
// 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.IO;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNet.Server.Kestrel.Filter;
|
||||||
|
using Microsoft.AspNet.Server.Kestrel.Http;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNet.Server.KestrelTests
|
||||||
|
{
|
||||||
|
public class ConnectionFilterTests
|
||||||
|
{
|
||||||
|
private async Task App(Frame frame)
|
||||||
|
{
|
||||||
|
frame.ResponseHeaders.Clear();
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
var buffer = new byte[8192];
|
||||||
|
var count = await frame.RequestBody.ReadAsync(buffer, 0, buffer.Length);
|
||||||
|
if (count == 0)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
await frame.ResponseBody.WriteAsync(buffer, 0, count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task CanReadAndWriteWithRewritingConnectionFilter()
|
||||||
|
{
|
||||||
|
var filter = new RewritingConnectionFilter();
|
||||||
|
var serviceContext = new TestServiceContext()
|
||||||
|
{
|
||||||
|
ConnectionFilter = filter
|
||||||
|
};
|
||||||
|
var sendString = "POST / HTTP/1.0\r\n\r\nHello World?";
|
||||||
|
|
||||||
|
using (var server = new TestServer(App, serviceContext))
|
||||||
|
{
|
||||||
|
using (var connection = new TestConnection())
|
||||||
|
{
|
||||||
|
// "?" changes to "!"
|
||||||
|
await connection.SendEnd(sendString);
|
||||||
|
await connection.ReceiveEnd(
|
||||||
|
"HTTP/1.0 200 OK",
|
||||||
|
"",
|
||||||
|
"Hello World!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert.Equal(sendString.Length, filter.BytesRead);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task CanReadAndWriteWithAsyncConnectionFilter()
|
||||||
|
{
|
||||||
|
var serviceContext = new TestServiceContext()
|
||||||
|
{
|
||||||
|
ConnectionFilter = new AsyncConnectionFilter()
|
||||||
|
};
|
||||||
|
|
||||||
|
using (var server = new TestServer(App, serviceContext))
|
||||||
|
{
|
||||||
|
using (var connection = new TestConnection())
|
||||||
|
{
|
||||||
|
await connection.SendEnd(
|
||||||
|
"POST / HTTP/1.0",
|
||||||
|
"",
|
||||||
|
"Hello World?");
|
||||||
|
await connection.ReceiveEnd(
|
||||||
|
"HTTP/1.0 200 OK",
|
||||||
|
"",
|
||||||
|
"Hello World!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class RewritingConnectionFilter : IConnectionFilter
|
||||||
|
{
|
||||||
|
private static Task _empty = Task.FromResult<object>(null);
|
||||||
|
|
||||||
|
private RewritingStream _rewritingStream;
|
||||||
|
|
||||||
|
public Task OnConnection(ConnectionFilterContext context)
|
||||||
|
{
|
||||||
|
_rewritingStream = new RewritingStream(context.Connection);
|
||||||
|
context.Connection = _rewritingStream;
|
||||||
|
return _empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int BytesRead => _rewritingStream.BytesRead;
|
||||||
|
}
|
||||||
|
|
||||||
|
private class AsyncConnectionFilter : IConnectionFilter
|
||||||
|
{
|
||||||
|
public async Task OnConnection(ConnectionFilterContext context)
|
||||||
|
{
|
||||||
|
var oldConnection = context.Connection;
|
||||||
|
|
||||||
|
// Set Connection to null to ensure it isn't used until the returned task completes.
|
||||||
|
context.Connection = null;
|
||||||
|
await Task.Delay(100);
|
||||||
|
|
||||||
|
context.Connection = new RewritingStream(oldConnection);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class RewritingStream : Stream
|
||||||
|
{
|
||||||
|
private readonly Stream _innerStream;
|
||||||
|
|
||||||
|
public RewritingStream(Stream innerStream)
|
||||||
|
{
|
||||||
|
_innerStream = innerStream;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int BytesRead { get; private set; }
|
||||||
|
|
||||||
|
public override bool CanRead => _innerStream.CanRead;
|
||||||
|
|
||||||
|
public override bool CanSeek => _innerStream.CanSeek;
|
||||||
|
|
||||||
|
public override bool CanWrite => _innerStream.CanWrite;
|
||||||
|
|
||||||
|
public override long Length => _innerStream.Length;
|
||||||
|
|
||||||
|
public override long Position
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _innerStream.Position;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_innerStream.Position = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Flush()
|
||||||
|
{
|
||||||
|
// No-op
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int Read(byte[] buffer, int offset, int count)
|
||||||
|
{
|
||||||
|
var actual = _innerStream.Read(buffer, offset, count);
|
||||||
|
|
||||||
|
BytesRead += actual;
|
||||||
|
|
||||||
|
return actual;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override long Seek(long offset, SeekOrigin origin)
|
||||||
|
{
|
||||||
|
return _innerStream.Seek(offset, origin);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void SetLength(long value)
|
||||||
|
{
|
||||||
|
_innerStream.SetLength(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Write(byte[] buffer, int offset, int count)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < buffer.Length; i++)
|
||||||
|
{
|
||||||
|
if (buffer[i] == '?')
|
||||||
|
{
|
||||||
|
buffer[i] = (byte)'!';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_innerStream.Write(buffer, offset, count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -8,6 +8,7 @@ using System.Net.Sockets;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNet.Server.Kestrel;
|
using Microsoft.AspNet.Server.Kestrel;
|
||||||
|
using Microsoft.AspNet.Server.Kestrel.Filter;
|
||||||
using Microsoft.AspNet.Server.Kestrel.Http;
|
using Microsoft.AspNet.Server.Kestrel.Http;
|
||||||
using Microsoft.Dnx.Runtime;
|
using Microsoft.Dnx.Runtime;
|
||||||
using Microsoft.Dnx.Runtime.Infrastructure;
|
using Microsoft.Dnx.Runtime.Infrastructure;
|
||||||
|
|
@ -20,6 +21,25 @@ namespace Microsoft.AspNet.Server.KestrelTests
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class EngineTests
|
public class EngineTests
|
||||||
{
|
{
|
||||||
|
public static TheoryData<ServiceContext> ConnectionFilterData
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return new TheoryData<ServiceContext>
|
||||||
|
{
|
||||||
|
{
|
||||||
|
new TestServiceContext()
|
||||||
|
},
|
||||||
|
{
|
||||||
|
new TestServiceContext
|
||||||
|
{
|
||||||
|
ConnectionFilter = new NoOpConnectionFilter()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private async Task App(Frame frame)
|
private async Task App(Frame frame)
|
||||||
{
|
{
|
||||||
frame.ResponseHeaders.Clear();
|
frame.ResponseHeaders.Clear();
|
||||||
|
|
@ -75,18 +95,20 @@ namespace Microsoft.AspNet.Server.KestrelTests
|
||||||
return Task.FromResult<object>(null);
|
return Task.FromResult<object>(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Theory]
|
||||||
public void EngineCanStartAndStop()
|
[MemberData(nameof(ConnectionFilterData))]
|
||||||
|
public void EngineCanStartAndStop(ServiceContext testContext)
|
||||||
{
|
{
|
||||||
var engine = new KestrelEngine(LibraryManager, new TestServiceContext());
|
var engine = new KestrelEngine(LibraryManager, testContext);
|
||||||
engine.Start(1);
|
engine.Start(1);
|
||||||
engine.Dispose();
|
engine.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Theory]
|
||||||
public void ListenerCanCreateAndDispose()
|
[MemberData(nameof(ConnectionFilterData))]
|
||||||
|
public void ListenerCanCreateAndDispose(ServiceContext testContext)
|
||||||
{
|
{
|
||||||
var engine = new KestrelEngine(LibraryManager, new TestServiceContext());
|
var engine = new KestrelEngine(LibraryManager, testContext);
|
||||||
engine.Start(1);
|
engine.Start(1);
|
||||||
var address = ServerAddress.FromUrl("http://localhost:54321/");
|
var address = ServerAddress.FromUrl("http://localhost:54321/");
|
||||||
var started = engine.CreateServer(address, App);
|
var started = engine.CreateServer(address, App);
|
||||||
|
|
@ -94,11 +116,11 @@ namespace Microsoft.AspNet.Server.KestrelTests
|
||||||
engine.Dispose();
|
engine.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
[Fact]
|
[MemberData(nameof(ConnectionFilterData))]
|
||||||
public void ConnectionCanReadAndWrite()
|
public void ConnectionCanReadAndWrite(ServiceContext testContext)
|
||||||
{
|
{
|
||||||
var engine = new KestrelEngine(LibraryManager, new TestServiceContext());
|
var engine = new KestrelEngine(LibraryManager, testContext);
|
||||||
engine.Start(1);
|
engine.Start(1);
|
||||||
var address = ServerAddress.FromUrl("http://localhost:54321/");
|
var address = ServerAddress.FromUrl("http://localhost:54321/");
|
||||||
var started = engine.CreateServer(address, App);
|
var started = engine.CreateServer(address, App);
|
||||||
|
|
@ -119,10 +141,12 @@ namespace Microsoft.AspNet.Server.KestrelTests
|
||||||
engine.Dispose();
|
engine.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public async Task Http10()
|
[Theory]
|
||||||
|
[MemberData(nameof(ConnectionFilterData))]
|
||||||
|
public async Task Http10(ServiceContext testContext)
|
||||||
{
|
{
|
||||||
using (var server = new TestServer(App))
|
using (var server = new TestServer(App, testContext))
|
||||||
{
|
{
|
||||||
using (var connection = new TestConnection())
|
using (var connection = new TestConnection())
|
||||||
{
|
{
|
||||||
|
|
@ -138,10 +162,12 @@ namespace Microsoft.AspNet.Server.KestrelTests
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public async Task Http11()
|
[Theory]
|
||||||
|
[MemberData(nameof(ConnectionFilterData))]
|
||||||
|
public async Task Http11(ServiceContext testContext)
|
||||||
{
|
{
|
||||||
using (var server = new TestServer(AppChunked))
|
using (var server = new TestServer(AppChunked, testContext))
|
||||||
{
|
{
|
||||||
using (var connection = new TestConnection())
|
using (var connection = new TestConnection())
|
||||||
{
|
{
|
||||||
|
|
@ -165,11 +191,11 @@ namespace Microsoft.AspNet.Server.KestrelTests
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
[Fact]
|
[MemberData(nameof(ConnectionFilterData))]
|
||||||
public async Task Http10ContentLength()
|
public async Task Http10ContentLength(ServiceContext testContext)
|
||||||
{
|
{
|
||||||
using (var server = new TestServer(App))
|
using (var server = new TestServer(App, testContext))
|
||||||
{
|
{
|
||||||
using (var connection = new TestConnection())
|
using (var connection = new TestConnection())
|
||||||
{
|
{
|
||||||
|
|
@ -186,10 +212,11 @@ namespace Microsoft.AspNet.Server.KestrelTests
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Theory]
|
||||||
public async Task Http10TransferEncoding()
|
[MemberData(nameof(ConnectionFilterData))]
|
||||||
|
public async Task Http10TransferEncoding(ServiceContext testContext)
|
||||||
{
|
{
|
||||||
using (var server = new TestServer(App))
|
using (var server = new TestServer(App, testContext))
|
||||||
{
|
{
|
||||||
using (var connection = new TestConnection())
|
using (var connection = new TestConnection())
|
||||||
{
|
{
|
||||||
|
|
@ -206,11 +233,11 @@ namespace Microsoft.AspNet.Server.KestrelTests
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
[Fact]
|
[MemberData(nameof(ConnectionFilterData))]
|
||||||
public async Task Http10KeepAlive()
|
public async Task Http10KeepAlive(ServiceContext testContext)
|
||||||
{
|
{
|
||||||
using (var server = new TestServer(AppChunked))
|
using (var server = new TestServer(AppChunked, testContext))
|
||||||
{
|
{
|
||||||
using (var connection = new TestConnection())
|
using (var connection = new TestConnection())
|
||||||
{
|
{
|
||||||
|
|
@ -235,10 +262,11 @@ namespace Microsoft.AspNet.Server.KestrelTests
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Theory]
|
||||||
public async Task Http10KeepAliveNotUsedIfResponseContentLengthNotSet()
|
[MemberData(nameof(ConnectionFilterData))]
|
||||||
|
public async Task Http10KeepAliveNotUsedIfResponseContentLengthNotSet(ServiceContext testContext)
|
||||||
{
|
{
|
||||||
using (var server = new TestServer(App))
|
using (var server = new TestServer(App, testContext))
|
||||||
{
|
{
|
||||||
using (var connection = new TestConnection())
|
using (var connection = new TestConnection())
|
||||||
{
|
{
|
||||||
|
|
@ -264,8 +292,9 @@ namespace Microsoft.AspNet.Server.KestrelTests
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Theory]
|
||||||
public async Task Http10KeepAliveContentLength()
|
[MemberData(nameof(ConnectionFilterData))]
|
||||||
|
public async Task Http10KeepAliveContentLength(ServiceContext testContext)
|
||||||
{
|
{
|
||||||
using (var server = new TestServer(AppChunked))
|
using (var server = new TestServer(AppChunked))
|
||||||
{
|
{
|
||||||
|
|
@ -294,8 +323,9 @@ namespace Microsoft.AspNet.Server.KestrelTests
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Theory]
|
||||||
public async Task Http10KeepAliveTransferEncoding()
|
[MemberData(nameof(ConnectionFilterData))]
|
||||||
|
public async Task Http10KeepAliveTransferEncoding(ServiceContext testContext)
|
||||||
{
|
{
|
||||||
using (var server = new TestServer(AppChunked))
|
using (var server = new TestServer(AppChunked))
|
||||||
{
|
{
|
||||||
|
|
@ -325,10 +355,11 @@ namespace Microsoft.AspNet.Server.KestrelTests
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Theory]
|
||||||
public async Task Expect100ContinueForBody()
|
[MemberData(nameof(ConnectionFilterData))]
|
||||||
|
public async Task Expect100ContinueForBody(ServiceContext testContext)
|
||||||
{
|
{
|
||||||
using (var server = new TestServer(AppChunked))
|
using (var server = new TestServer(AppChunked, testContext))
|
||||||
{
|
{
|
||||||
using (var connection = new TestConnection())
|
using (var connection = new TestConnection())
|
||||||
{
|
{
|
||||||
|
|
@ -350,11 +381,11 @@ namespace Microsoft.AspNet.Server.KestrelTests
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
[Fact]
|
[MemberData(nameof(ConnectionFilterData))]
|
||||||
public async Task DisconnectingClient()
|
public async Task DisconnectingClient(ServiceContext testContext)
|
||||||
{
|
{
|
||||||
using (var server = new TestServer(App))
|
using (var server = new TestServer(App, testContext))
|
||||||
{
|
{
|
||||||
var socket = new Socket(SocketType.Stream, ProtocolType.IP);
|
var socket = new Socket(SocketType.Stream, ProtocolType.IP);
|
||||||
socket.Connect(IPAddress.Loopback, 54321);
|
socket.Connect(IPAddress.Loopback, 54321);
|
||||||
|
|
@ -375,10 +406,11 @@ namespace Microsoft.AspNet.Server.KestrelTests
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Theory]
|
||||||
public async Task ZeroContentLengthSetAutomaticallyAfterNoWrites()
|
[MemberData(nameof(ConnectionFilterData))]
|
||||||
|
public async Task ZeroContentLengthSetAutomaticallyAfterNoWrites(ServiceContext testContext)
|
||||||
{
|
{
|
||||||
using (var server = new TestServer(EmptyApp))
|
using (var server = new TestServer(EmptyApp, testContext))
|
||||||
{
|
{
|
||||||
using (var connection = new TestConnection())
|
using (var connection = new TestConnection())
|
||||||
{
|
{
|
||||||
|
|
@ -402,10 +434,11 @@ namespace Microsoft.AspNet.Server.KestrelTests
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Theory]
|
||||||
public async Task ZeroContentLengthNotSetAutomaticallyForNonKeepAliveRequests()
|
[MemberData(nameof(ConnectionFilterData))]
|
||||||
|
public async Task ZeroContentLengthNotSetAutomaticallyForNonKeepAliveRequests(ServiceContext testContext)
|
||||||
{
|
{
|
||||||
using (var server = new TestServer(EmptyApp))
|
using (var server = new TestServer(EmptyApp, testContext))
|
||||||
{
|
{
|
||||||
using (var connection = new TestConnection())
|
using (var connection = new TestConnection())
|
||||||
{
|
{
|
||||||
|
|
@ -435,10 +468,11 @@ namespace Microsoft.AspNet.Server.KestrelTests
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Theory]
|
||||||
public async Task ZeroContentLengthNotSetAutomaticallyForHeadRequests()
|
[MemberData(nameof(ConnectionFilterData))]
|
||||||
|
public async Task ZeroContentLengthNotSetAutomaticallyForHeadRequests(ServiceContext testContext)
|
||||||
{
|
{
|
||||||
using (var server = new TestServer(EmptyApp))
|
using (var server = new TestServer(EmptyApp, testContext))
|
||||||
{
|
{
|
||||||
using (var connection = new TestConnection())
|
using (var connection = new TestConnection())
|
||||||
{
|
{
|
||||||
|
|
@ -454,8 +488,9 @@ namespace Microsoft.AspNet.Server.KestrelTests
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Theory]
|
||||||
public async Task ZeroContentLengthNotSetAutomaticallyForCertainStatusCodes()
|
[MemberData(nameof(ConnectionFilterData))]
|
||||||
|
public async Task ZeroContentLengthNotSetAutomaticallyForCertainStatusCodes(ServiceContext testContext)
|
||||||
{
|
{
|
||||||
using (var server = new TestServer(async frame =>
|
using (var server = new TestServer(async frame =>
|
||||||
{
|
{
|
||||||
|
|
@ -466,7 +501,7 @@ namespace Microsoft.AspNet.Server.KestrelTests
|
||||||
var statusString = await reader.ReadLineAsync();
|
var statusString = await reader.ReadLineAsync();
|
||||||
frame.StatusCode = int.Parse(statusString);
|
frame.StatusCode = int.Parse(statusString);
|
||||||
}
|
}
|
||||||
}))
|
}, testContext))
|
||||||
{
|
{
|
||||||
using (var connection = new TestConnection())
|
using (var connection = new TestConnection())
|
||||||
{
|
{
|
||||||
|
|
@ -504,8 +539,9 @@ namespace Microsoft.AspNet.Server.KestrelTests
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Theory]
|
||||||
public async Task ThrowingResultsIn500Response()
|
[MemberData(nameof(ConnectionFilterData))]
|
||||||
|
public async Task ThrowingResultsIn500Response(ServiceContext testContext)
|
||||||
{
|
{
|
||||||
bool onStartingCalled = false;
|
bool onStartingCalled = false;
|
||||||
|
|
||||||
|
|
@ -521,7 +557,7 @@ namespace Microsoft.AspNet.Server.KestrelTests
|
||||||
frame.ResponseHeaders.Clear();
|
frame.ResponseHeaders.Clear();
|
||||||
frame.ResponseHeaders["Content-Length"] = new[] { "11" };
|
frame.ResponseHeaders["Content-Length"] = new[] { "11" };
|
||||||
throw new Exception();
|
throw new Exception();
|
||||||
}))
|
}, testContext))
|
||||||
{
|
{
|
||||||
using (var connection = new TestConnection())
|
using (var connection = new TestConnection())
|
||||||
{
|
{
|
||||||
|
|
@ -555,8 +591,9 @@ namespace Microsoft.AspNet.Server.KestrelTests
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Theory]
|
||||||
public async Task ThrowingAfterWritingKillsConnection()
|
[MemberData(nameof(ConnectionFilterData))]
|
||||||
|
public async Task ThrowingAfterWritingKillsConnection(ServiceContext testContext)
|
||||||
{
|
{
|
||||||
bool onStartingCalled = false;
|
bool onStartingCalled = false;
|
||||||
|
|
||||||
|
|
@ -572,7 +609,7 @@ namespace Microsoft.AspNet.Server.KestrelTests
|
||||||
frame.ResponseHeaders["Content-Length"] = new[] { "11" };
|
frame.ResponseHeaders["Content-Length"] = new[] { "11" };
|
||||||
await frame.ResponseBody.WriteAsync(Encoding.ASCII.GetBytes("Hello World"), 0, 11);
|
await frame.ResponseBody.WriteAsync(Encoding.ASCII.GetBytes("Hello World"), 0, 11);
|
||||||
throw new Exception();
|
throw new Exception();
|
||||||
}))
|
}, testContext))
|
||||||
{
|
{
|
||||||
using (var connection = new TestConnection())
|
using (var connection = new TestConnection())
|
||||||
{
|
{
|
||||||
|
|
@ -591,8 +628,9 @@ namespace Microsoft.AspNet.Server.KestrelTests
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Theory]
|
||||||
public async Task ThrowingAfterPartialWriteKillsConnection()
|
[MemberData(nameof(ConnectionFilterData))]
|
||||||
|
public async Task ThrowingAfterPartialWriteKillsConnection(ServiceContext testContext)
|
||||||
{
|
{
|
||||||
bool onStartingCalled = false;
|
bool onStartingCalled = false;
|
||||||
|
|
||||||
|
|
@ -608,7 +646,7 @@ namespace Microsoft.AspNet.Server.KestrelTests
|
||||||
frame.ResponseHeaders["Content-Length"] = new[] { "11" };
|
frame.ResponseHeaders["Content-Length"] = new[] { "11" };
|
||||||
await frame.ResponseBody.WriteAsync(Encoding.ASCII.GetBytes("Hello"), 0, 5);
|
await frame.ResponseBody.WriteAsync(Encoding.ASCII.GetBytes("Hello"), 0, 5);
|
||||||
throw new Exception();
|
throw new Exception();
|
||||||
}))
|
}, testContext))
|
||||||
{
|
{
|
||||||
using (var connection = new TestConnection())
|
using (var connection = new TestConnection())
|
||||||
{
|
{
|
||||||
|
|
@ -627,10 +665,11 @@ namespace Microsoft.AspNet.Server.KestrelTests
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Theory]
|
||||||
public async Task ConnectionClosesWhenFinReceived()
|
[MemberData(nameof(ConnectionFilterData))]
|
||||||
|
public async Task ConnectionClosesWhenFinReceived(ServiceContext testContext)
|
||||||
{
|
{
|
||||||
using (var server = new TestServer(AppChunked))
|
using (var server = new TestServer(AppChunked, testContext))
|
||||||
{
|
{
|
||||||
using (var connection = new TestConnection())
|
using (var connection = new TestConnection())
|
||||||
{
|
{
|
||||||
|
|
@ -653,10 +692,11 @@ namespace Microsoft.AspNet.Server.KestrelTests
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Theory]
|
||||||
public async Task ConnectionClosesWhenFinReceivedBeforeRequestCompletes()
|
[MemberData(nameof(ConnectionFilterData))]
|
||||||
|
public async Task ConnectionClosesWhenFinReceivedBeforeRequestCompletes(ServiceContext testContext)
|
||||||
{
|
{
|
||||||
using (var server = new TestServer(AppChunked))
|
using (var server = new TestServer(AppChunked, testContext))
|
||||||
{
|
{
|
||||||
using (var connection = new TestConnection())
|
using (var connection = new TestConnection())
|
||||||
{
|
{
|
||||||
|
|
@ -694,8 +734,9 @@ namespace Microsoft.AspNet.Server.KestrelTests
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Theory]
|
||||||
public async Task ThrowingInOnStartingResultsIn500Response()
|
[MemberData(nameof(ConnectionFilterData))]
|
||||||
|
public async Task ThrowingInOnStartingResultsIn500Response(ServiceContext testContext)
|
||||||
{
|
{
|
||||||
using (var server = new TestServer(frame =>
|
using (var server = new TestServer(frame =>
|
||||||
{
|
{
|
||||||
|
|
@ -710,7 +751,7 @@ namespace Microsoft.AspNet.Server.KestrelTests
|
||||||
// If we write to the response stream, we will not get a 500.
|
// If we write to the response stream, we will not get a 500.
|
||||||
|
|
||||||
return Task.FromResult<object>(null);
|
return Task.FromResult<object>(null);
|
||||||
}))
|
}, testContext))
|
||||||
{
|
{
|
||||||
using (var connection = new TestConnection())
|
using (var connection = new TestConnection())
|
||||||
{
|
{
|
||||||
|
|
@ -742,8 +783,9 @@ namespace Microsoft.AspNet.Server.KestrelTests
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Theory]
|
||||||
public async Task ThrowingInOnStartingResultsInFailedWrites()
|
[MemberData(nameof(ConnectionFilterData))]
|
||||||
|
public async Task ThrowingInOnStartingResultsInFailedWrites(ServiceContext testContext)
|
||||||
{
|
{
|
||||||
using (var server = new TestServer(async frame =>
|
using (var server = new TestServer(async frame =>
|
||||||
{
|
{
|
||||||
|
|
@ -764,7 +806,7 @@ namespace Microsoft.AspNet.Server.KestrelTests
|
||||||
|
|
||||||
// The second write should succeed since the OnStarting callback will not be called again
|
// The second write should succeed since the OnStarting callback will not be called again
|
||||||
await frame.ResponseBody.WriteAsync(Encoding.ASCII.GetBytes("Exception!!"), 0, 11);
|
await frame.ResponseBody.WriteAsync(Encoding.ASCII.GetBytes("Exception!!"), 0, 11);
|
||||||
}))
|
}, testContext))
|
||||||
{
|
{
|
||||||
using (var connection = new TestConnection())
|
using (var connection = new TestConnection())
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,74 @@
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
#if DNX451
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Net;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Net.Security;
|
||||||
|
using System.Security.Cryptography.X509Certificates;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNet.Server.Kestrel.Filter;
|
||||||
|
using Microsoft.AspNet.Server.Kestrel.Http;
|
||||||
|
using Microsoft.AspNet.Server.Kestrel.Https;
|
||||||
|
using Microsoft.AspNet.Testing.xunit;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNet.Server.KestrelTests
|
||||||
|
{
|
||||||
|
public class HttpsConnectionFilterTests
|
||||||
|
{
|
||||||
|
private async Task App(Frame frame)
|
||||||
|
{
|
||||||
|
frame.ResponseHeaders.Clear();
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
var buffer = new byte[8192];
|
||||||
|
var count = await frame.RequestBody.ReadAsync(buffer, 0, buffer.Length);
|
||||||
|
if (count == 0)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
await frame.ResponseBody.WriteAsync(buffer, 0, count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://github.com/aspnet/KestrelHttpServer/issues/240
|
||||||
|
// This test currently fails on mono because of an issue with SslStream.
|
||||||
|
[ConditionalFact]
|
||||||
|
[OSSkipCondition(OperatingSystems.Linux | OperatingSystems.MacOSX)]
|
||||||
|
public async Task CanReadAndWriteWithHttpsConnectionFilter()
|
||||||
|
{
|
||||||
|
RemoteCertificateValidationCallback validationCallback =
|
||||||
|
(sender, cert, chain, sslPolicyErrors) => true;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ServicePointManager.ServerCertificateValidationCallback += validationCallback;
|
||||||
|
|
||||||
|
var sereverAddress = "https://localhost:54321/";
|
||||||
|
var serviceContext = new TestServiceContext()
|
||||||
|
{
|
||||||
|
ConnectionFilter = new HttpsConnectionFilter(new X509Certificate2(@"TestResources/testCert.cer"), new NoOpConnectionFilter())
|
||||||
|
};
|
||||||
|
|
||||||
|
using (var server = new TestServer(App, serviceContext, sereverAddress))
|
||||||
|
{
|
||||||
|
using (var client = new HttpClient())
|
||||||
|
{
|
||||||
|
var result = await client.PostAsync(sereverAddress, new FormUrlEncodedContent(new[] {
|
||||||
|
new KeyValuePair<string, string>("content", "Hello World?")
|
||||||
|
}));
|
||||||
|
|
||||||
|
Assert.Equal("content=Hello+World%3F", await result.Content.ReadAsStringAsync());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
ServicePointManager.ServerCertificateValidationCallback -= validationCallback;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
Binary file not shown.
|
|
@ -19,8 +19,17 @@ namespace Microsoft.AspNet.Server.KestrelTests
|
||||||
private IDisposable _server;
|
private IDisposable _server;
|
||||||
|
|
||||||
public TestServer(Func<Frame, Task> app)
|
public TestServer(Func<Frame, Task> app)
|
||||||
|
: this(app, new TestServiceContext())
|
||||||
{
|
{
|
||||||
Create(app);
|
}
|
||||||
|
|
||||||
|
public TestServer(Func<Frame, Task> app, ServiceContext context)
|
||||||
|
: this(app, context, "http://localhost:54321/")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
public TestServer(Func<Frame, Task> app, ServiceContext context, string serverAddress)
|
||||||
|
{
|
||||||
|
Create(app, context, serverAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
ILibraryManager LibraryManager
|
ILibraryManager LibraryManager
|
||||||
|
|
@ -45,14 +54,14 @@ namespace Microsoft.AspNet.Server.KestrelTests
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Create(Func<Frame, Task> app)
|
public void Create(Func<Frame, Task> app, ServiceContext context, string serverAddress)
|
||||||
{
|
{
|
||||||
_engine = new KestrelEngine(
|
_engine = new KestrelEngine(
|
||||||
LibraryManager,
|
LibraryManager,
|
||||||
new TestServiceContext());
|
context);
|
||||||
_engine.Start(1);
|
_engine.Start(1);
|
||||||
_server = _engine.CreateServer(
|
_server = _engine.CreateServer(
|
||||||
ServerAddress.FromUrl("http://localhost:54321/"),
|
ServerAddress.FromUrl(serverAddress),
|
||||||
app);
|
app);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,10 +2,16 @@
|
||||||
"version": "1.0.0-*",
|
"version": "1.0.0-*",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"xunit.runner.aspnet": "2.0.0-aspnet-*",
|
"xunit.runner.aspnet": "2.0.0-aspnet-*",
|
||||||
"Microsoft.AspNet.Server.Kestrel": "1.0.0-*"
|
"Microsoft.AspNet.Server.Kestrel": "1.0.0-*",
|
||||||
|
"Microsoft.AspNet.Testing": "1.0.0-*"
|
||||||
},
|
},
|
||||||
"frameworks": {
|
"frameworks": {
|
||||||
"dnx451": { },
|
"dnx451": {
|
||||||
|
"dependencies": {
|
||||||
|
"System.Net.Http": "4.0.1-beta-*",
|
||||||
|
"Microsoft.AspNet.Server.Kestrel.Https": "1.0.0-*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"dnxcore50": {
|
"dnxcore50": {
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"System.Diagnostics.TraceSource": "4.0.0-beta-*",
|
"System.Diagnostics.TraceSource": "4.0.0-beta-*",
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue