This is an automated email from the ASF dual-hosted git repository. schultz pushed a commit to branch 9.0.x in repository https://gitbox.apache.org/repos/asf/tomcat.git
The following commit(s) were added to refs/heads/9.0.x by this push: new 79746b1805 Make checkstyle happy 79746b1805 is described below commit 79746b18058c5c305c376c11ce2984a70af82431 Author: Christopher Schultz <ch...@christopherschultz.net> AuthorDate: Tue May 9 09:36:57 2023 -0400 Make checkstyle happy --- .../apache/catalina/filters/RateLimitFilter.java | 42 ++++++++++++---------- .../apache/catalina/util/TimeBucketCounter.java | 18 ++++------ .../catalina/filters/TestRateLimitFilter.java | 12 ++++--- .../catalina/util/TestTimeBucketCounter.java | 2 +- webapps/docs/changelog.xml | 3 +- webapps/docs/config/filter.xml | 20 +++++------ 6 files changed, 49 insertions(+), 48 deletions(-) diff --git a/java/org/apache/catalina/filters/RateLimitFilter.java b/java/org/apache/catalina/filters/RateLimitFilter.java index 00d4fad683..e545381d58 100644 --- a/java/org/apache/catalina/filters/RateLimitFilter.java +++ b/java/org/apache/catalina/filters/RateLimitFilter.java @@ -17,6 +17,8 @@ package org.apache.catalina.filters; +import java.io.IOException; + import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.GenericFilter; @@ -24,24 +26,23 @@ import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletResponse; + import org.apache.catalina.util.TimeBucketCounter; import org.apache.juli.logging.Log; import org.apache.juli.logging.LogFactory; import org.apache.tomcat.util.res.StringManager; -import java.io.IOException; - /** * <p>Servlet filter that can help mitigate Denial of Service - * (DoS) and Brute Force attacks by limiting the number of a requests that are + * (DoS) and Brute Force attacks by limiting the number of a requests that are * allowed from a single IP address within a time window (also referred * to as a time bucket), e.g. 300 Requests per 60 seconds.</p> - * + * * <p>The filter works by incrementing a counter in a time bucket for each IP * address, and if the counter exceeds the allowed limit then further requests - * from that IP are dropped with a "429 Too many requests" response + * from that IP are dropped with a "429 Too many requests" response * until the bucket time ends and a new bucket starts.</p> - * + * * <p>The filter is optimized for efficiency and low overhead, so it converts * some configured values to more efficient values. For example, a configuration * of a 60 seconds time bucket is converted to 65.536 seconds. That allows @@ -49,23 +50,23 @@ import java.io.IOException; * true to the user intent, the configured number of requests is then multiplied * by the same ratio, so a configuration of 100 Requests per 60 seconds, has the * real values of 109 Requests per 65 seconds.</p> - * + * * <p>It is common to set up different restrictions for different URIs. - * For example, a login page or authentication script is typically expected - * to get far less requests than the rest of the application, so you can add + * For example, a login page or authentication script is typically expected + * to get far less requests than the rest of the application, so you can add * a filter definition that would allow only 5 requests per 15 seconds and map * those URIs to it.</p> - * + * * <p>You can set <code>enforce</code> to <code>false</code> * to disable the termination of requests that exceed the allowed limit. Then - * your application code can inspect the Request Attribute + * your application code can inspect the Request Attribute * <code>org.apache.catalina.filters.RateLimitFilter.Count</code> and decide * how to handle the request based on other information that it has, e.g. allow * more requests to certain users based on roles, etc.</p> - * + * * <p><strong>WARNING:</strong> if Tomcat is behind a reverse proxy then you must * make sure that the Rate Limit Filter sees the client IP address, so if for - * example you are using the <a href="#Remote_IP_Filter">Remote IP Filter</a>, + * example you are using the <a href="#Remote_IP_Filter">Remote IP Filter</a>, * then the filter mapping for the Rate Limit Filter must come <em>after</em> * the mapping of the Remote IP Filter to ensure that each request has its IP * address resolved before the Rate Limit Filter is applied. Failure to do so @@ -168,24 +169,29 @@ public class RateLimitFilter extends GenericFilter { String param; param = config.getInitParameter(PARAM_BUCKET_DURATION); - if (param != null) + if (param != null) { bucketDuration = Integer.parseInt(param); + } param = config.getInitParameter(PARAM_BUCKET_REQUESTS); - if (param != null) + if (param != null) { bucketRequests = Integer.parseInt(param); + } param = config.getInitParameter(PARAM_ENFORCE); - if (param != null) + if (param != null) { enforce = Boolean.parseBoolean(param); + } param = config.getInitParameter(PARAM_STATUS_CODE); - if (param != null) + if (param != null) { statusCode = Integer.parseInt(param); + } param = config.getInitParameter(PARAM_STATUS_MESSAGE); - if (param != null) + if (param != null) { statusMessage = param; + } bucketCounter = new TimeBucketCounter(bucketDuration); diff --git a/java/org/apache/catalina/util/TimeBucketCounter.java b/java/org/apache/catalina/util/TimeBucketCounter.java index 70bb09f122..bd5e70fcb4 100644 --- a/java/org/apache/catalina/util/TimeBucketCounter.java +++ b/java/org/apache/catalina/util/TimeBucketCounter.java @@ -53,6 +53,7 @@ public class TimeBucketCounter { volatile boolean isRunning = false; /** + * Creates a new TimeBucketCounter with the specified lifetime. * * @param bucketDuration duration in seconds, e.g. for 1 minute pass 60 */ @@ -93,15 +94,13 @@ public class TimeBucketCounter { * calculates the current time bucket prefix by shifting bits for fast * division, e.g. shift 16 bits is the same as dividing by 65,536 which is * about 1:05m + * + * @return The current bucket prefix. */ public final int getCurrentBucketPrefix() { return (int) (System.currentTimeMillis() >> this.numBits); } - /** - * - * @return - */ public int getNumBits() { return numBits; } @@ -132,9 +131,6 @@ public class TimeBucketCounter { /** * returns the ratio to the next power of 2 so that we can adjust the value - * - * @param value - * @return */ static double ratioToPowerOf2(int value) { double nextPO2 = nextPowerOf2(value); @@ -144,14 +140,12 @@ public class TimeBucketCounter { /** * returns the next power of 2 given a value, e.g. 256 for 250, * or 1024, for 1000 - * - * @param value - * @return */ static int nextPowerOf2(int value) { int valueOfHighestBit = Integer.highestOneBit(value); - if (valueOfHighestBit == value) + if (valueOfHighestBit == value) { return value; + } return valueOfHighestBit << 1; } @@ -183,7 +177,7 @@ public class TimeBucketCounter { final long sleeptime; - public MaintenanceThread(long sleeptime) { + MaintenanceThread(long sleeptime) { super.setDaemon(true); this.sleeptime = sleeptime; } diff --git a/test/org/apache/catalina/filters/TestRateLimitFilter.java b/test/org/apache/catalina/filters/TestRateLimitFilter.java index 444d1d7e8d..f78b099e74 100644 --- a/test/org/apache/catalina/filters/TestRateLimitFilter.java +++ b/test/org/apache/catalina/filters/TestRateLimitFilter.java @@ -17,10 +17,16 @@ package org.apache.catalina.filters; +import java.io.IOException; +import java.time.Instant; +import java.util.Enumeration; +import java.util.Map; + import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletContext; import javax.servlet.ServletException; + import org.apache.catalina.Context; import org.apache.catalina.LifecycleException; import org.apache.catalina.startup.Tomcat; @@ -31,14 +37,10 @@ import org.apache.tomcat.unittest.TesterResponse; import org.apache.tomcat.unittest.TesterServletContext; import org.apache.tomcat.util.descriptor.web.FilterDef; import org.apache.tomcat.util.descriptor.web.FilterMap; + import org.junit.Assert; import org.junit.Test; -import java.io.IOException; -import java.time.Instant; -import java.util.Enumeration; -import java.util.Map; - public class TestRateLimitFilter extends TomcatBaseTest { @Test diff --git a/test/org/apache/catalina/util/TestTimeBucketCounter.java b/test/org/apache/catalina/util/TestTimeBucketCounter.java index bfaca1e6f4..b1a7fd8606 100644 --- a/test/org/apache/catalina/util/TestTimeBucketCounter.java +++ b/test/org/apache/catalina/util/TestTimeBucketCounter.java @@ -22,7 +22,7 @@ import org.junit.Test; public class TestTimeBucketCounter { - final static double DELTA = 0.001; + static final double DELTA = 0.001; @Test public void testNextPowerOf2() { diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml index 0beff46de4..c91e57aa90 100644 --- a/webapps/docs/changelog.xml +++ b/webapps/docs/changelog.xml @@ -108,7 +108,7 @@ <subsection name="Catalina"> <changelog> <add> - Add RateLimitFilter which can be used to mitigate DoS and Brute Force + Add RateLimitFilter which can be used to mitigate DoS and Brute Force attacks. (isapir) </add> </changelog> @@ -14007,4 +14007,3 @@ </body> </document> - diff --git a/webapps/docs/config/filter.xml b/webapps/docs/config/filter.xml index 0327dd7fde..1c25e15adb 100644 --- a/webapps/docs/config/filter.xml +++ b/webapps/docs/config/filter.xml @@ -968,13 +968,13 @@ FINE: Request "/docs/config/manager.html" with response status "200" <subsection name="Introduction"> <p>The <strong>Rate Limit Filter</strong> can help mitigate Denial of Service - (DoS) and Brute Force attacks by limiting the number of a requests that are + (DoS) and Brute Force attacks by limiting the number of a requests that are allowed from a single IP address within a time window (also referred to as a time bucket), e.g. 300 Requests per 60 seconds.</p> <p>The filter works by incrementing a counter in a time bucket for each IP address, and if the counter exceeds the allowed limit then further requests - from that IP are dropped with a "429 Too many requests" response + from that IP are dropped with a "429 Too many requests" response until the bucket time ends and a new bucket starts.</p> <p>The filter is optimized for efficiency and low overhead, so it converts @@ -986,21 +986,21 @@ FINE: Request "/docs/config/manager.html" with response status "200" real values of 109 Requests per 65 seconds.</p> <p>It is common to set up different restrictions for different URIs. - For example, a login page or authentication script is typically expected - to get far less requests than the rest of the application, so you can add + For example, a login page or authentication script is typically expected + to get far less requests than the rest of the application, so you can add a filter definition that would allow only 5 requests per 15 seconds and map those URIs to it.</p> <p>You can set <code>enforce</code> to <code>false</code> to disable the termination of requests that exceed the allowed limit. Then - your application code can inspect the Request Attribute + your application code can inspect the Request Attribute <code>org.apache.catalina.filters.RateLimitFilter.Count</code> and decide how to handle the request based on other information that it has, e.g. allow more requests to certain users based on roles, etc.</p> <p><strong>WARNING:</strong> if Tomcat is behind a reverse proxy then you must make sure that the Rate Limit Filter sees the client IP address, so if for - example you are using the <a href="#Remote_IP_Filter">Remote IP Filter</a>, + example you are using the <a href="#Remote_IP_Filter">Remote IP Filter</a>, then the filter mapping for the Rate Limit Filter must come <em>after</em> the mapping of the Remote IP Filter to ensure that each request has its IP address resolved before the Rate Limit Filter is applied. Failure to do so @@ -1029,16 +1029,16 @@ FINE: Request "/docs/config/manager.html" with response status "200" </attribute> <attribute name="bucketRequests" required="false"> - <p>The number of requests that are allowed in a time bucket. + <p>The number of requests that are allowed in a time bucket. Default is <code>300</code>.</p> </attribute> <attribute name="enforce" required="false"> <p>Set to false to allow requests through even when they exceed - the maximum allowed per time window. Your application code can - still inspect the Request Attribute + the maximum allowed per time window. Your application code can + still inspect the Request Attribute org.apache.catalina.filters.RateLimitFilter.Count to retrieve - the number of Requests made from that IP within the time window. + the number of Requests made from that IP within the time window. Default is <code>true</code>.</p> </attribute> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org