Skip to content
This repository was archived by the owner on Dec 18, 2018. It is now read-only.

Commit 6cc9b8d

Browse files
committed
WIP: HttpsConnectionMiddleware
1 parent 68a0863 commit 6cc9b8d

File tree

20 files changed

+561
-259
lines changed

20 files changed

+561
-259
lines changed

src/Kestrel.Core/Adapter/Internal/AdaptedPipeline.cs

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System;
55
using System.IO;
66
using System.IO.Pipelines;
7+
using System.Threading;
78
using System.Threading.Tasks;
89
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http;
910
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure;
@@ -12,16 +13,16 @@
1213

1314
namespace Microsoft.AspNetCore.Server.Kestrel.Core.Adapter.Internal
1415
{
15-
public class AdaptedPipeline : IDuplexPipe
16+
public class AdaptedPipeline : IDuplexPipe, IDisposable
1617
{
1718
private static readonly int MinAllocBufferSize = KestrelMemoryPool.MinimumSegmentSize / 2;
1819

1920
private readonly IDuplexPipe _transport;
2021

21-
public AdaptedPipeline(IDuplexPipe transport,
22-
Pipe inputPipe,
22+
public AdaptedPipeline(Pipe inputPipe,
2323
Pipe outputPipe,
24-
IKestrelTrace log)
24+
ILogger log,
25+
IDuplexPipe transport = null)
2526
{
2627
_transport = transport;
2728
Input = inputPipe;
@@ -33,7 +34,7 @@ public AdaptedPipeline(IDuplexPipe transport,
3334

3435
public Pipe Output { get; }
3536

36-
public IKestrelTrace Log { get; }
37+
public ILogger Log { get; }
3738

3839
PipeReader IDuplexPipe.Input => Input.Reader;
3940

@@ -111,7 +112,8 @@ private async Task WriteOutputAsync(Stream stream)
111112
finally
112113
{
113114
Output.Reader.Complete();
114-
_transport.Output.Complete();
115+
116+
_transport?.Output.Complete();
115117
}
116118
}
117119

@@ -163,10 +165,17 @@ private async Task ReadInputAsync(Stream stream)
163165
finally
164166
{
165167
Input.Writer.Complete(error);
168+
166169
// The application could have ended the input pipe so complete
167170
// the transport pipe as well
168-
_transport.Input.Complete();
171+
_transport?.Input.Complete();
169172
}
170173
}
174+
175+
public void Dispose()
176+
{
177+
Input.Reader.Complete();
178+
Output.Writer.Complete();
179+
}
171180
}
172181
}

src/Kestrel.Core/Adapter/Internal/RawStream.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -61,18 +61,18 @@ public override int Read(byte[] buffer, int offset, int count)
6161
{
6262
// ValueTask uses .GetAwaiter().GetResult() if necessary
6363
// https://github.com/dotnet/corefx/blob/f9da3b4af08214764a51b2331f3595ffaf162abe/src/System.Threading.Tasks.Extensions/src/System/Threading/Tasks/ValueTask.cs#L156
64-
return ReadAsyncInternal(new Memory<byte>(buffer, offset, count)).Result;
64+
return ReadAsyncInternal(new Memory<byte>(buffer, offset, count), default).Result;
6565
}
6666

6767
public override Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
6868
{
69-
return ReadAsyncInternal(new Memory<byte>(buffer, offset, count)).AsTask();
69+
return ReadAsyncInternal(new Memory<byte>(buffer, offset, count), cancellationToken).AsTask();
7070
}
7171

7272
#if NETCOREAPP2_1
7373
public override ValueTask<int> ReadAsync(Memory<byte> destination, CancellationToken cancellationToken = default)
7474
{
75-
return ReadAsyncInternal(destination);
75+
return ReadAsyncInternal(destination, cancellationToken);
7676
}
7777
#elif NETSTANDARD2_0
7878
#else
@@ -115,11 +115,11 @@ public override Task FlushAsync(CancellationToken cancellationToken)
115115
return WriteAsync(null, 0, 0, cancellationToken);
116116
}
117117

