diff options
author | Brennan <brecon@microsoft.com> | 2022-09-26 20:22:27 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-09-26 20:22:27 +0300 |
commit | a889912cf71f13fec142a33e0cdbf8b1120ed8b3 (patch) | |
tree | cba426262a826b9eb969e25bb30e30aaff4c196e /src/libraries | |
parent | b914bb6d918fc9766e43401127da3b2bb1ed4d8c (diff) |
Disallow TimeSpan.Zero in rate limiters (#75496)
Diffstat (limited to 'src/libraries')
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] |