Rename request body min rate APIs (#1901).
This commit is contained in:
parent
3ba8c2d3f0
commit
f2061ed716
|
|
@ -333,4 +333,7 @@
|
|||
<data name="NonNegativeTimeSpanRequired" xml:space="preserve">
|
||||
<value>Value must be a non-negative TimeSpan.</value>
|
||||
</data>
|
||||
<data name="MinimumGracePeriodRequired" xml:space="preserve">
|
||||
<value>The request body rate enforcement grace period must be greater than {heartbeatInterval} second.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
|
|
|||
|
|
@ -6,13 +6,13 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Features
|
|||
/// <summary>
|
||||
/// Represents a minimum data rate for the request body of an HTTP request.
|
||||
/// </summary>
|
||||
public interface IHttpRequestBodyMinimumDataRateFeature
|
||||
public interface IHttpMinRequestBodyDataRateFeature
|
||||
{
|
||||
/// <summary>
|
||||
/// The minimum data rate in bytes/second at which the request body should be received.
|
||||
/// Setting this property to null indicates no minimum data rate should be enforced.
|
||||
/// This limit has no effect on upgraded connections which are always unlimited.
|
||||
/// </summary>
|
||||
MinimumDataRate MinimumDataRate { get; set; }
|
||||
MinDataRate MinDataRate { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -1,41 +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;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.Kestrel.Core.Features
|
||||
{
|
||||
public class MinimumDataRate
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a new instance of <see cref="MinimumDataRate"/>.
|
||||
/// </summary>
|
||||
/// <param name="rate">The minimum rate in bytes/second at which data should be processed.</param>
|
||||
/// <param name="gracePeriod">The amount of time to delay enforcement of <paramref name="rate"/>.</param>
|
||||
public MinimumDataRate(double rate, TimeSpan gracePeriod)
|
||||
{
|
||||
if (rate <= 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(rate), CoreStrings.PositiveNumberRequired);
|
||||
}
|
||||
|
||||
if (gracePeriod < TimeSpan.Zero)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(gracePeriod), CoreStrings.NonNegativeTimeSpanRequired);
|
||||
}
|
||||
|
||||
Rate = rate;
|
||||
GracePeriod = gracePeriod;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The minimum rate in bytes/second at which data should be processed.
|
||||
/// </summary>
|
||||
public double Rate { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The amount of time to delay enforcement of <see cref="MinimumDataRate" />.
|
||||
/// </summary>
|
||||
public TimeSpan GracePeriod { get; }
|
||||
}
|
||||
}
|
||||
|
|
@ -285,14 +285,14 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal
|
|||
{
|
||||
_readTimingElapsedTicks += timestamp - _lastTimestamp;
|
||||
|
||||
if (_frame.RequestBodyMinimumDataRate?.Rate > 0 && _readTimingElapsedTicks > _frame.RequestBodyMinimumDataRate.GracePeriod.Ticks)
|
||||
if (_frame.MinRequestBodyDataRate?.BytesPerSecond > 0 && _readTimingElapsedTicks > _frame.MinRequestBodyDataRate.GracePeriod.Ticks)
|
||||
{
|
||||
var elapsedSeconds = (double)_readTimingElapsedTicks / TimeSpan.TicksPerSecond;
|
||||
var rate = Interlocked.Read(ref _readTimingBytesRead) / elapsedSeconds;
|
||||
|
||||
if (rate < _frame.RequestBodyMinimumDataRate.Rate && !Debugger.IsAttached)
|
||||
if (rate < _frame.MinRequestBodyDataRate.BytesPerSecond && !Debugger.IsAttached)
|
||||
{
|
||||
Log.RequestBodyMininumDataRateNotSatisfied(_context.ConnectionId, _frame.TraceIdentifier, _frame.RequestBodyMinimumDataRate.Rate);
|
||||
Log.RequestBodyMininumDataRateNotSatisfied(_context.ConnectionId, _frame.TraceIdentifier, _frame.MinRequestBodyDataRate.BytesPerSecond);
|
||||
Timeout();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
|||
IHttpRequestLifetimeFeature,
|
||||
IHttpRequestIdentifierFeature,
|
||||
IHttpMaxRequestBodySizeFeature,
|
||||
IHttpRequestBodyMinimumDataRateFeature
|
||||
IHttpMinRequestBodyDataRateFeature
|
||||
{
|
||||
// NOTE: When feature interfaces are added to or removed from this Frame class implementation,
|
||||
// then the list of `implementedFeatures` in the generated code project MUST also be updated.
|
||||
|
|
@ -229,10 +229,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
|||
}
|
||||
}
|
||||
|
||||
MinimumDataRate IHttpRequestBodyMinimumDataRateFeature.MinimumDataRate
|
||||
MinDataRate IHttpMinRequestBodyDataRateFeature.MinDataRate
|
||||
{
|
||||
get => RequestBodyMinimumDataRate;
|
||||
set => RequestBodyMinimumDataRate = value;
|
||||
get => MinRequestBodyDataRate;
|
||||
set => MinRequestBodyDataRate = value;
|
||||
}
|
||||
|
||||
object IFeatureCollection.this[Type key]
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
|||
private static readonly Type IHttpWebSocketFeatureType = typeof(global::Microsoft.AspNetCore.Http.Features.IHttpWebSocketFeature);
|
||||
private static readonly Type ISessionFeatureType = typeof(global::Microsoft.AspNetCore.Http.Features.ISessionFeature);
|
||||
private static readonly Type IHttpMaxRequestBodySizeFeatureType = typeof(global::Microsoft.AspNetCore.Http.Features.IHttpMaxRequestBodySizeFeature);
|
||||
private static readonly Type IHttpRequestBodyMinimumDataRateFeatureType = typeof(global::Microsoft.AspNetCore.Server.Kestrel.Core.Features.IHttpRequestBodyMinimumDataRateFeature);
|
||||
private static readonly Type IHttpMinRequestBodyDataRateFeatureType = typeof(global::Microsoft.AspNetCore.Server.Kestrel.Core.Features.IHttpMinRequestBodyDataRateFeature);
|
||||
private static readonly Type IHttpSendFileFeatureType = typeof(global::Microsoft.AspNetCore.Http.Features.IHttpSendFileFeature);
|
||||
|
||||
private object _currentIHttpRequestFeature;
|
||||
|
|
@ -43,7 +43,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
|||
private object _currentIHttpWebSocketFeature;
|
||||
private object _currentISessionFeature;
|
||||
private object _currentIHttpMaxRequestBodySizeFeature;
|
||||
private object _currentIHttpRequestBodyMinimumDataRateFeature;
|
||||
private object _currentIHttpMinRequestBodyDataRateFeature;
|
||||
private object _currentIHttpSendFileFeature;
|
||||
|
||||
private void FastReset()
|
||||
|
|
@ -55,7 +55,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
|||
_currentIHttpRequestLifetimeFeature = this;
|
||||
_currentIHttpConnectionFeature = this;
|
||||
_currentIHttpMaxRequestBodySizeFeature = this;
|
||||
_currentIHttpRequestBodyMinimumDataRateFeature = this;
|
||||
_currentIHttpMinRequestBodyDataRateFeature = this;
|
||||
|
||||
_currentIServiceProvidersFeature = null;
|
||||
_currentIHttpAuthenticationFeature = null;
|
||||
|
|
@ -135,9 +135,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
|||
{
|
||||
return _currentIHttpMaxRequestBodySizeFeature;
|
||||
}
|
||||
if (key == IHttpRequestBodyMinimumDataRateFeatureType)
|
||||
if (key == IHttpMinRequestBodyDataRateFeatureType)
|
||||
{
|
||||
return _currentIHttpRequestBodyMinimumDataRateFeature;
|
||||
return _currentIHttpMinRequestBodyDataRateFeature;
|
||||
}
|
||||
if (key == IHttpSendFileFeatureType)
|
||||
{
|
||||
|
|
@ -230,9 +230,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
|||
_currentIHttpMaxRequestBodySizeFeature = feature;
|
||||
return;
|
||||
}
|
||||
if (key == IHttpRequestBodyMinimumDataRateFeatureType)
|
||||
if (key == IHttpMinRequestBodyDataRateFeatureType)
|
||||
{
|
||||
_currentIHttpRequestBodyMinimumDataRateFeature = feature;
|
||||
_currentIHttpMinRequestBodyDataRateFeature = feature;
|
||||
return;
|
||||
}
|
||||
if (key == IHttpSendFileFeatureType)
|
||||
|
|
@ -309,9 +309,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
|||
{
|
||||
yield return new KeyValuePair<Type, object>(IHttpMaxRequestBodySizeFeatureType, _currentIHttpMaxRequestBodySizeFeature as global::Microsoft.AspNetCore.Http.Features.IHttpMaxRequestBodySizeFeature);
|
||||
}
|
||||
if (_currentIHttpRequestBodyMinimumDataRateFeature != null)
|
||||
if (_currentIHttpMinRequestBodyDataRateFeature != null)
|
||||
{
|
||||
yield return new KeyValuePair<Type, object>(IHttpRequestBodyMinimumDataRateFeatureType, _currentIHttpRequestBodyMinimumDataRateFeature as global::Microsoft.AspNetCore.Server.Kestrel.Core.Features.IHttpRequestBodyMinimumDataRateFeature);
|
||||
yield return new KeyValuePair<Type, object>(IHttpMinRequestBodyDataRateFeatureType, _currentIHttpMinRequestBodyDataRateFeature as global::Microsoft.AspNetCore.Server.Kestrel.Core.Features.IHttpMinRequestBodyDataRateFeature);
|
||||
}
|
||||
if (_currentIHttpSendFileFeature != null)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ using System.Threading;
|
|||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Http.Features;
|
||||
using Microsoft.AspNetCore.Server.Kestrel.Core.Features;
|
||||
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure;
|
||||
using Microsoft.AspNetCore.Server.Kestrel.Internal.System;
|
||||
using Microsoft.AspNetCore.Server.Kestrel.Internal.System.IO.Pipelines;
|
||||
|
|
@ -300,7 +299,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
|||
|
||||
protected FrameResponseHeaders FrameResponseHeaders { get; } = new FrameResponseHeaders();
|
||||
|
||||
public MinimumDataRate RequestBodyMinimumDataRate { get; set; }
|
||||
public MinDataRate MinRequestBodyDataRate { get; set; }
|
||||
|
||||
public void InitializeStreams(MessageBody messageBody)
|
||||
{
|
||||
|
|
@ -379,7 +378,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
|||
_responseBytesWritten = 0;
|
||||
_requestCount++;
|
||||
|
||||
RequestBodyMinimumDataRate = ServerOptions.Limits.RequestBodyMinimumDataRate;
|
||||
MinRequestBodyDataRate = ServerOptions.Limits.MinRequestBodyDataRate;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
|||
|
|
@ -255,11 +255,11 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core
|
|||
/// Gets or sets the request body minimum data rate in bytes/second.
|
||||
/// Setting this property to null indicates no minimum data rate should be enforced.
|
||||
/// This limit has no effect on upgraded connections which are always unlimited.
|
||||
/// This can be overridden per-request via <see cref="IHttpRequestBodyMinimumDataRateFeature"/>.
|
||||
/// This can be overridden per-request via <see cref="IHttpMinRequestBodyDataRateFeature"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Defaults to 1 byte/second with a 5 second grace period.
|
||||
/// </remarks>
|
||||
public MinimumDataRate RequestBodyMinimumDataRate { get; set; } = new MinimumDataRate(rate: 1, gracePeriod: TimeSpan.FromSeconds(5));
|
||||
public MinDataRate MinRequestBodyDataRate { get; set; } = new MinDataRate(bytesPerSecond: 1, gracePeriod: TimeSpan.FromSeconds(5));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,44 @@
|
|||
// 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 Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.Kestrel.Core
|
||||
{
|
||||
public class MinDataRate
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a new instance of <see cref="MinDataRate"/>.
|
||||
/// </summary>
|
||||
/// <param name="bytesPerSecond">The minimum rate in bytes/second at which data should be processed.</param>
|
||||
/// <param name="gracePeriod">The amount of time to delay enforcement of <paramref name="bytesPerSecond"/>,
|
||||
/// starting at the time data is first read or written.</param>
|
||||
public MinDataRate(double bytesPerSecond, TimeSpan gracePeriod)
|
||||
{
|
||||
if (bytesPerSecond < 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(bytesPerSecond), CoreStrings.NonNegativeNumberRequired);
|
||||
}
|
||||
|
||||
if (gracePeriod <= Heartbeat.Interval)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(gracePeriod), CoreStrings.FormatMinimumGracePeriodRequired(Heartbeat.Interval.TotalSeconds));
|
||||
}
|
||||
|
||||
BytesPerSecond = bytesPerSecond;
|
||||
GracePeriod = gracePeriod;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The minimum rate in bytes/second at which data should be processed.
|
||||
/// </summary>
|
||||
public double BytesPerSecond { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The amount of time to delay enforcement of <see cref="MinDataRate" />,
|
||||
/// starting at the time data is first read or written.
|
||||
/// </summary>
|
||||
public TimeSpan GracePeriod { get; }
|
||||
}
|
||||
}
|
||||
|
|
@ -1018,6 +1018,20 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core
|
|||
internal static string FormatNonNegativeTimeSpanRequired()
|
||||
=> GetString("NonNegativeTimeSpanRequired");
|
||||
|
||||
/// <summary>
|
||||
/// The request body rate enforcement grace period must be greater than {heartbeatInterval} seconds.
|
||||
/// </summary>
|
||||
internal static string MinimumGracePeriodRequired
|
||||
{
|
||||
get => GetString("MinimumGracePeriodRequired");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The request body rate enforcement grace period must be greater than {heartbeatInterval} seconds.
|
||||
/// </summary>
|
||||
internal static string FormatMinimumGracePeriodRequired(object heartbeatInterval)
|
||||
=> string.Format(CultureInfo.CurrentCulture, GetString("MinimumGracePeriodRequired", "heartbeatInterval"), heartbeatInterval);
|
||||
|
||||
private static string GetString(string name, params string[] formatterNames)
|
||||
{
|
||||
var value = _resourceManager.GetString(name);
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Server.Kestrel.Core.Adapter.Internal;
|
||||
using Microsoft.AspNetCore.Server.Kestrel.Core.Features;
|
||||
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal;
|
||||
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure;
|
||||
using Microsoft.AspNetCore.Server.Kestrel.Internal.System.IO.Pipelines;
|
||||
|
|
@ -72,11 +71,11 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
|||
var mockDebugger = new Mock<IDebugger>();
|
||||
mockDebugger.SetupGet(g => g.IsAttached).Returns(true);
|
||||
_frameConnection.Debugger = mockDebugger.Object;
|
||||
var requestBodyMinimumDataRate = 100;
|
||||
var bytesPerSecond = 100;
|
||||
var mockLogger = new Mock<IKestrelTrace>();
|
||||
mockLogger.Setup(l => l.RequestBodyMininumDataRateNotSatisfied(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<double>())).Throws(new InvalidOperationException("Should not log"));
|
||||
|
||||
TickBodyWithMinimumDataRate(mockLogger.Object, requestBodyMinimumDataRate);
|
||||
TickBodyWithMinimumDataRate(mockLogger.Object, bytesPerSecond);
|
||||
|
||||
Assert.False(_frameConnection.TimedOut);
|
||||
}
|
||||
|
|
@ -84,22 +83,22 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
|||
[Fact]
|
||||
public void TimesOutWhenRequestBodyDoesNotSatisfyMinimumDataRate()
|
||||
{
|
||||
var requestBodyMinimumDataRate = 100;
|
||||
var bytesPerSecond = 100;
|
||||
var mockLogger = new Mock<IKestrelTrace>();
|
||||
TickBodyWithMinimumDataRate(mockLogger.Object, requestBodyMinimumDataRate);
|
||||
TickBodyWithMinimumDataRate(mockLogger.Object, bytesPerSecond);
|
||||
|
||||
// Timed out
|
||||
Assert.True(_frameConnection.TimedOut);
|
||||
mockLogger.Verify(logger =>
|
||||
logger.RequestBodyMininumDataRateNotSatisfied(It.IsAny<string>(), It.IsAny<string>(), requestBodyMinimumDataRate), Times.Once);
|
||||
logger.RequestBodyMininumDataRateNotSatisfied(It.IsAny<string>(), It.IsAny<string>(), bytesPerSecond), Times.Once);
|
||||
}
|
||||
|
||||
private void TickBodyWithMinimumDataRate(IKestrelTrace logger, int requestBodyMinimumDataRate)
|
||||
private void TickBodyWithMinimumDataRate(IKestrelTrace logger, int bytesPerSecond)
|
||||
{
|
||||
var requestBodyGracePeriod = TimeSpan.FromSeconds(5);
|
||||
var gracePeriod = TimeSpan.FromSeconds(5);
|
||||
|
||||
_frameConnectionContext.ServiceContext.ServerOptions.Limits.RequestBodyMinimumDataRate =
|
||||
new MinimumDataRate(rate: requestBodyMinimumDataRate, gracePeriod: requestBodyGracePeriod);
|
||||
_frameConnectionContext.ServiceContext.ServerOptions.Limits.MinRequestBodyDataRate =
|
||||
new MinDataRate(bytesPerSecond: bytesPerSecond, gracePeriod: gracePeriod);
|
||||
|
||||
_frameConnectionContext.ServiceContext.Log = logger;
|
||||
|
||||
|
|
@ -113,19 +112,19 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
|||
_frameConnection.StartTimingReads();
|
||||
|
||||
// Tick after grace period w/ low data rate
|
||||
now += requestBodyGracePeriod + TimeSpan.FromSeconds(1);
|
||||
now += gracePeriod + TimeSpan.FromSeconds(1);
|
||||
_frameConnection.BytesRead(1);
|
||||
_frameConnection.Tick(now);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MinimumDataRateNotEnforcedDuringGracePeriod()
|
||||
public void RequestBodyMinimumDataRateNotEnforcedDuringGracePeriod()
|
||||
{
|
||||
var requestBodyMinimumDataRate = 100;
|
||||
var requestBodyGracePeriod = TimeSpan.FromSeconds(2);
|
||||
var bytesPerSecond = 100;
|
||||
var gracePeriod = TimeSpan.FromSeconds(2);
|
||||
|
||||
_frameConnectionContext.ServiceContext.ServerOptions.Limits.RequestBodyMinimumDataRate =
|
||||
new MinimumDataRate(rate: requestBodyMinimumDataRate, gracePeriod: requestBodyGracePeriod);
|
||||
_frameConnectionContext.ServiceContext.ServerOptions.Limits.MinRequestBodyDataRate =
|
||||
new MinDataRate(bytesPerSecond: bytesPerSecond, gracePeriod: gracePeriod);
|
||||
|
||||
var mockLogger = new Mock<IKestrelTrace>();
|
||||
_frameConnectionContext.ServiceContext.Log = mockLogger.Object;
|
||||
|
|
@ -147,7 +146,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
|||
// Not timed out
|
||||
Assert.False(_frameConnection.TimedOut);
|
||||
mockLogger.Verify(logger =>
|
||||
logger.RequestBodyMininumDataRateNotSatisfied(It.IsAny<string>(), It.IsAny<string>(), requestBodyMinimumDataRate), Times.Never);
|
||||
logger.RequestBodyMininumDataRateNotSatisfied(It.IsAny<string>(), It.IsAny<string>(), bytesPerSecond), Times.Never);
|
||||
|
||||
// Tick after grace period w/ low data rate
|
||||
now += TimeSpan.FromSeconds(2);
|
||||
|
|
@ -157,17 +156,17 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
|||
// Timed out
|
||||
Assert.True(_frameConnection.TimedOut);
|
||||
mockLogger.Verify(logger =>
|
||||
logger.RequestBodyMininumDataRateNotSatisfied(It.IsAny<string>(), It.IsAny<string>(), requestBodyMinimumDataRate), Times.Once);
|
||||
logger.RequestBodyMininumDataRateNotSatisfied(It.IsAny<string>(), It.IsAny<string>(), bytesPerSecond), Times.Once);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DataRateIsAveragedOverTimeSpentReadingRequestBody()
|
||||
public void RequestBodyDataRateIsAveragedOverTimeSpentReadingRequestBody()
|
||||
{
|
||||
var requestBodyMinimumDataRate = 100;
|
||||
var requestBodyGracePeriod = TimeSpan.FromSeconds(1);
|
||||
var bytesPerSecond = 100;
|
||||
var gracePeriod = TimeSpan.FromSeconds(2);
|
||||
|
||||
_frameConnectionContext.ServiceContext.ServerOptions.Limits.RequestBodyMinimumDataRate =
|
||||
new MinimumDataRate(rate: requestBodyMinimumDataRate, gracePeriod: requestBodyGracePeriod);
|
||||
_frameConnectionContext.ServiceContext.ServerOptions.Limits.MinRequestBodyDataRate =
|
||||
new MinDataRate(bytesPerSecond: bytesPerSecond, gracePeriod: gracePeriod);
|
||||
|
||||
var mockLogger = new Mock<IKestrelTrace>();
|
||||
_frameConnectionContext.ServiceContext.Log = mockLogger.Object;
|
||||
|
|
@ -181,60 +180,69 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
|||
|
||||
_frameConnection.StartTimingReads();
|
||||
|
||||
// Tick after grace period to start enforcing minimum data rate
|
||||
now += requestBodyGracePeriod;
|
||||
_frameConnection.BytesRead(100);
|
||||
// Set base data rate to 200 bytes/second
|
||||
now += gracePeriod;
|
||||
_frameConnection.BytesRead(400);
|
||||
_frameConnection.Tick(now);
|
||||
|
||||
// Data rate: 200 bytes/second
|
||||
now += TimeSpan.FromSeconds(1);
|
||||
_frameConnection.BytesRead(300);
|
||||
_frameConnection.BytesRead(200);
|
||||
_frameConnection.Tick(now);
|
||||
|
||||
// Not timed out
|
||||
Assert.False(_frameConnection.TimedOut);
|
||||
mockLogger.Verify(logger =>
|
||||
logger.RequestBodyMininumDataRateNotSatisfied(It.IsAny<string>(), It.IsAny<string>(), requestBodyMinimumDataRate), Times.Never);
|
||||
logger.RequestBodyMininumDataRateNotSatisfied(It.IsAny<string>(), It.IsAny<string>(), bytesPerSecond), Times.Never);
|
||||
|
||||
// Data rate: 150 bytes/second
|
||||
now += TimeSpan.FromSeconds(1);
|
||||
_frameConnection.BytesRead(50);
|
||||
_frameConnection.BytesRead(0);
|
||||
_frameConnection.Tick(now);
|
||||
|
||||
// Not timed out
|
||||
Assert.False(_frameConnection.TimedOut);
|
||||
mockLogger.Verify(logger =>
|
||||
logger.RequestBodyMininumDataRateNotSatisfied(It.IsAny<string>(), It.IsAny<string>(), requestBodyMinimumDataRate), Times.Never);
|
||||
logger.RequestBodyMininumDataRateNotSatisfied(It.IsAny<string>(), It.IsAny<string>(), bytesPerSecond), Times.Never);
|
||||
|
||||
// Data rate: 115 bytes/second
|
||||
// Data rate: 120 bytes/second
|
||||
now += TimeSpan.FromSeconds(1);
|
||||
_frameConnection.BytesRead(10);
|
||||
_frameConnection.BytesRead(0);
|
||||
_frameConnection.Tick(now);
|
||||
|
||||
// Not timed out
|
||||
Assert.False(_frameConnection.TimedOut);
|
||||
mockLogger.Verify(logger =>
|
||||
logger.RequestBodyMininumDataRateNotSatisfied(It.IsAny<string>(), It.IsAny<string>(), requestBodyMinimumDataRate), Times.Never);
|
||||
logger.RequestBodyMininumDataRateNotSatisfied(It.IsAny<string>(), It.IsAny<string>(), bytesPerSecond), Times.Never);
|
||||
|
||||
// Data rate: 50 bytes/second
|
||||
now += TimeSpan.FromSeconds(6);
|
||||
_frameConnection.BytesRead(40);
|
||||
// Data rate: 100 bytes/second
|
||||
now += TimeSpan.FromSeconds(1);
|
||||
_frameConnection.BytesRead(0);
|
||||
_frameConnection.Tick(now);
|
||||
|
||||
// Not timed out
|
||||
Assert.False(_frameConnection.TimedOut);
|
||||
mockLogger.Verify(logger =>
|
||||
logger.RequestBodyMininumDataRateNotSatisfied(It.IsAny<string>(), It.IsAny<string>(), bytesPerSecond), Times.Never);
|
||||
|
||||
// Data rate: ~85 bytes/second
|
||||
now += TimeSpan.FromSeconds(1);
|
||||
_frameConnection.BytesRead(0);
|
||||
_frameConnection.Tick(now);
|
||||
|
||||
// Timed out
|
||||
Assert.True(_frameConnection.TimedOut);
|
||||
mockLogger.Verify(logger =>
|
||||
logger.RequestBodyMininumDataRateNotSatisfied(It.IsAny<string>(), It.IsAny<string>(), requestBodyMinimumDataRate), Times.Once);
|
||||
logger.RequestBodyMininumDataRateNotSatisfied(It.IsAny<string>(), It.IsAny<string>(), bytesPerSecond), Times.Once);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void PausedTimeDoesNotCountAgainstRequestBodyTimeout()
|
||||
public void RequestBodyDataRateNotComputedOnPausedTime()
|
||||
{
|
||||
var requestBodyTimeout = TimeSpan.FromSeconds(5);
|
||||
var systemClock = new MockSystemClock();
|
||||
|
||||
_frameConnectionContext.ServiceContext.ServerOptions.Limits.RequestBodyMinimumDataRate =
|
||||
new MinimumDataRate(rate: 100, gracePeriod: TimeSpan.Zero);
|
||||
_frameConnectionContext.ServiceContext.ServerOptions.Limits.MinRequestBodyDataRate =
|
||||
new MinDataRate(bytesPerSecond: 100, gracePeriod: TimeSpan.FromSeconds(2));
|
||||
_frameConnectionContext.ServiceContext.SystemClock = systemClock;
|
||||
|
||||
var mockLogger = new Mock<IKestrelTrace>();
|
||||
|
|
@ -248,21 +256,21 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
|||
|
||||
_frameConnection.StartTimingReads();
|
||||
|
||||
// Tick at 1s, expected counted time is 1s, expected data rate is 400 bytes/second
|
||||
systemClock.UtcNow += TimeSpan.FromSeconds(1);
|
||||
_frameConnection.BytesRead(400);
|
||||
// Tick at 3s, expected counted time is 3s, expected data rate is 200 bytes/second
|
||||
systemClock.UtcNow += TimeSpan.FromSeconds(3);
|
||||
_frameConnection.BytesRead(600);
|
||||
_frameConnection.Tick(systemClock.UtcNow);
|
||||
|
||||
// Pause at 1.5s
|
||||
// Pause at 3.5s
|
||||
systemClock.UtcNow += TimeSpan.FromSeconds(0.5);
|
||||
_frameConnection.PauseTimingReads();
|
||||
|
||||
// Tick at 2s, expected counted time is 2s, expected data rate is 400 bytes/second
|
||||
// Tick at 4s, expected counted time is 4s (first tick after pause goes through), expected data rate is 150 bytes/second
|
||||
systemClock.UtcNow += TimeSpan.FromSeconds(0.5);
|
||||
_frameConnection.Tick(systemClock.UtcNow);
|
||||
|
||||
// Tick at 6s, expected counted time is 2s, expected data rate is 400 bytes/second
|
||||
systemClock.UtcNow += TimeSpan.FromSeconds(4);
|
||||
// Tick at 6s, expected counted time is 4s, expected data rate is 150 bytes/second
|
||||
systemClock.UtcNow += TimeSpan.FromSeconds(2);
|
||||
_frameConnection.Tick(systemClock.UtcNow);
|
||||
|
||||
// Not timed out
|
||||
|
|
@ -275,7 +283,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
|||
systemClock.UtcNow += TimeSpan.FromSeconds(0.5);
|
||||
_frameConnection.ResumeTimingReads();
|
||||
|
||||
// Tick at 8s, expected counted time is 4s, expected data rate is 100 bytes/second
|
||||
// Tick at 9s, expected counted time is 6s, expected data rate is 100 bytes/second
|
||||
systemClock.UtcNow += TimeSpan.FromSeconds(1.5);
|
||||
_frameConnection.Tick(systemClock.UtcNow);
|
||||
|
||||
|
|
@ -285,7 +293,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
|||
logger => logger.RequestBodyMininumDataRateNotSatisfied(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<double>()),
|
||||
Times.Never);
|
||||
|
||||
// Tick at 9s, expected counted time is 9s, expected data rate drops below 100 bytes/second
|
||||
// Tick at 10s, expected counted time is 7s, expected data rate drops below 100 bytes/second
|
||||
systemClock.UtcNow += TimeSpan.FromSeconds(1);
|
||||
_frameConnection.Tick(systemClock.UtcNow);
|
||||
|
||||
|
|
@ -297,12 +305,12 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
|||
}
|
||||
|
||||
[Fact]
|
||||
public void NotPausedWhenResumeCalledBeforeNextTick()
|
||||
public void ReadTimingNotPausedWhenResumeCalledBeforeNextTick()
|
||||
{
|
||||
var systemClock = new MockSystemClock();
|
||||
|
||||
_frameConnectionContext.ServiceContext.ServerOptions.Limits.RequestBodyMinimumDataRate =
|
||||
new MinimumDataRate(rate: 100, gracePeriod: TimeSpan.Zero);
|
||||
_frameConnectionContext.ServiceContext.ServerOptions.Limits.MinRequestBodyDataRate =
|
||||
new MinDataRate(bytesPerSecond: 100, gracePeriod: TimeSpan.FromSeconds(2));
|
||||
_frameConnectionContext.ServiceContext.SystemClock = systemClock;
|
||||
|
||||
var mockLogger = new Mock<IKestrelTrace>();
|
||||
|
|
@ -316,9 +324,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
|||
|
||||
_frameConnection.StartTimingReads();
|
||||
|
||||
// Tick at 1s, expected counted time is 1s, expected data rate is 100 bytes/second
|
||||
systemClock.UtcNow += TimeSpan.FromSeconds(1);
|
||||
_frameConnection.BytesRead(100);
|
||||
// Tick at 2s, expected counted time is 2s, expected data rate is 100 bytes/second
|
||||
systemClock.UtcNow += TimeSpan.FromSeconds(2);
|
||||
_frameConnection.BytesRead(200);
|
||||
_frameConnection.Tick(systemClock.UtcNow);
|
||||
|
||||
// Not timed out
|
||||
|
|
@ -327,15 +335,15 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
|||
logger => logger.RequestBodyMininumDataRateNotSatisfied(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<double>()),
|
||||
Times.Never);
|
||||
|
||||
// Pause at 1.25s
|
||||
// Pause at 2.25s
|
||||
systemClock.UtcNow += TimeSpan.FromSeconds(0.25);
|
||||
_frameConnection.PauseTimingReads();
|
||||
|
||||
// Resume at 1.5s
|
||||
// Resume at 2.5s
|
||||
systemClock.UtcNow += TimeSpan.FromSeconds(0.25);
|
||||
_frameConnection.ResumeTimingReads();
|
||||
|
||||
// Tick at 2s, expected counted time is 2s, expected data rate is 100 bytes/second
|
||||
// Tick at 3s, expected counted time is 3s, expected data rate is 100 bytes/second
|
||||
systemClock.UtcNow += TimeSpan.FromSeconds(0.5);
|
||||
_frameConnection.BytesRead(100);
|
||||
_frameConnection.Tick(systemClock.UtcNow);
|
||||
|
|
@ -346,7 +354,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
|||
logger => logger.RequestBodyMininumDataRateNotSatisfied(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<double>()),
|
||||
Times.Never);
|
||||
|
||||
// Tick at 3s, expected counted time is 3s, expected data rate drops below 100 bytes/second
|
||||
// Tick at 4s, expected counted time is 4s, expected data rate drops below 100 bytes/second
|
||||
systemClock.UtcNow += TimeSpan.FromSeconds(1);
|
||||
_frameConnection.Tick(systemClock.UtcNow);
|
||||
|
||||
|
|
|
|||
|
|
@ -141,13 +141,13 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
|||
}
|
||||
|
||||
[Fact]
|
||||
public void ResetResetsRequestBodyMinimumDataRate()
|
||||
public void ResetResetsMinRequestBodyDataRate()
|
||||
{
|
||||
_frame.RequestBodyMinimumDataRate = new MinimumDataRate(rate: 1, gracePeriod: TimeSpan.Zero);
|
||||
_frame.MinRequestBodyDataRate = new MinDataRate(bytesPerSecond: 1, gracePeriod: TimeSpan.MaxValue);
|
||||
|
||||
_frame.Reset();
|
||||
|
||||
Assert.Equal(_serviceContext.ServerOptions.Limits.RequestBodyMinimumDataRate, _frame.RequestBodyMinimumDataRate);
|
||||
Assert.Equal(_serviceContext.ServerOptions.Limits.MinRequestBodyDataRate, _frame.MinRequestBodyDataRate);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -254,12 +254,12 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
|||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RequestBodyMinimumDataRateData))]
|
||||
public void ConfiguringRequestBodyMinimumDataRateFeatureSetsRequestBodyMinimumDateRate(MinimumDataRate minimumDataRate)
|
||||
[MemberData(nameof(MinRequestBodyDataRateData))]
|
||||
public void ConfiguringIHttpMinRequestBodyDataRateFeatureSetsMinRequestBodyDataRate(MinDataRate minDataRate)
|
||||
{
|
||||
((IFeatureCollection)_frame).Get<IHttpRequestBodyMinimumDataRateFeature>().MinimumDataRate = minimumDataRate;
|
||||
((IFeatureCollection)_frame).Get<IHttpMinRequestBodyDataRateFeature>().MinDataRate = minDataRate;
|
||||
|
||||
Assert.Same(minimumDataRate, _frame.RequestBodyMinimumDataRate);
|
||||
Assert.Same(minDataRate, _frame.MinRequestBodyDataRate);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -878,10 +878,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
|||
TimeSpan.Zero
|
||||
};
|
||||
|
||||
public static TheoryData<MinimumDataRate> RequestBodyMinimumDataRateData => new TheoryData<MinimumDataRate>
|
||||
public static TheoryData<MinDataRate> MinRequestBodyDataRateData => new TheoryData<MinDataRate>
|
||||
{
|
||||
null,
|
||||
new MinimumDataRate(rate: 1, gracePeriod: TimeSpan.Zero)
|
||||
new MinDataRate(bytesPerSecond: 1, gracePeriod: TimeSpan.MaxValue)
|
||||
};
|
||||
|
||||
private class RequestHeadersWrapper : IHeaderDictionary
|
||||
|
|
|
|||
|
|
@ -15,6 +15,12 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
|||
{
|
||||
public class HeartbeatTests
|
||||
{
|
||||
[Fact]
|
||||
public void HeartbeatIntervalIsOneSecond()
|
||||
{
|
||||
Assert.Equal(TimeSpan.FromSeconds(1), Heartbeat.Interval);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void BlockedHeartbeatDoesntCauseOverlapsAndIsLoggedAsError()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -293,11 +293,11 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
|||
}
|
||||
|
||||
[Fact]
|
||||
public void RequestBodyMinimumDataRateDefault()
|
||||
public void MinRequestBodyDataRateDefault()
|
||||
{
|
||||
Assert.NotNull(new KestrelServerLimits().RequestBodyMinimumDataRate);
|
||||
Assert.Equal(1, new KestrelServerLimits().RequestBodyMinimumDataRate.Rate);
|
||||
Assert.Equal(TimeSpan.FromSeconds(5), new KestrelServerLimits().RequestBodyMinimumDataRate.GracePeriod);
|
||||
Assert.NotNull(new KestrelServerLimits().MinRequestBodyDataRate);
|
||||
Assert.Equal(1, new KestrelServerLimits().MinRequestBodyDataRate.BytesPerSecond);
|
||||
Assert.Equal(TimeSpan.FromSeconds(5), new KestrelServerLimits().MinRequestBodyDataRate.GracePeriod);
|
||||
}
|
||||
|
||||
public static TheoryData<TimeSpan> TimeoutValidData => new TheoryData<TimeSpan>
|
||||
|
|
|
|||
|
|
@ -2,60 +2,62 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using Microsoft.AspNetCore.Server.Kestrel.Core.Features;
|
||||
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
||||
{
|
||||
public class MinimumDataRateTests
|
||||
public class MinDataRateTests
|
||||
{
|
||||
[Theory]
|
||||
[InlineData(0)]
|
||||
[InlineData(double.Epsilon)]
|
||||
[InlineData(double.MaxValue)]
|
||||
public void RateValid(double value)
|
||||
public void BytesPerSecondValid(double value)
|
||||
{
|
||||
Assert.Equal(value, new MinimumDataRate(rate: value, gracePeriod: TimeSpan.Zero).Rate);
|
||||
Assert.Equal(value, new MinDataRate(bytesPerSecond: value, gracePeriod: TimeSpan.MaxValue).BytesPerSecond);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(double.MinValue)]
|
||||
[InlineData(0)]
|
||||
public void RateInvalid(double value)
|
||||
[InlineData(-double.Epsilon)]
|
||||
public void BytesPerSecondInvalid(double value)
|
||||
{
|
||||
var exception = Assert.Throws<ArgumentOutOfRangeException>(() => new MinimumDataRate(rate: value, gracePeriod: TimeSpan.Zero));
|
||||
var exception = Assert.Throws<ArgumentOutOfRangeException>(() => new MinDataRate(bytesPerSecond: value, gracePeriod: TimeSpan.MaxValue));
|
||||
|
||||
Assert.Equal("rate", exception.ParamName);
|
||||
Assert.StartsWith(CoreStrings.PositiveNumberRequired, exception.Message);
|
||||
Assert.Equal("bytesPerSecond", exception.ParamName);
|
||||
Assert.StartsWith(CoreStrings.NonNegativeNumberRequired, exception.Message);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(GracePeriodValidData))]
|
||||
public void GracePeriodValid(TimeSpan value)
|
||||
{
|
||||
Assert.Equal(value, new MinimumDataRate(rate: 1, gracePeriod: value).GracePeriod);
|
||||
Assert.Equal(value, new MinDataRate(bytesPerSecond: 1, gracePeriod: value).GracePeriod);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(GracePeriodInvalidData))]
|
||||
public void GracePeriodInvalid(TimeSpan value)
|
||||
{
|
||||
var exception = Assert.Throws<ArgumentOutOfRangeException>(() => new MinimumDataRate(rate: 1, gracePeriod: value));
|
||||
var exception = Assert.Throws<ArgumentOutOfRangeException>(() => new MinDataRate(bytesPerSecond: 1, gracePeriod: value));
|
||||
|
||||
Assert.Equal("gracePeriod", exception.ParamName);
|
||||
Assert.StartsWith(CoreStrings.NonNegativeTimeSpanRequired, exception.Message);
|
||||
Assert.StartsWith(CoreStrings.FormatMinimumGracePeriodRequired(Heartbeat.Interval.TotalSeconds), exception.Message);
|
||||
}
|
||||
|
||||
public static TheoryData<TimeSpan> GracePeriodValidData => new TheoryData<TimeSpan>
|
||||
{
|
||||
TimeSpan.Zero,
|
||||
TimeSpan.FromTicks(1),
|
||||
Heartbeat.Interval + TimeSpan.FromTicks(1),
|
||||
TimeSpan.MaxValue
|
||||
};
|
||||
|
||||
public static TheoryData<TimeSpan> GracePeriodInvalidData => new TheoryData<TimeSpan>
|
||||
{
|
||||
TimeSpan.MinValue,
|
||||
TimeSpan.FromTicks(-1)
|
||||
TimeSpan.FromTicks(-1),
|
||||
TimeSpan.Zero,
|
||||
Heartbeat.Interval
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -197,7 +197,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
Limits =
|
||||
{
|
||||
KeepAliveTimeout = KeepAliveTimeout,
|
||||
RequestBodyMinimumDataRate = null
|
||||
MinRequestBodyDataRate = null
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -274,7 +274,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
options.Limits.MaxRequestHeadersTotalSize = (int)maxRequestBufferSize;
|
||||
}
|
||||
|
||||
options.Limits.RequestBodyMinimumDataRate = null;
|
||||
options.Limits.MinRequestBodyDataRate = null;
|
||||
})
|
||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
||||
.Configure(app => app.Run(async context =>
|
||||
|
|
|
|||
|
|
@ -17,9 +17,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
public class RequestBodyTimeoutTests
|
||||
{
|
||||
[Fact]
|
||||
public async Task RequestTimesOutWhenRequestBodyNotReceivedAtDesiredMinimumRate()
|
||||
public async Task RequestTimesOutWhenRequestBodyNotReceivedAtSpecifiedMinimumRate()
|
||||
{
|
||||
var minimumDataRateGracePeriod = TimeSpan.FromSeconds(5);
|
||||
var gracePeriod = TimeSpan.FromSeconds(5);
|
||||
var systemClock = new MockSystemClock();
|
||||
var serviceContext = new TestServiceContext
|
||||
{
|
||||
|
|
@ -31,8 +31,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
|
||||
using (var server = new TestServer(context =>
|
||||
{
|
||||
context.Features.Get<IHttpRequestBodyMinimumDataRateFeature>().MinimumDataRate =
|
||||
new MinimumDataRate(rate: 1, gracePeriod: minimumDataRateGracePeriod);
|
||||
context.Features.Get<IHttpMinRequestBodyDataRateFeature>().MinDataRate =
|
||||
new MinDataRate(bytesPerSecond: 1, gracePeriod: gracePeriod);
|
||||
|
||||
appRunningEvent.Set();
|
||||
return context.Request.Body.ReadAsync(new byte[1], 0, 1);
|
||||
|
|
@ -48,7 +48,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
"");
|
||||
|
||||
Assert.True(appRunningEvent.Wait(TimeSpan.FromSeconds(10)));
|
||||
systemClock.UtcNow += minimumDataRateGracePeriod + TimeSpan.FromSeconds(1);
|
||||
systemClock.UtcNow += gracePeriod + TimeSpan.FromSeconds(1);
|
||||
|
||||
await connection.Receive(
|
||||
"HTTP/1.1 408 Request Timeout",
|
||||
|
|
@ -64,7 +64,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
}
|
||||
|
||||
[Fact]
|
||||
public async Task RequestTimesWhenNotDrainedWithinDrainTimeoutPeriod()
|
||||
public async Task RequestTimesOutWhenNotDrainedWithinDrainTimeoutPeriod()
|
||||
{
|
||||
// This test requires a real clock since we can't control when the drain timeout is set
|
||||
var systemClock = new SystemClock();
|
||||
|
|
@ -78,7 +78,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
|
||||
using (var server = new TestServer(context =>
|
||||
{
|
||||
context.Features.Get<IHttpRequestBodyMinimumDataRateFeature>().MinimumDataRate = null;
|
||||
context.Features.Get<IHttpMinRequestBodyDataRateFeature>().MinDataRate = null;
|
||||
|
||||
appRunningEvent.Set();
|
||||
return Task.CompletedTask;
|
||||
|
|
@ -112,7 +112,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
[Fact]
|
||||
public async Task ConnectionClosedEvenIfAppSwallowsException()
|
||||
{
|
||||
var minimumDataRateGracePeriod = TimeSpan.FromSeconds(5);
|
||||
var gracePeriod = TimeSpan.FromSeconds(5);
|
||||
var systemClock = new MockSystemClock();
|
||||
var serviceContext = new TestServiceContext
|
||||
{
|
||||
|
|
@ -125,8 +125,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
|
||||
using (var server = new TestServer(async context =>
|
||||
{
|
||||
context.Features.Get<IHttpRequestBodyMinimumDataRateFeature>().MinimumDataRate =
|
||||
new MinimumDataRate(rate: 1, gracePeriod: minimumDataRateGracePeriod);
|
||||
context.Features.Get<IHttpMinRequestBodyDataRateFeature>().MinDataRate =
|
||||
new MinDataRate(bytesPerSecond: 1, gracePeriod: gracePeriod);
|
||||
|
||||
appRunningEvent.Set();
|
||||
|
||||
|
|
@ -154,7 +154,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
"");
|
||||
|
||||
Assert.True(appRunningEvent.Wait(TimeSpan.FromSeconds(10)));
|
||||
systemClock.UtcNow += minimumDataRateGracePeriod + TimeSpan.FromSeconds(1);
|
||||
systemClock.UtcNow += gracePeriod + TimeSpan.FromSeconds(1);
|
||||
Assert.True(exceptionSwallowedEvent.Wait(TimeSpan.FromSeconds(10)));
|
||||
|
||||
await connection.Receive(
|
||||
|
|
|
|||
|
|
@ -106,7 +106,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
Limits =
|
||||
{
|
||||
RequestHeadersTimeout = RequestHeadersTimeout,
|
||||
RequestBodyMinimumDataRate = null
|
||||
MinRequestBodyDataRate = null
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
.UseKestrel(options =>
|
||||
{
|
||||
options.Limits.MaxRequestBodySize = contentLength;
|
||||
options.Limits.RequestBodyMinimumDataRate = null;
|
||||
options.Limits.MinRequestBodyDataRate = null;
|
||||
})
|
||||
.UseUrls("http://127.0.0.1:0/")
|
||||
.Configure(app =>
|
||||
|
|
@ -1429,7 +1429,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
|
||||
using (var server = new TestServer(async context =>
|
||||
{
|
||||
context.Features.Get<IHttpRequestBodyMinimumDataRateFeature>().MinimumDataRate = new MinimumDataRate(rate: double.MaxValue, gracePeriod: TimeSpan.Zero);
|
||||
context.Features.Get<IHttpMinRequestBodyDataRateFeature>().MinDataRate =
|
||||
new MinDataRate(bytesPerSecond: double.MaxValue, gracePeriod: Heartbeat.Interval + TimeSpan.FromTicks(1));
|
||||
|
||||
using (var stream = await context.Features.Get<IHttpUpgradeFeature>().UpgradeAsync())
|
||||
{
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ namespace CodeGenerator
|
|||
typeof(IHttpWebSocketFeature),
|
||||
typeof(ISessionFeature),
|
||||
typeof(IHttpMaxRequestBodySizeFeature),
|
||||
typeof(IHttpRequestBodyMinimumDataRateFeature),
|
||||
typeof(IHttpMinRequestBodyDataRateFeature),
|
||||
};
|
||||
|
||||
var rareFeatures = new[]
|
||||
|
|
@ -68,7 +68,7 @@ namespace CodeGenerator
|
|||
typeof(IHttpRequestLifetimeFeature),
|
||||
typeof(IHttpConnectionFeature),
|
||||
typeof(IHttpMaxRequestBodySizeFeature),
|
||||
typeof(IHttpRequestBodyMinimumDataRateFeature),
|
||||
typeof(IHttpMinRequestBodyDataRateFeature),
|
||||
};
|
||||
|
||||
return $@"// Copyright (c) .NET Foundation. All rights reserved.
|
||||
|
|
|
|||
Loading…
Reference in New Issue