118-
private async ValueTask<int> ReadAsyncInternal(Memory<byte> destination)
118+
private async ValueTask<int> ReadAsyncInternal(Memory<byte> destination, CancellationToken cancellationToken)
119119
{
120120
while (true)
121121
{
122-
var result = await _input.ReadAsync();
122+
var result = await _input.ReadAsync(cancellationToken);
123123
var readableBuffer = result.Buffer;
124124
try
125125
{

src/Kestrel.Core/HttpsConnectionAdapterOptions.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,14 @@
22
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
33

44
using System;
5+
using System.IO.Pipelines;
56
using System.Net.Security;
67
using System.Security.Authentication;
78
using System.Security.Cryptography.X509Certificates;
89
using System.Threading;
910
using Microsoft.AspNetCore.Connections;
1011
using Microsoft.AspNetCore.Server.Kestrel.Core;
12+
using Microsoft.Extensions.Logging;
1113

1214
namespace Microsoft.AspNetCore.Server.Kestrel.Https
1315
{
@@ -75,6 +77,12 @@ public HttpsConnectionAdapterOptions()
7577
/// </summary>
7678
public bool CheckCertificateRevocation { get; set; }
7779

80+
internal PipeScheduler Scheduler { get; set; } = PipeScheduler.ThreadPool;
81+
82+
internal long? MaxInputBufferSize { get; set; }
83+
84+
internal long? MaxOutputBufferSize { get; set; }
85+
7886
/// <summary>
7987
/// Specifies the maximum amount of time allowed for the TLS/SSL handshake. This must be positive and finite.
8088
/// </summary>

src/Kestrel.Core/Internal/AddressBinder.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -170,8 +170,7 @@ public async Task BindAsync(AddressBindContext context)
170170
var httpsDefault = ParseAddress(Constants.DefaultServerHttpsAddress, out https);
171171
context.ServerOptions.ApplyEndpointDefaults(httpsDefault);
172172

173-
if (httpsDefault.ConnectionAdapters.Any(f => f.IsHttps)
174-
|| httpsDefault.TryUseHttps())
173+
if (httpsDefault.IsTls || httpsDefault.TryUseHttps())
175174
{
176175
await httpsDefault.BindAsync(context).ConfigureAwait(false);
177176
context.Logger.LogDebug(CoreStrings.BindingToDefaultAddresses,
@@ -254,7 +253,7 @@ public virtual async Task BindAsync(AddressBindContext context)
254253
var options = ParseAddress(address, out var https);
255254
context.ServerOptions.ApplyEndpointDefaults(options);
256255

257-
if (https && !options.ConnectionAdapters.Any(f => f.IsHttps))
256+
if (https && !options.IsTls)
258257
{
259258
options.UseHttps();
260259
}

src/Kestrel.Core/Internal/Http/Http1Connection.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ public void Abort(ConnectionAbortedException abortReason)
7171
}
7272

7373
// Abort output prior to calling OnIOCompleted() to give the transport the chance to complete the input
74-
// with the correct error and message.
74+
// with the correct error and message.
7575
Output.Abort(abortReason);
7676

7777
OnInputOrOutputCompleted();

src/Kestrel.Core/Internal/HttpConnection.cs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -110,10 +110,10 @@ public async Task ProcessRequestsAsync<TContext>(IHttpApplication<TContext> http
110110

111111
if (_context.ConnectionAdapters.Count > 0)
112112
{
113-
adaptedPipeline = new AdaptedPipeline(_adaptedTransport,
114-
new Pipe(AdaptedInputPipeOptions),
113+
adaptedPipeline = new AdaptedPipeline(new Pipe(AdaptedInputPipeOptions),
115114
new Pipe(AdaptedOutputPipeOptions),
116-
Log);
115+
Log,
116+
_adaptedTransport);
117117

118118
_adaptedTransport = adaptedPipeline;
119119
}
@@ -639,8 +639,12 @@ private void CloseUninitializedConnection(ConnectionAbortedException abortReason
639639

640640
_context.ConnectionContext.Abort(abortReason);
641641

642-
_adaptedTransport.Input.Complete();
643-
_adaptedTransport.Output.Complete();
642+
// Back compat
643+
if (_context.ConnectionAdapters.Count > 0)
644+
{
645+
_adaptedTransport.Input.Complete();
646+
_adaptedTransport.Output.Complete();
647+
}
644648
}
645649

646650
private enum ProtocolSelectionState

src/Kestrel.Core/Internal/HttpConnectionMiddleware.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,6 @@ public HttpConnectionMiddleware(IList<IConnectionAdapter> adapters, ServiceConte
3333

3434
public Task OnConnectionAsync(ConnectionContext connectionContext)
3535
{
36-
// We need the transport feature so that we can cancel the output reader that the transport is using
37-
// This is a bit of a hack but it preserves the existing semantics
3836
var memoryPoolFeature = connectionContext.Features.Get<IMemoryPoolFeature>();
3937

4038
var httpConnectionContext = new HttpConnectionContext

0 commit comments

Comments
 (0)