Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/dotnet/runtime.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrennan <brecon@microsoft.com>2022-09-26 20:22:27 +0300
committerGitHub <noreply@github.com>2022-09-26 20:22:27 +0300
commita889912cf71f13fec142a33e0cdbf8b1120ed8b3 (patch)
treecba426262a826b9eb969e25bb30e30aaff4c196e /src/libraries
parentb914bb6d918fc9766e43401127da3b2bb1ed4d8c (diff)
Disallow TimeSpan.Zero in rate limiters (#75496)
Diffstat (limited to 'src/libraries')
-rw-r--r--src/libraries/System.Threading.RateLimiting/src/Resources/Strings.resx9
-rw-r--r--src/libraries/System.Threading.RateLimiting/src/System/Threading/RateLimiting/ConcurrencyLimiter.cs4
-rw-r--r--src/libraries/System.Threading.RateLimiting/src/System/Threading/RateLimiting/FixedWindowRateLimiter.cs8
-rw-r--r--src/libraries/System.Threading.RateLimiting/src/System/Threading/RateLimiting/FixedWindowRateLimiterOptions.cs3
-rw-r--r--src/libraries/System.Threading.RateLimiting/src/System/Threading/RateLimiting/SlidingWindowRateLimiter.cs14
-rw-r--r--src/libraries/System.Threading.RateLimiting/src/System/Threading/RateLimiting/SlidingWindowRateLimiterOptions.cs3
-rw-r--r--src/libraries/System.Threading.RateLimiting/src/System/Threading/RateLimiting/TokenBucketRateLimiter.cs14
-rw-r--r--src/libraries/System.Threading.RateLimiting/src/System/Threading/RateLimiting/TokenBucketRateLimiterOptions.cs3
-rw-r--r--src/libraries/System.Threading.RateLimiting/tests/ConcurrencyLimiterTests.cs4
-rw-r--r--src/libraries/System.Threading.RateLimiting/tests/FixedWindowRateLimiterTests.cs17
-rw-r--r--src/libraries/System.Threading.RateLimiting/tests/SlidingWindowRateLimiterTests.cs20
-rw-r--r--src/libraries/System.Threading.RateLimiting/tests/TokenBucketRateLimiterTests.cs20
12 files changed, 81 insertions, 38 deletions
diff --git a/src/libraries/System.Threading.RateLimiting/src/Resources/Strings.resx b/src/libraries/System.Threading.RateLimiting/src/Resources/Strings.resx
index 0bbb8516816..cb67a1ee66d 100644
--- a/src/libraries/System.Threading.RateLimiting/src/Resources/Strings.resx
+++ b/src/libraries/System.Threading.RateLimiting/src/Resources/Strings.resx
@@ -126,4 +126,13 @@
<data name="ReplenishmentLimitTooHigh" xml:space="preserve">
<value>Over 49 days is not supported.</value>
</data>
+ <data name="ShouldBeGreaterThan0" xml:space="preserve">
+ <value>{0} must be set to a value greater than 0.</value>
+ </data>
+ <data name="ShouldBeGreaterThanOrEqual0" xml:space="preserve">
+ <value>{0} must be set to a value greater than or equal to 0.</value>
+ </data>
+ <data name="ShouldBeGreaterThanTimeSpan0" xml:space="preserve">
+ <value>{0} must be set to a value greater than TimeSpan.Zero.</value>
+ </data>
</root> \ No newline at end of file
diff --git a/src/libraries/System.Threading.RateLimiting/src/System/Threading/RateLimiting/ConcurrencyLimiter.cs b/src/libraries/System.Threading.RateLimiting/src/System/Threading/RateLimiting/ConcurrencyLimiter.cs
index 508340a2e13..90c4620d18d 100644
--- a/src/libraries/System.Threading.RateLimiting/src/System/Threading/RateLimiting/ConcurrencyLimiter.cs
+++ b/src/libraries/System.Threading.RateLimiting/src/System/Threading/RateLimiting/ConcurrencyLimiter.cs
@@ -47,11 +47,11 @@ namespace System.Threading.RateLimiting
}
if (options.PermitLimit <= 0)
{
- throw new ArgumentException($"{nameof(options.PermitLimit)} must be set to a value greater than 0.", nameof(options));
+ throw new ArgumentException(SR.Format(SR.ShouldBeGreaterThan0, nameof(options.PermitLimit)), nameof(options));
}
if (options.QueueLimit < 0)
{
- throw new ArgumentException($"{nameof(options.QueueLimit)} must be set to a value greater than or equal to 0.", nameof(options));
+ throw new ArgumentException(SR.Format(SR.ShouldBeGreaterThanOrEqual0, nameof(options.QueueLimit)), nameof(options));
}
_options = new ConcurrencyLimiterOptions
diff --git a/src/libraries/System.Threading.RateLimiting/src/System/Threading/RateLimiting/FixedWindowRateLimiter.cs b/src/libraries/System.Threading.RateLimiting/src/System/Threading/RateLimiting/FixedWindowRateLimiter.cs
index 774a6876c24..71dd29faa14 100644
--- a/src/libraries/System.Threading.RateLimiting/src/System/Threading/RateLimiting/FixedWindowRateLimiter.cs
+++ b/src/libraries/System.Threading.RateLimiting/src/System/Threading/RateLimiting/FixedWindowRateLimiter.cs
@@ -53,15 +53,15 @@ namespace System.Threading.RateLimiting
}
if (options.PermitLimit <= 0)
{
- throw new ArgumentException($"{nameof(options.PermitLimit)} must be set to a value greater than 0.", nameof(options));
+ throw new ArgumentException(SR.Format(SR.ShouldBeGreaterThan0, nameof(options.PermitLimit)), nameof(options));
}
if (options.QueueLimit < 0)
{
- throw new ArgumentException($"{nameof(options.QueueLimit)} must be set to a value greater than or equal to 0.", nameof(options));
+ throw new ArgumentException(SR.Format(SR.ShouldBeGreaterThanOrEqual0, nameof(options.QueueLimit)), nameof(options));
}
- if (options.Window < TimeSpan.Zero)
+ if (options.Window <= TimeSpan.Zero)
{
- throw new ArgumentException($"{nameof(options.Window)} must be set to a value greater than or equal to TimeSpan.Zero.", nameof(options));
+ throw new ArgumentException(SR.Format(SR.ShouldBeGreaterThanTimeSpan0, nameof(options.Window)), nameof(options));
}
_options = new FixedWindowRateLimiterOptions
diff --git a/src/libraries/System.Threading.RateLimiting/src/System/Threading/RateLimiting/FixedWindowRateLimiterOptions.cs b/src/libraries/System.Threading.RateLimiting/src/System/Threading/RateLimiting/FixedWindowRateLimiterOptions.cs
index a6d2b164755..8f7dbaa344b 100644
--- a/src/libraries/System.Threading.RateLimiting/src/System/Threading/RateLimiting/FixedWindowRateLimiterOptions.cs
+++ b/src/libraries/System.Threading.RateLimiting/src/System/Threading/RateLimiting/FixedWindowRateLimiterOptions.cs
@@ -10,9 +10,8 @@ namespace System.Threading.RateLimiting
{
/// <summary>
/// Specifies the time window that takes in the requests.
- /// Must be set to a value >= <see cref="TimeSpan.Zero" /> by the time these options are passed to the constructor of <see cref="FixedWindowRateLimiter"/>.
+ /// Must be set to a value greater than <see cref="TimeSpan.Zero" /> by the time these options are passed to the constructor of <see cref="FixedWindowRateLimiter"/>.
/// </summary>
- /// <remarks><see cref="TimeSpan.Zero"/> means the limiter will never replenish.</remarks>
public TimeSpan Window { get; set; } = TimeSpan.Zero;
/// <summary>
diff --git a/src/libraries/System.Threading.RateLimiting/src/System/Threading/RateLimiting/SlidingWindowRateLimiter.cs b/src/libraries/System.Threading.RateLimiting/src/System/Threading/RateLimiting/SlidingWindowRateLimiter.cs
index a1fe3e2839e..205b2d5b5bc 100644
--- a/src/libraries/System.Threading.RateLimiting/src/System/Threading/RateLimiting/SlidingWindowRateLimiter.cs
+++ b/src/libraries/System.Threading.RateLimiting/src/System/Threading/RateLimiting/SlidingWindowRateLimiter.cs
@@ -55,17 +55,21 @@ namespace System.Threading.RateLimiting
{
throw new ArgumentNullException(nameof(options));
}
- if (options.PermitLimit <= 0 || options.SegmentsPerWindow <= 0)
+ if (options.PermitLimit <= 0)
{
- throw new ArgumentException($"Both {nameof(options.PermitLimit)} and {nameof(options.SegmentsPerWindow)} must be set to values greater than 0.", nameof(options));
+ throw new ArgumentException(SR.Format(SR.ShouldBeGreaterThan0, nameof(options.PermitLimit)), nameof(options));
+ }
+ if (options.SegmentsPerWindow <= 0)
+ {
+ throw new ArgumentException(SR.Format(SR.ShouldBeGreaterThan0, nameof(options.SegmentsPerWindow)), nameof(options));
}
if (options.QueueLimit < 0)
{
- throw new ArgumentException($"{nameof(options.QueueLimit)} must be set to a value greater than or equal to 0.", nameof(options));
+ throw new ArgumentException(SR.Format(SR.ShouldBeGreaterThanOrEqual0, nameof(options.QueueLimit)), nameof(options));
}
- if (options.Window < TimeSpan.Zero)
+ if (options.Window <= TimeSpan.Zero)
{
- throw new ArgumentException($"{nameof(options.Window)} must be set to a value greater than or equal to TimeSpan.Zero.", nameof(options));
+ throw new ArgumentException(SR.Format(SR.ShouldBeGreaterThanTimeSpan0, nameof(options.Window)), nameof(options));
}
_options = new SlidingWindowRateLimiterOptions
diff --git a/src/libraries/System.Threading.RateLimiting/src/System/Threading/RateLimiting/SlidingWindowRateLimiterOptions.cs b/src/libraries/System.Threading.RateLimiting/src/System/Threading/RateLimiting/SlidingWindowRateLimiterOptions.cs
index f7f399e175b..93f7ba933b4 100644
--- a/src/libraries/System.Threading.RateLimiting/src/System/Threading/RateLimiting/SlidingWindowRateLimiterOptions.cs
+++ b/src/libraries/System.Threading.RateLimiting/src/System/Threading/RateLimiting/SlidingWindowRateLimiterOptions.cs
@@ -10,9 +10,8 @@ namespace System.Threading.RateLimiting
{
/// <summary>
/// Specifies the minimum period between replenishments.
- /// Must be set to a value >= <see cref="TimeSpan.Zero" /> by the time these options are passed to the constructor of <see cref="SlidingWindowRateLimiter"/>.
+ /// Must be set to a value greater than <see cref="TimeSpan.Zero" /> by the time these options are passed to the constructor of <see cref="SlidingWindowRateLimiter"/>.
/// </summary>
- /// <remarks><see cref="TimeSpan.Zero"/> means the limiter will never replenish.</remarks>
public TimeSpan Window { get; set; } = TimeSpan.Zero;
/// <summary>
diff --git a/src/libraries/System.Threading.RateLimiting/src/System/Threading/RateLimiting/TokenBucketRateLimiter.cs b/src/libraries/System.Threading.RateLimiting/src/System/Threading/RateLimiting/TokenBucketRateLimiter.cs
index 9238a62a0c0..8423b13a603 100644
--- a/src/libraries/System.Threading.RateLimiting/src/System/Threading/RateLimiting/TokenBucketRateLimiter.cs
+++ b/src/libraries/System.Threading.RateLimiting/src/System/Threading/RateLimiting/TokenBucketRateLimiter.cs
@@ -53,17 +53,21 @@ namespace System.Threading.RateLimiting
{
throw new ArgumentNullException(nameof(options));
}
- if (options.TokenLimit <= 0 || options.TokensPerPeriod <= 0)
+ if (options.TokenLimit <= 0)
{
- throw new ArgumentException($"Both {nameof(options.TokenLimit)} and {nameof(options.TokensPerPeriod)} must be set to values greater than 0.", nameof(options));
+ throw new ArgumentException(SR.Format(SR.ShouldBeGreaterThan0, nameof(options.TokenLimit)), nameof(options));
+ }
+ if (options.TokensPerPeriod <= 0)
+ {
+ throw new ArgumentException(SR.Format(SR.ShouldBeGreaterThan0, nameof(options.TokensPerPeriod)), nameof(options));
}
if (options.QueueLimit < 0)
{
- throw new ArgumentException($"{nameof(options.QueueLimit)} must be set to a value greater than or equal to 0.", nameof(options));
+ throw new ArgumentException(SR.Format(SR.ShouldBeGreaterThanOrEqual0, nameof(options.QueueLimit)), nameof(options));
}
- if (options.ReplenishmentPeriod < TimeSpan.Zero)
+ if (options.ReplenishmentPeriod <= TimeSpan.Zero)
{
- throw new ArgumentException($"{nameof(options.ReplenishmentPeriod)} must be set to a value greater than or equal to TimeSpan.Zero.", nameof(options));
+ throw new ArgumentException(SR.Format(SR.ShouldBeGreaterThanTimeSpan0, nameof(options.ReplenishmentPeriod)), nameof(options));
}
_options = new TokenBucketRateLimiterOptions
diff --git a/src/libraries/System.Threading.RateLimiting/src/System/Threading/RateLimiting/TokenBucketRateLimiterOptions.cs b/src/libraries/System.Threading.RateLimiting/src/System/Threading/RateLimiting/TokenBucketRateLimiterOptions.cs
index b0371119ce3..2c065d9432e 100644
--- a/src/libraries/System.Threading.RateLimiting/src/System/Threading/RateLimiting/TokenBucketRateLimiterOptions.cs
+++ b/src/libraries/System.Threading.RateLimiting/src/System/Threading/RateLimiting/TokenBucketRateLimiterOptions.cs
@@ -10,9 +10,8 @@ namespace System.Threading.RateLimiting
{
/// <summary>
/// Specifies the minimum period between replenishments.
- /// Must be set to a value >= <see cref="TimeSpan.Zero" /> by the time these options are passed to the constructor of <see cref="TokenBucketRateLimiter"/>.
+ /// Must be set to a value greater than <see cref="TimeSpan.Zero" /> by the time these options are passed to the constructor of <see cref="TokenBucketRateLimiter"/>.
/// </summary>
- /// <remarks><see cref="TimeSpan.Zero"/> means the limiter will never replenish.</remarks>
public TimeSpan ReplenishmentPeriod { get; set; } = TimeSpan.Zero;
/// <summary>
diff --git a/src/libraries/System.Threading.RateLimiting/tests/ConcurrencyLimiterTests.cs b/src/libraries/System.Threading.RateLimiting/tests/ConcurrencyLimiterTests.cs
index 54e2bbecc19..0669a4bd6bc 100644
--- a/src/libraries/System.Threading.RateLimiting/tests/ConcurrencyLimiterTests.cs
+++ b/src/libraries/System.Threading.RateLimiting/tests/ConcurrencyLimiterTests.cs
@@ -11,13 +11,13 @@ namespace System.Threading.RateLimiting.Test
[Fact]
public override void InvalidOptionsThrows()
{
- Assert.Throws<ArgumentException>(() => new ConcurrencyLimiter(new ConcurrencyLimiterOptions
+ AssertExtensions.Throws<ArgumentException>("options", () => new ConcurrencyLimiter(new ConcurrencyLimiterOptions
{
PermitLimit = -1,
QueueProcessingOrder = QueueProcessingOrder.NewestFirst,
QueueLimit = 1
}));
- Assert.Throws<ArgumentException>(() => new ConcurrencyLimiter(new ConcurrencyLimiterOptions
+ AssertExtensions.Throws<ArgumentException>("options", () => new ConcurrencyLimiter(new ConcurrencyLimiterOptions
{
PermitLimit = 1,
QueueProcessingOrder = QueueProcessingOrder.NewestFirst,
diff --git a/src/libraries/System.Threading.RateLimiting/tests/FixedWindowRateLimiterTests.cs b/src/libraries/System.Threading.RateLimiting/tests/FixedWindowRateLimiterTests.cs
index f5c75a0308a..3e67bd130d7 100644
--- a/src/libraries/System.Threading.RateLimiting/tests/FixedWindowRateLimiterTests.cs
+++ b/src/libraries/System.Threading.RateLimiting/tests/FixedWindowRateLimiterTests.cs
@@ -35,7 +35,7 @@ namespace System.Threading.RateLimiting.Test
[Fact]
public override void InvalidOptionsThrows()
{
- Assert.Throws<ArgumentException>(
+ AssertExtensions.Throws<ArgumentException>("options",
() => new FixedWindowRateLimiter(new FixedWindowRateLimiterOptions
{
PermitLimit = -1,
@@ -44,7 +44,7 @@ namespace System.Threading.RateLimiting.Test
Window = TimeSpan.FromMinutes(2),
AutoReplenishment = false
}));
- Assert.Throws<ArgumentException>(
+ AssertExtensions.Throws<ArgumentException>("options",
() => new FixedWindowRateLimiter(new FixedWindowRateLimiterOptions
{
PermitLimit = 1,
@@ -53,7 +53,7 @@ namespace System.Threading.RateLimiting.Test
Window = TimeSpan.FromMinutes(2),
AutoReplenishment = false
}));
- Assert.Throws<ArgumentException>(
+ AssertExtensions.Throws<ArgumentException>("options",
() => new FixedWindowRateLimiter(new FixedWindowRateLimiterOptions
{
PermitLimit = 1,
@@ -62,7 +62,7 @@ namespace System.Threading.RateLimiting.Test
Window = TimeSpan.MinValue,
AutoReplenishment = false
}));
- Assert.Throws<ArgumentException>(
+ AssertExtensions.Throws<ArgumentException>("options",
() => new FixedWindowRateLimiter(new FixedWindowRateLimiterOptions
{
PermitLimit = 1,
@@ -71,6 +71,15 @@ namespace System.Threading.RateLimiting.Test
Window = TimeSpan.FromMinutes(-2),
AutoReplenishment = false,
}));
+ AssertExtensions.Throws<ArgumentException>("options",
+ () => new FixedWindowRateLimiter(new FixedWindowRateLimiterOptions
+ {
+ PermitLimit = 1,
+ QueueProcessingOrder = QueueProcessingOrder.NewestFirst,
+ QueueLimit = 1,
+ Window = TimeSpan.Zero,
+ AutoReplenishment = false,
+ }));
}
[Fact]
diff --git a/src/libraries/System.Threading.RateLimiting/tests/SlidingWindowRateLimiterTests.cs b/src/libraries/System.Threading.RateLimiting/tests/SlidingWindowRateLimiterTests.cs
index bd0d0d298d5..c45b9d75140 100644
--- a/src/libraries/System.Threading.RateLimiting/tests/SlidingWindowRateLimiterTests.cs
+++ b/src/libraries/System.Threading.RateLimiting/tests/SlidingWindowRateLimiterTests.cs
@@ -37,7 +37,7 @@ namespace System.Threading.RateLimiting.Test
[Fact]
public override void InvalidOptionsThrows()
{
- Assert.Throws<ArgumentException>(
+ AssertExtensions.Throws<ArgumentException>("options",
() => new SlidingWindowRateLimiter(new SlidingWindowRateLimiterOptions
{
PermitLimit = -1,
@@ -47,7 +47,7 @@ namespace System.Threading.RateLimiting.Test
SegmentsPerWindow = 1,
AutoReplenishment = false
}));
- Assert.Throws<ArgumentException>(
+ AssertExtensions.Throws<ArgumentException>("options",
() => new SlidingWindowRateLimiter(new SlidingWindowRateLimiterOptions
{
PermitLimit = 1,
@@ -57,7 +57,7 @@ namespace System.Threading.RateLimiting.Test
SegmentsPerWindow = 1,
AutoReplenishment = false
}));
- Assert.Throws<ArgumentException>(
+ AssertExtensions.Throws<ArgumentException>("options",
() => new SlidingWindowRateLimiter(new SlidingWindowRateLimiterOptions
{
PermitLimit = 1,
@@ -67,7 +67,7 @@ namespace System.Threading.RateLimiting.Test
SegmentsPerWindow = -1,
AutoReplenishment = false
}));
- Assert.Throws<ArgumentException>(
+ AssertExtensions.Throws<ArgumentException>("options",
() => new SlidingWindowRateLimiter(new SlidingWindowRateLimiterOptions
{
PermitLimit = 1,
@@ -77,7 +77,7 @@ namespace System.Threading.RateLimiting.Test
SegmentsPerWindow = 1,
AutoReplenishment = false
}));
- Assert.Throws<ArgumentException>(
+ AssertExtensions.Throws<ArgumentException>("options",
() => new SlidingWindowRateLimiter(new SlidingWindowRateLimiterOptions
{
PermitLimit = 1,
@@ -87,6 +87,16 @@ namespace System.Threading.RateLimiting.Test
SegmentsPerWindow = 1,
AutoReplenishment = false
}));
+ AssertExtensions.Throws<ArgumentException>("options",
+ () => new SlidingWindowRateLimiter(new SlidingWindowRateLimiterOptions
+ {
+ PermitLimit = 1,
+ QueueProcessingOrder = QueueProcessingOrder.NewestFirst,
+ QueueLimit = 1,
+ Window = TimeSpan.Zero,
+ SegmentsPerWindow = 1,
+ AutoReplenishment = false
+ }));
}
[Fact]
diff --git a/src/libraries/System.Threading.RateLimiting/tests/TokenBucketRateLimiterTests.cs b/src/libraries/System.Threading.RateLimiting/tests/TokenBucketRateLimiterTests.cs
index 69876938fdf..e7fefcbf7a0 100644
--- a/src/libraries/System.Threading.RateLimiting/tests/TokenBucketRateLimiterTests.cs
+++ b/src/libraries/System.Threading.RateLimiting/tests/TokenBucketRateLimiterTests.cs
@@ -37,7 +37,7 @@ namespace System.Threading.RateLimiting.Test
[Fact]
public override void InvalidOptionsThrows()
{
- Assert.Throws<ArgumentException>(
+ AssertExtensions.Throws<ArgumentException>("options",
() => new TokenBucketRateLimiter(new TokenBucketRateLimiterOptions
{
TokenLimit = -1,
@@ -47,7 +47,7 @@ namespace System.Threading.RateLimiting.Test
TokensPerPeriod = 1,
AutoReplenishment = false
}));
- Assert.Throws<ArgumentException>(
+ AssertExtensions.Throws<ArgumentException>("options",
() => new TokenBucketRateLimiter(new TokenBucketRateLimiterOptions
{
TokenLimit = 1,
@@ -57,7 +57,7 @@ namespace System.Threading.RateLimiting.Test
TokensPerPeriod = 1,
AutoReplenishment = false
}));
- Assert.Throws<ArgumentException>(
+ AssertExtensions.Throws<ArgumentException>("options",
() => new TokenBucketRateLimiter(new TokenBucketRateLimiterOptions
{
TokenLimit = 1,
@@ -67,7 +67,7 @@ namespace System.Threading.RateLimiting.Test
TokensPerPeriod = -1,
AutoReplenishment = false
}));
- Assert.Throws<ArgumentException>(
+ AssertExtensions.Throws<ArgumentException>("options",
() => new TokenBucketRateLimiter(new TokenBucketRateLimiterOptions
{
TokenLimit = 1,
@@ -77,7 +77,7 @@ namespace System.Threading.RateLimiting.Test
TokensPerPeriod = 1,
AutoReplenishment = false
}));
- Assert.Throws<ArgumentException>(
+ AssertExtensions.Throws<ArgumentException>("options",
() => new TokenBucketRateLimiter(new TokenBucketRateLimiterOptions
{
TokenLimit = 1,
@@ -87,6 +87,16 @@ namespace System.Threading.RateLimiting.Test
TokensPerPeriod = 1,
AutoReplenishment = false
}));
+ AssertExtensions.Throws<ArgumentException>("options",
+ () => new TokenBucketRateLimiter(new TokenBucketRateLimiterOptions
+ {
+ TokenLimit = 1,
+ QueueProcessingOrder = QueueProcessingOrder.NewestFirst,
+ QueueLimit = 1,
+ ReplenishmentPeriod = TimeSpan.Zero,
+ TokensPerPeriod = 1,
+ AutoReplenishment = false
+ }));
}
[Fact]