Create Frame in FrameConnection.
This commit is contained in:
parent
b9518e3684
commit
37f15bdd85
|
|
@ -33,15 +33,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal
|
||||||
var connectionId = CorrelationIdGenerator.GetNextId();
|
var connectionId = CorrelationIdGenerator.GetNextId();
|
||||||
var frameConnectionId = Interlocked.Increment(ref _lastFrameConnectionId);
|
var frameConnectionId = Interlocked.Increment(ref _lastFrameConnectionId);
|
||||||
|
|
||||||
var frameContext = new FrameContext
|
|
||||||
{
|
|
||||||
ConnectionId = connectionId,
|
|
||||||
ConnectionInformation = connectionInfo,
|
|
||||||
ServiceContext = _serviceContext
|
|
||||||
};
|
|
||||||
|
|
||||||
var frame = new Frame<TContext>(_application, frameContext);
|
|
||||||
|
|
||||||
var connection = new FrameConnection(new FrameConnectionContext
|
var connection = new FrameConnection(new FrameConnectionContext
|
||||||
{
|
{
|
||||||
ConnectionId = connectionId,
|
ConnectionId = connectionId,
|
||||||
|
|
@ -49,7 +40,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal
|
||||||
ServiceContext = _serviceContext,
|
ServiceContext = _serviceContext,
|
||||||
ConnectionInformation = connectionInfo,
|
ConnectionInformation = connectionInfo,
|
||||||
ConnectionAdapters = _listenOptions.ConnectionAdapters,
|
ConnectionAdapters = _listenOptions.ConnectionAdapters,
|
||||||
Frame = frame,
|
|
||||||
Input = inputPipe,
|
Input = inputPipe,
|
||||||
Output = outputPipe,
|
Output = outputPipe,
|
||||||
});
|
});
|
||||||
|
|
@ -57,7 +47,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal
|
||||||
// Since data cannot be added to the inputPipe by the transport until OnConnection returns,
|
// Since data cannot be added to the inputPipe by the transport until OnConnection returns,
|
||||||
// Frame.ProcessRequestsAsync is guaranteed to unblock the transport thread before calling
|
// Frame.ProcessRequestsAsync is guaranteed to unblock the transport thread before calling
|
||||||
// application code.
|
// application code.
|
||||||
connection.StartRequestProcessing();
|
connection.StartRequestProcessing<TContext>(_application);
|
||||||
|
|
||||||
return connection;
|
return connection;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ using System.IO;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.Http.Features;
|
using Microsoft.AspNetCore.Http.Features;
|
||||||
|
using Microsoft.AspNetCore.Hosting.Server;
|
||||||
using Microsoft.AspNetCore.Server.Kestrel.Core.Adapter.Internal;
|
using Microsoft.AspNetCore.Server.Kestrel.Core.Adapter.Internal;
|
||||||
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http;
|
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http;
|
||||||
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure;
|
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure;
|
||||||
|
|
@ -20,9 +21,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal
|
||||||
public class FrameConnection : IConnectionContext, ITimeoutControl
|
public class FrameConnection : IConnectionContext, ITimeoutControl
|
||||||
{
|
{
|
||||||
private readonly FrameConnectionContext _context;
|
private readonly FrameConnectionContext _context;
|
||||||
private readonly Frame _frame;
|
|
||||||
private List<IAdaptedConnection> _adaptedConnections;
|
private List<IAdaptedConnection> _adaptedConnections;
|
||||||
private readonly TaskCompletionSource<object> _socketClosedTcs = new TaskCompletionSource<object>(TaskCreationOptions.RunContinuationsAsynchronously);
|
private readonly TaskCompletionSource<object> _socketClosedTcs = new TaskCompletionSource<object>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||||
|
private Frame _frame;
|
||||||
|
|
||||||
private long _lastTimestamp;
|
private long _lastTimestamp;
|
||||||
private long _timeoutTimestamp = long.MaxValue;
|
private long _timeoutTimestamp = long.MaxValue;
|
||||||
|
|
@ -33,7 +34,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal
|
||||||
public FrameConnection(FrameConnectionContext context)
|
public FrameConnection(FrameConnectionContext context)
|
||||||
{
|
{
|
||||||
_context = context;
|
_context = context;
|
||||||
_frame = context.Frame;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public string ConnectionId => _context.ConnectionId;
|
public string ConnectionId => _context.ConnectionId;
|
||||||
|
|
@ -61,12 +61,12 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal
|
||||||
|
|
||||||
private IKestrelTrace Log => _context.ServiceContext.Log;
|
private IKestrelTrace Log => _context.ServiceContext.Log;
|
||||||
|
|
||||||
public void StartRequestProcessing()
|
public void StartRequestProcessing<TContext>(IHttpApplication<TContext> application)
|
||||||
{
|
{
|
||||||
_lifetimeTask = ProcessRequestsAsync();
|
_lifetimeTask = ProcessRequestsAsync<TContext>(application);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task ProcessRequestsAsync()
|
private async Task ProcessRequestsAsync<TContext>(IHttpApplication<TContext> application)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
@ -90,11 +90,19 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal
|
||||||
output = adaptedPipeline.Output;
|
output = adaptedPipeline.Output;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set these before the first await, this is to make sure that we don't yield control
|
// _frame must be initialized before adding the connection to the connection manager
|
||||||
// to the transport until we've added the connection to the connection manager
|
_frame = new Frame<TContext>(application, new FrameContext
|
||||||
_frame.TimeoutControl = this;
|
{
|
||||||
_frame.Input = input;
|
ConnectionId = _context.ConnectionId,
|
||||||
_frame.Output = new OutputProducer(output, ConnectionId, Log);
|
ConnectionInformation = _context.ConnectionInformation,
|
||||||
|
ServiceContext = _context.ServiceContext,
|
||||||
|
TimeoutControl = this,
|
||||||
|
Input = input,
|
||||||
|
Output = output
|
||||||
|
});
|
||||||
|
|
||||||
|
// Do this before the first await so we don't yield control to the transport until we've
|
||||||
|
// added the connection to the connection manager
|
||||||
_context.ServiceContext.ConnectionManager.AddConnection(_context.FrameConnectionId, this);
|
_context.ServiceContext.ConnectionManager.AddConnection(_context.FrameConnectionId, this);
|
||||||
_lastTimestamp = _context.ServiceContext.SystemClock.UtcNow.Ticks;
|
_lastTimestamp = _context.ServiceContext.SystemClock.UtcNow.Ticks;
|
||||||
|
|
||||||
|
|
@ -125,6 +133,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal
|
||||||
|
|
||||||
public void OnConnectionClosed(Exception ex)
|
public void OnConnectionClosed(Exception ex)
|
||||||
{
|
{
|
||||||
|
Debug.Assert(_frame != null, $"nameof({_frame}) is null");
|
||||||
|
|
||||||
// Abort the connection (if not already aborted)
|
// Abort the connection (if not already aborted)
|
||||||
_frame.Abort(ex);
|
_frame.Abort(ex);
|
||||||
|
|
||||||
|
|
@ -133,6 +143,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal
|
||||||
|
|
||||||
public Task StopAsync()
|
public Task StopAsync()
|
||||||
{
|
{
|
||||||
|
Debug.Assert(_frame != null, $"nameof({_frame}) is null");
|
||||||
|
|
||||||
_frame.Stop();
|
_frame.Stop();
|
||||||
|
|
||||||
return _lifetimeTask;
|
return _lifetimeTask;
|
||||||
|
|
@ -140,12 +152,16 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal
|
||||||
|
|
||||||
public void Abort(Exception ex)
|
public void Abort(Exception ex)
|
||||||
{
|
{
|
||||||
|
Debug.Assert(_frame != null, $"nameof({_frame}) is null");
|
||||||
|
|
||||||
// Abort the connection (if not already aborted)
|
// Abort the connection (if not already aborted)
|
||||||
_frame.Abort(ex);
|
_frame.Abort(ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task AbortAsync(Exception ex)
|
public Task AbortAsync(Exception ex)
|
||||||
{
|
{
|
||||||
|
Debug.Assert(_frame != null, $"nameof({_frame}) is null");
|
||||||
|
|
||||||
// Abort the connection (if not already aborted)
|
// Abort the connection (if not already aborted)
|
||||||
_frame.Abort(ex);
|
_frame.Abort(ex);
|
||||||
|
|
||||||
|
|
@ -154,11 +170,15 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal
|
||||||
|
|
||||||
public void Timeout()
|
public void Timeout()
|
||||||
{
|
{
|
||||||
|
Debug.Assert(_frame != null, $"nameof({_frame}) is null");
|
||||||
|
|
||||||
_frame.SetBadRequestState(RequestRejectionReason.RequestTimeout);
|
_frame.SetBadRequestState(RequestRejectionReason.RequestTimeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<Stream> ApplyConnectionAdaptersAsync()
|
private async Task<Stream> ApplyConnectionAdaptersAsync()
|
||||||
{
|
{
|
||||||
|
Debug.Assert(_frame != null, $"nameof({_frame}) is null");
|
||||||
|
|
||||||
var features = new FeatureCollection();
|
var features = new FeatureCollection();
|
||||||
var connectionAdapters = _context.ConnectionAdapters;
|
var connectionAdapters = _context.ConnectionAdapters;
|
||||||
var stream = new RawStream(_context.Input.Reader, _context.Output.Writer);
|
var stream = new RawStream(_context.Input.Reader, _context.Output.Writer);
|
||||||
|
|
@ -202,6 +222,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal
|
||||||
|
|
||||||
public void Tick(DateTimeOffset now)
|
public void Tick(DateTimeOffset now)
|
||||||
{
|
{
|
||||||
|
Debug.Assert(_frame != null, $"nameof({_frame}) is null");
|
||||||
|
|
||||||
var timestamp = now.Ticks;
|
var timestamp = now.Ticks;
|
||||||
|
|
||||||
// TODO: Use PlatformApis.VolatileRead equivalent again
|
// TODO: Use PlatformApis.VolatileRead equivalent again
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal
|
||||||
public ServiceContext ServiceContext { get; set; }
|
public ServiceContext ServiceContext { get; set; }
|
||||||
public List<IConnectionAdapter> ConnectionAdapters { get; set; }
|
public List<IConnectionAdapter> ConnectionAdapters { get; set; }
|
||||||
public IConnectionInformation ConnectionInformation { get; set; }
|
public IConnectionInformation ConnectionInformation { get; set; }
|
||||||
public Frame Frame { get; set; }
|
|
||||||
|
|
||||||
public IPipe Input { get; set; }
|
public IPipe Input { get; set; }
|
||||||
public IPipe Output { get; set; }
|
public IPipe Output { get; set; }
|
||||||
|
|
|
||||||
|
|
@ -96,15 +96,17 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
||||||
FrameControl = this;
|
FrameControl = this;
|
||||||
_keepAliveTicks = ServerOptions.Limits.KeepAliveTimeout.Ticks;
|
_keepAliveTicks = ServerOptions.Limits.KeepAliveTimeout.Ticks;
|
||||||
_requestHeadersTimeoutTicks = ServerOptions.Limits.RequestHeadersTimeout.Ticks;
|
_requestHeadersTimeoutTicks = ServerOptions.Limits.RequestHeadersTimeout.Ticks;
|
||||||
|
|
||||||
|
Output = new OutputProducer(frameContext.Output, frameContext.ConnectionId, frameContext.ServiceContext.Log);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ServiceContext ServiceContext => _frameContext.ServiceContext;
|
public ServiceContext ServiceContext => _frameContext.ServiceContext;
|
||||||
public IConnectionInformation ConnectionInformation => _frameContext.ConnectionInformation;
|
public IConnectionInformation ConnectionInformation => _frameContext.ConnectionInformation;
|
||||||
|
|
||||||
public IPipeReader Input { get; set; }
|
|
||||||
public OutputProducer Output { get; set; }
|
|
||||||
public IFeatureCollection ConnectionFeatures { get; set; }
|
public IFeatureCollection ConnectionFeatures { get; set; }
|
||||||
public ITimeoutControl TimeoutControl { get; set; }
|
public IPipeReader Input => _frameContext.Input;
|
||||||
|
public OutputProducer Output { get; }
|
||||||
|
public ITimeoutControl TimeoutControl => _frameContext.TimeoutControl;
|
||||||
|
|
||||||
protected IKestrelTrace Log => ServiceContext.Log;
|
protected IKestrelTrace Log => ServiceContext.Log;
|
||||||
private DateHeaderValueManager DateHeaderValueManager => ServiceContext.DateHeaderValueManager;
|
private DateHeaderValueManager DateHeaderValueManager => ServiceContext.DateHeaderValueManager;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
// Copyright (c) .NET Foundation. All rights reserved.
|
// 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.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure;
|
||||||
|
using Microsoft.AspNetCore.Server.Kestrel.Internal.System.IO.Pipelines;
|
||||||
using Microsoft.AspNetCore.Server.Kestrel.Transport.Abstractions;
|
using Microsoft.AspNetCore.Server.Kestrel.Transport.Abstractions;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
||||||
|
|
@ -10,5 +12,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
||||||
public string ConnectionId { get; set; }
|
public string ConnectionId { get; set; }
|
||||||
public ServiceContext ServiceContext { get; set; }
|
public ServiceContext ServiceContext { get; set; }
|
||||||
public IConnectionInformation ConnectionInformation { get; set; }
|
public IConnectionInformation ConnectionInformation { get; set; }
|
||||||
|
public ITimeoutControl TimeoutControl { get; set; }
|
||||||
|
public IPipeReader Input { get; set; }
|
||||||
|
public IPipe Output { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http;
|
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http;
|
||||||
|
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure;
|
||||||
using Microsoft.AspNetCore.Server.Kestrel.Transport.Abstractions;
|
using Microsoft.AspNetCore.Server.Kestrel.Transport.Abstractions;
|
||||||
using Microsoft.AspNetCore.Testing;
|
using Microsoft.AspNetCore.Testing;
|
||||||
using Microsoft.Extensions.Primitives;
|
using Microsoft.Extensions.Primitives;
|
||||||
|
|
@ -22,7 +23,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
||||||
var frameContext = new FrameContext
|
var frameContext = new FrameContext
|
||||||
{
|
{
|
||||||
ServiceContext = new TestServiceContext(),
|
ServiceContext = new TestServiceContext(),
|
||||||
ConnectionInformation = Mock.Of<IConnectionInformation>()
|
ConnectionInformation = Mock.Of<IConnectionInformation>(),
|
||||||
|
TimeoutControl = null
|
||||||
};
|
};
|
||||||
|
|
||||||
var frame = new Frame<object>(application: null, frameContext: frameContext);
|
var frame = new Frame<object>(application: null, frameContext: frameContext);
|
||||||
|
|
@ -61,14 +63,14 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
||||||
[InlineData("Ser\u0080ver", "Data")]
|
[InlineData("Ser\u0080ver", "Data")]
|
||||||
[InlineData("Server", "Da\u0080ta")]
|
[InlineData("Server", "Da\u0080ta")]
|
||||||
[InlineData("Unknown\u0080-Header", "Data")]
|
[InlineData("Unknown\u0080-Header", "Data")]
|
||||||
[InlineData("Ser™ver", "Data")]
|
[InlineData("Ser™ver", "Data")]
|
||||||
[InlineData("Server", "Da™ta")]
|
[InlineData("Server", "Da™ta")]
|
||||||
[InlineData("Unknown™-Header", "Data")]
|
[InlineData("Unknown™-Header", "Data")]
|
||||||
[InlineData("Ser™ver", "Data")]
|
[InlineData("Ser™ver", "Data")]
|
||||||
[InlineData("šerver", "Data")]
|
[InlineData("šerver", "Data")]
|
||||||
[InlineData("Server", "Dašta")]
|
[InlineData("Server", "Dašta")]
|
||||||
[InlineData("Unknownš-Header", "Data")]
|
[InlineData("Unknownš-Header", "Data")]
|
||||||
[InlineData("Seršver", "Data")]
|
[InlineData("Seršver", "Data")]
|
||||||
public void AddingControlOrNonAsciiCharactersToHeadersThrows(string key, string value)
|
public void AddingControlOrNonAsciiCharactersToHeadersThrows(string key, string value)
|
||||||
{
|
{
|
||||||
var responseHeaders = new FrameResponseHeaders();
|
var responseHeaders = new FrameResponseHeaders();
|
||||||
|
|
|
||||||
|
|
@ -36,11 +36,12 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
||||||
private readonly PipeFactory _pipelineFactory;
|
private readonly PipeFactory _pipelineFactory;
|
||||||
private ReadCursor _consumed;
|
private ReadCursor _consumed;
|
||||||
private ReadCursor _examined;
|
private ReadCursor _examined;
|
||||||
|
private Mock<ITimeoutControl> _timeoutControl;
|
||||||
|
|
||||||
private class TestFrame<TContext> : Frame<TContext>
|
private class TestFrame<TContext> : Frame<TContext>
|
||||||
{
|
{
|
||||||
public TestFrame(IHttpApplication<TContext> application, FrameContext context)
|
public TestFrame(IHttpApplication<TContext> application, FrameContext context)
|
||||||
: base(application, context)
|
: base(application, context)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -57,21 +58,17 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
||||||
var output = _pipelineFactory.Create();
|
var output = _pipelineFactory.Create();
|
||||||
|
|
||||||
_serviceContext = new TestServiceContext();
|
_serviceContext = new TestServiceContext();
|
||||||
|
_timeoutControl = new Mock<ITimeoutControl>();
|
||||||
_frameContext = new FrameContext
|
_frameContext = new FrameContext
|
||||||
{
|
{
|
||||||
ServiceContext = _serviceContext,
|
ServiceContext = _serviceContext,
|
||||||
ConnectionInformation = Mock.Of<IConnectionInformation>()
|
ConnectionInformation = Mock.Of<IConnectionInformation>(),
|
||||||
};
|
TimeoutControl = _timeoutControl.Object,
|
||||||
|
|
||||||
_frame = new TestFrame<object>(application: null, context: _frameContext)
|
|
||||||
{
|
|
||||||
Input = _input.Reader,
|
Input = _input.Reader,
|
||||||
TimeoutControl = Mock.Of<ITimeoutControl>()
|
Output = output
|
||||||
};
|
};
|
||||||
|
|
||||||
_frame.Output = new OutputProducer(output, "", Mock.Of<IKestrelTrace>());
|
_frame = new TestFrame<object>(application: null, context: _frameContext);
|
||||||
|
|
||||||
_frame.Reset();
|
_frame.Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -343,16 +340,13 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task ParseRequestStartsRequestHeadersTimeoutOnFirstByteAvailable()
|
public async Task ParseRequestStartsRequestHeadersTimeoutOnFirstByteAvailable()
|
||||||
{
|
{
|
||||||
var connectionControl = new Mock<ITimeoutControl>();
|
|
||||||
_frame.TimeoutControl = connectionControl.Object;
|
|
||||||
|
|
||||||
await _input.Writer.WriteAsync(Encoding.ASCII.GetBytes("G"));
|
await _input.Writer.WriteAsync(Encoding.ASCII.GetBytes("G"));
|
||||||
|
|
||||||
_frame.ParseRequest((await _input.Reader.ReadAsync()).Buffer, out _consumed, out _examined);
|
_frame.ParseRequest((await _input.Reader.ReadAsync()).Buffer, out _consumed, out _examined);
|
||||||
_input.Reader.Advance(_consumed, _examined);
|
_input.Reader.Advance(_consumed, _examined);
|
||||||
|
|
||||||
var expectedRequestHeadersTimeout = _serviceContext.ServerOptions.Limits.RequestHeadersTimeout.Ticks;
|
var expectedRequestHeadersTimeout = _serviceContext.ServerOptions.Limits.RequestHeadersTimeout.Ticks;
|
||||||
connectionControl.Verify(cc => cc.ResetTimeout(expectedRequestHeadersTimeout, TimeoutAction.SendTimeoutResponse));
|
_timeoutControl.Verify(cc => cc.ResetTimeout(expectedRequestHeadersTimeout, TimeoutAction.SendTimeoutResponse));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
@ -466,13 +460,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
||||||
[Fact]
|
[Fact]
|
||||||
public void ProcessRequestsAsyncEnablesKeepAliveTimeout()
|
public void ProcessRequestsAsyncEnablesKeepAliveTimeout()
|
||||||
{
|
{
|
||||||
var connectionControl = new Mock<ITimeoutControl>();
|
|
||||||
_frame.TimeoutControl = connectionControl.Object;
|
|
||||||
|
|
||||||
var requestProcessingTask = _frame.ProcessRequestsAsync();
|
var requestProcessingTask = _frame.ProcessRequestsAsync();
|
||||||
|
|
||||||
var expectedKeepAliveTimeout = _serviceContext.ServerOptions.Limits.KeepAliveTimeout.Ticks;
|
var expectedKeepAliveTimeout = _serviceContext.ServerOptions.Limits.KeepAliveTimeout.Ticks;
|
||||||
connectionControl.Verify(cc => cc.SetTimeout(expectedKeepAliveTimeout, TimeoutAction.CloseConnection));
|
_timeoutControl.Verify(cc => cc.SetTimeout(expectedKeepAliveTimeout, TimeoutAction.CloseConnection));
|
||||||
|
|
||||||
_frame.Stop();
|
_frame.Stop();
|
||||||
_input.Writer.Complete();
|
_input.Writer.Complete();
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http;
|
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http;
|
||||||
|
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure;
|
||||||
using Microsoft.AspNetCore.Server.Kestrel.Internal.System.IO.Pipelines;
|
using Microsoft.AspNetCore.Server.Kestrel.Internal.System.IO.Pipelines;
|
||||||
using Microsoft.AspNetCore.Testing;
|
using Microsoft.AspNetCore.Testing;
|
||||||
using Moq;
|
using Moq;
|
||||||
|
|
|
||||||
|
|
@ -7,10 +7,12 @@ using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http;
|
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http;
|
||||||
|
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure;
|
||||||
using Microsoft.AspNetCore.Server.Kestrel.Internal.System.IO.Pipelines;
|
using Microsoft.AspNetCore.Server.Kestrel.Internal.System.IO.Pipelines;
|
||||||
using Microsoft.AspNetCore.Server.Kestrel.Transport.Abstractions;
|
using Microsoft.AspNetCore.Server.Kestrel.Transport.Abstractions;
|
||||||
using Microsoft.AspNetCore.Testing;
|
using Microsoft.AspNetCore.Testing;
|
||||||
using Microsoft.Extensions.Internal;
|
using Microsoft.Extensions.Internal;
|
||||||
|
using Moq;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
||||||
{
|
{
|
||||||
|
|
@ -21,15 +23,17 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
||||||
|
|
||||||
public TestInput()
|
public TestInput()
|
||||||
{
|
{
|
||||||
var innerContext = new FrameContext { ServiceContext = new TestServiceContext() };
|
|
||||||
|
|
||||||
FrameContext = new Frame<object>(null, innerContext);
|
|
||||||
FrameContext.FrameControl = this;
|
|
||||||
|
|
||||||
_memoryPool = new MemoryPool();
|
_memoryPool = new MemoryPool();
|
||||||
_pipelineFactory = new PipeFactory();
|
_pipelineFactory = new PipeFactory();
|
||||||
|
|
||||||
Pipe = _pipelineFactory.Create();
|
Pipe = _pipelineFactory.Create();
|
||||||
FrameContext.Input = Pipe.Reader;
|
|
||||||
|
FrameContext = new Frame<object>(null, new FrameContext
|
||||||
|
{
|
||||||
|
ServiceContext = new TestServiceContext(),
|
||||||
|
Input = Pipe.Reader
|
||||||
|
});
|
||||||
|
FrameContext.FrameControl = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IPipe Pipe { get; }
|
public IPipe Pipe { get; }
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ using Microsoft.AspNetCore.Server.Kestrel.Core;
|
||||||
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal;
|
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal;
|
||||||
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http;
|
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http;
|
||||||
using Microsoft.AspNetCore.Server.Kestrel.Internal.System.IO.Pipelines;
|
using Microsoft.AspNetCore.Server.Kestrel.Internal.System.IO.Pipelines;
|
||||||
|
using Microsoft.AspNetCore.Server.Kestrel.Performance.Mocks;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Server.Kestrel.Performance
|
namespace Microsoft.AspNetCore.Server.Kestrel.Performance
|
||||||
{
|
{
|
||||||
|
|
@ -28,7 +29,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Performance
|
||||||
var frameContext = new FrameContext
|
var frameContext = new FrameContext
|
||||||
{
|
{
|
||||||
ServiceContext = serviceContext,
|
ServiceContext = serviceContext,
|
||||||
ConnectionInformation = new MockConnectionInformation()
|
ConnectionInformation = new MockConnectionInformation(),
|
||||||
|
TimeoutControl = new MockTimeoutControl()
|
||||||
};
|
};
|
||||||
|
|
||||||
_frame = new Frame<object>(application: null, frameContext: frameContext);
|
_frame = new Frame<object>(application: null, frameContext: frameContext);
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ using Microsoft.AspNetCore.Server.Kestrel.Core;
|
||||||
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal;
|
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal;
|
||||||
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http;
|
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http;
|
||||||
using Microsoft.AspNetCore.Server.Kestrel.Internal.System.IO.Pipelines;
|
using Microsoft.AspNetCore.Server.Kestrel.Internal.System.IO.Pipelines;
|
||||||
|
using Microsoft.AspNetCore.Server.Kestrel.Performance.Mocks;
|
||||||
using Microsoft.AspNetCore.Testing;
|
using Microsoft.AspNetCore.Testing;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Server.Kestrel.Performance
|
namespace Microsoft.AspNetCore.Server.Kestrel.Performance
|
||||||
|
|
@ -98,18 +99,14 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Performance
|
||||||
Log = new MockTrace(),
|
Log = new MockTrace(),
|
||||||
HttpParserFactory = f => new HttpParser<FrameAdapter>()
|
HttpParserFactory = f => new HttpParser<FrameAdapter>()
|
||||||
};
|
};
|
||||||
var frameContext = new FrameContext
|
|
||||||
|
var frame = new TestFrame<object>(application: null, context: new FrameContext
|
||||||
{
|
{
|
||||||
ServiceContext = serviceContext,
|
ServiceContext = serviceContext,
|
||||||
ConnectionInformation = new MockConnectionInformation()
|
ConnectionInformation = new MockConnectionInformation(),
|
||||||
};
|
|
||||||
|
|
||||||
var frame = new TestFrame<object>(application: null, context: frameContext)
|
|
||||||
{
|
|
||||||
Input = input.Reader,
|
Input = input.Reader,
|
||||||
};
|
Output = output
|
||||||
|
});
|
||||||
frame.Output = new OutputProducer(output, "", null);
|
|
||||||
|
|
||||||
frame.Reset();
|
frame.Reset();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,11 +30,11 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Performance
|
||||||
var frameContext = new FrameContext
|
var frameContext = new FrameContext
|
||||||
{
|
{
|
||||||
ServiceContext = serviceContext,
|
ServiceContext = serviceContext,
|
||||||
ConnectionInformation = new MockConnectionInformation()
|
ConnectionInformation = new MockConnectionInformation(),
|
||||||
|
TimeoutControl = new MockTimeoutControl()
|
||||||
};
|
};
|
||||||
|
|
||||||
Frame = new Frame<object>(application: null, frameContext: frameContext);
|
Frame = new Frame<object>(application: null, frameContext: frameContext);
|
||||||
Frame.TimeoutControl = new MockTimeoutControl();
|
|
||||||
PipelineFactory = new PipeFactory();
|
PipelineFactory = new PipeFactory();
|
||||||
Pipe = PipelineFactory.Create();
|
Pipe = PipelineFactory.Create();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ using Microsoft.AspNetCore.Server.Kestrel.Core;
|
||||||
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal;
|
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal;
|
||||||
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http;
|
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http;
|
||||||
using Microsoft.AspNetCore.Server.Kestrel.Internal.System.IO.Pipelines;
|
using Microsoft.AspNetCore.Server.Kestrel.Internal.System.IO.Pipelines;
|
||||||
|
using Microsoft.AspNetCore.Server.Kestrel.Performance.Mocks;
|
||||||
using Microsoft.AspNetCore.Testing;
|
using Microsoft.AspNetCore.Testing;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Server.Kestrel.Performance
|
namespace Microsoft.AspNetCore.Server.Kestrel.Performance
|
||||||
|
|
@ -121,17 +122,14 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Performance
|
||||||
HttpParserFactory = f => new HttpParser<FrameAdapter>()
|
HttpParserFactory = f => new HttpParser<FrameAdapter>()
|
||||||
};
|
};
|
||||||
|
|
||||||
var frameContext = new FrameContext
|
var frame = new TestFrame<object>(application: null, context: new FrameContext
|
||||||
{
|
{
|
||||||
ServiceContext = serviceContext,
|
ServiceContext = serviceContext,
|
||||||
ConnectionInformation = new MockConnectionInformation()
|
ConnectionInformation = new MockConnectionInformation(),
|
||||||
};
|
TimeoutControl = new MockTimeoutControl(),
|
||||||
|
|
||||||
var frame = new TestFrame<object>(application: null, context: frameContext)
|
|
||||||
{
|
|
||||||
Input = input.Reader,
|
Input = input.Reader,
|
||||||
};
|
Output = output
|
||||||
frame.Output = new OutputProducer(output, "", null);
|
});
|
||||||
|
|
||||||
frame.Reset();
|
frame.Reset();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -693,12 +693,15 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv.Tests
|
||||||
};
|
};
|
||||||
var transportContext = new TestLibuvTransportContext { Log = new LibuvTrace(logger) };
|
var transportContext = new TestLibuvTransportContext { Log = new LibuvTrace(logger) };
|
||||||
|
|
||||||
var frame = new Frame<object>(null, new FrameContext { ServiceContext = serviceContext });
|
|
||||||
|
|
||||||
var socket = new MockSocket(_mockLibuv, _libuvThread.Loop.ThreadId, transportContext.Log);
|
var socket = new MockSocket(_mockLibuv, _libuvThread.Loop.ThreadId, transportContext.Log);
|
||||||
var outputProducer = new OutputProducer(pipe, "0", serviceContext.Log);
|
|
||||||
var consumer = new LibuvOutputConsumer(pipe.Reader, _libuvThread, socket, "0", transportContext.Log);
|
var consumer = new LibuvOutputConsumer(pipe.Reader, _libuvThread, socket, "0", transportContext.Log);
|
||||||
frame.Output = outputProducer;
|
|
||||||
|
var frame = new Frame<object>(null, new FrameContext
|
||||||
|
{
|
||||||
|
ServiceContext = serviceContext,
|
||||||
|
TimeoutControl = Mock.Of<ITimeoutControl>(),
|
||||||
|
Output = pipe
|
||||||
|
});
|
||||||
|
|
||||||
if (cts != null)
|
if (cts != null)
|
||||||
{
|
{
|
||||||
|
|
@ -707,7 +710,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv.Tests
|
||||||
|
|
||||||
var ignore = WriteOutputAsync(consumer, pipe.Reader, frame);
|
var ignore = WriteOutputAsync(consumer, pipe.Reader, frame);
|
||||||
|
|
||||||
return outputProducer;
|
return frame.Output;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task WriteOutputAsync(LibuvOutputConsumer consumer, IPipeReader outputReader, Frame frame)
|
private async Task WriteOutputAsync(LibuvOutputConsumer consumer, IPipeReader outputReader, Frame frame)
|
||||||
|
|
|
||||||
|
|
@ -4,13 +4,14 @@
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.Hosting.Server;
|
using Microsoft.AspNetCore.Hosting.Server;
|
||||||
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http;
|
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http;
|
||||||
|
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Testing
|
namespace Microsoft.AspNetCore.Testing
|
||||||
{
|
{
|
||||||
public class TestFrame<TContext> : Frame<TContext>
|
public class TestFrame<TContext> : Frame<TContext>
|
||||||
{
|
{
|
||||||
public TestFrame(IHttpApplication<TContext> application, FrameContext context)
|
public TestFrame(IHttpApplication<TContext> application, FrameContext context)
|
||||||
: base(application, context)
|
: base(application, context)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue