From 849398d840c1e8cab57348e91f70bcf0dd37ead2 Mon Sep 17 00:00:00 2001
From: Simone Bordet
Date: Wed, 27 Feb 2013 18:29:26 +0100
Subject: [PATCH] Merged branch 'jetty-8'.
---
jetty-servlets/pom.xml | 10 +-
.../org/eclipse/jetty/servlets/DoSFilter.java | 168 ++++--------------
.../jetty/servlets/DoSFilterJMXTest.java | 8 +-
3 files changed, 35 insertions(+), 151 deletions(-)
diff --git a/jetty-servlets/pom.xml b/jetty-servlets/pom.xml
index cf1e2af48e7..e6b394108ec 100644
--- a/jetty-servlets/pom.xml
+++ b/jetty-servlets/pom.xml
@@ -85,20 +85,14 @@
provided
-<<<<<<< HEAD
- org.eclipse.jetty.toolchain
- jetty-test-helper
-=======
org.eclipse.jetty
jetty-jmx
${project.version}
test
- org.eclipse.jetty
- test-jetty-servlet
- ${project.version}
->>>>>>> jetty-8
+ org.eclipse.jetty.toolchain
+ jetty-test-helper
test
diff --git a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/DoSFilter.java b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/DoSFilter.java
index 555ac258864..4bb4113cb57 100644
--- a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/DoSFilter.java
+++ b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/DoSFilter.java
@@ -19,13 +19,9 @@
package org.eclipse.jetty.servlets;
import java.io.IOException;
-<<<<<<< HEAD
-import java.util.HashSet;
-=======
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
->>>>>>> jetty-8
import java.util.Queue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
@@ -55,6 +51,8 @@ import org.eclipse.jetty.continuation.ContinuationSupport;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.util.annotation.ManagedAttribute;
import org.eclipse.jetty.util.annotation.ManagedObject;
+import org.eclipse.jetty.util.annotation.ManagedOperation;
+import org.eclipse.jetty.util.annotation.Name;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.thread.Timeout;
@@ -118,26 +116,16 @@ import org.eclipse.jetty.util.thread.Timeout;
* if true and session tracking is not used, then rate is tracked by IP+port (effectively connection). Defaults to false.
*
* ipWhitelist
-<<<<<<< HEAD
- * a comma-separated list of IP addresses that will not be rate limited
- *
- * managedAttr
- * if set to true, then this servlet is set as a {@link ServletContext} attribute with the
-=======
* a comma-separated list of IP addresses that will not be rate limited
*
* managedAttr
* if set to true, then this servlet is set as a {@link ServletContext} attribute with the
->>>>>>> jetty-8
* filter name as the attribute name. This allows context external mechanism (eg JMX via {@link ContextHandler#MANAGED_ATTRIBUTES}) to
* manage the configuration of the filter.
*
*
*/
-<<<<<<< HEAD
@ManagedObject("limits exposure to abuse from request flooding, whether malicious, or as a result of a misconfigured client")
-=======
->>>>>>> jetty-8
public class DoSFilter implements Filter
{
private static final Logger LOG = Log.getLogger(DoSFilter.class);
@@ -190,8 +178,8 @@ public class DoSFilter implements Filter
private volatile int _maxRequestsPerSec;
private Queue[] _queue;
private ContinuationListener[] _listeners;
- private final ConcurrentHashMap _rateTrackers = new ConcurrentHashMap();
- private final List _whitelist = new CopyOnWriteArrayList();
+ private final ConcurrentHashMap _rateTrackers = new ConcurrentHashMap<>();
+ private final List _whitelist = new CopyOnWriteArrayList<>();
private final Timeout _requestTimeoutQ = new Timeout();
private final Timeout _trackerTimeoutQ = new Timeout();
private Thread _timerThread;
@@ -205,7 +193,7 @@ public class DoSFilter implements Filter
_listeners = new ContinuationListener[getMaxPriority() + 1];
for (int p = 0; p < _queue.length; p++)
{
- _queue[p] = new ConcurrentLinkedQueue();
+ _queue[p] = new ConcurrentLinkedQueue<>();
final int priority = p;
_listeners[p] = new ContinuationListener()
@@ -370,26 +358,15 @@ public class DoSFilter implements Filter
case -1:
{
// Reject this request
-<<<<<<< HEAD
- if (_insertHeaders)
- ((HttpServletResponse)response).addHeader("DoSFilter","unavailable");
-
- ((HttpServletResponse)response).sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
-=======
if (insertHeaders)
response.addHeader("DoSFilter", "unavailable");
response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
->>>>>>> jetty-8
return;
}
case 0:
{
// fall through to throttle code
-<<<<<<< HEAD
- request.setAttribute(__TRACKER,tracker);
-=======
request.setAttribute(__TRACKER, tracker);
->>>>>>> jetty-8
break;
}
default:
@@ -398,26 +375,9 @@ public class DoSFilter implements Filter
if (insertHeaders)
response.addHeader("DoSFilter", "delayed");
Continuation continuation = ContinuationSupport.getContinuation(request);
-<<<<<<< HEAD
- request.setAttribute(__TRACKER,tracker);
- if (_delayMs > 0)
- continuation.setTimeout(_delayMs);
- continuation.addContinuationListener(new ContinuationListener()
- {
-
- public void onComplete(Continuation continuation)
- {
- }
-
- public void onTimeout(Continuation continuation)
- {
- }
- });
-=======
request.setAttribute(__TRACKER, tracker);
if (delayMs > 0)
continuation.setTimeout(delayMs);
->>>>>>> jetty-8
continuation.suspend();
return;
}
@@ -713,23 +673,6 @@ public class DoSFilter implements Filter
}
/**
-<<<<<<< HEAD
- * Initialize the IP address whitelist
- */
- protected void initWhitelist()
- {
- _whitelist.clear();
- StringTokenizer tokenizer = new StringTokenizer(_whitelistStr, ",");
- while (tokenizer.hasMoreTokens())
- _whitelist.add(tokenizer.nextToken().trim());
-
- LOG.info("Whitelisted IP addresses: {}", _whitelist.toString());
- }
-
- /* ------------------------------------------------------------ */
- /**
-=======
->>>>>>> jetty-8
* Get maximum number of requests from a connection per
* second. Requests in excess of this are first delayed,
* then throttled.
@@ -742,10 +685,6 @@ public class DoSFilter implements Filter
return _maxRequestsPerSec;
}
-<<<<<<< HEAD
- /* ------------------------------------------------------------ */
-=======
->>>>>>> jetty-8
/**
* Get maximum number of requests from a connection per
* second. Requests in excess of this are first delayed,
@@ -758,10 +697,6 @@ public class DoSFilter implements Filter
_maxRequestsPerSec = value;
}
-<<<<<<< HEAD
- /* ------------------------------------------------------------ */
-=======
->>>>>>> jetty-8
/**
* Get delay (in milliseconds) that is applied to all requests
* over the rate limit, before they are considered at all.
@@ -783,10 +718,6 @@ public class DoSFilter implements Filter
_delayMs = value;
}
-<<<<<<< HEAD
- /* ------------------------------------------------------------ */
-=======
->>>>>>> jetty-8
/**
* Get maximum amount of time (in milliseconds) the filter will
* blocking wait for the throttle semaphore.
@@ -799,10 +730,6 @@ public class DoSFilter implements Filter
return _maxWaitMs;
}
-<<<<<<< HEAD
- /* ------------------------------------------------------------ */
-=======
->>>>>>> jetty-8
/**
* Set maximum amount of time (in milliseconds) the filter will
* blocking wait for the throttle semaphore.
@@ -860,10 +787,6 @@ public class DoSFilter implements Filter
_throttleMs = value;
}
-<<<<<<< HEAD
- /* ------------------------------------------------------------ */
-=======
->>>>>>> jetty-8
/**
* Get maximum amount of time (in milliseconds) to allow
* the request to process.
@@ -876,10 +799,6 @@ public class DoSFilter implements Filter
return _maxRequestMs;
}
-<<<<<<< HEAD
- /* ------------------------------------------------------------ */
-=======
->>>>>>> jetty-8
/**
* Set maximum amount of time (in milliseconds) to allow
* the request to process.
@@ -904,10 +823,6 @@ public class DoSFilter implements Filter
return _maxIdleTrackerMs;
}
-<<<<<<< HEAD
- /* ------------------------------------------------------------ */
-=======
->>>>>>> jetty-8
/**
* Set maximum amount of time (in milliseconds) to keep track
* of request rates for a connection, before deciding that
@@ -920,10 +835,6 @@ public class DoSFilter implements Filter
_maxIdleTrackerMs = value;
}
-<<<<<<< HEAD
- /* ------------------------------------------------------------ */
-=======
->>>>>>> jetty-8
/**
* Check flag to insert the DoSFilter headers into the response.
*
@@ -935,10 +846,6 @@ public class DoSFilter implements Filter
return _insertHeaders;
}
-<<<<<<< HEAD
- /* ------------------------------------------------------------ */
-=======
->>>>>>> jetty-8
/**
* Set flag to insert the DoSFilter headers into the response.
*
@@ -949,10 +856,6 @@ public class DoSFilter implements Filter
_insertHeaders = value;
}
-<<<<<<< HEAD
- /* ------------------------------------------------------------ */
-=======
->>>>>>> jetty-8
/**
* Get flag to have usage rate tracked by session if a session exists.
*
@@ -964,10 +867,6 @@ public class DoSFilter implements Filter
return _trackSessions;
}
-<<<<<<< HEAD
- /* ------------------------------------------------------------ */
-=======
->>>>>>> jetty-8
/**
* Set flag to have usage rate tracked by session if a session exists.
*
@@ -978,10 +877,6 @@ public class DoSFilter implements Filter
_trackSessions = value;
}
-<<<<<<< HEAD
- /* ------------------------------------------------------------ */
-=======
->>>>>>> jetty-8
/**
* Get flag to have usage rate tracked by IP+port (effectively connection)
* if session tracking is not used.
@@ -994,11 +889,6 @@ public class DoSFilter implements Filter
return _remotePort;
}
-<<<<<<< HEAD
-
- /* ------------------------------------------------------------ */
-=======
->>>>>>> jetty-8
/**
* Set flag to have usage rate tracked by IP+port (effectively connection)
* if session tracking is not used.
@@ -1013,6 +903,7 @@ public class DoSFilter implements Filter
/**
* @return whether this filter is enabled
*/
+ @ManagedAttribute("whether this filter is enabled")
public boolean isEnabled()
{
return _enabled;
@@ -1052,20 +943,33 @@ public class DoSFilter implements Filter
*/
public void setWhitelist(String value)
{
- List result = new ArrayList();
+ List result = new ArrayList<>();
for (String address : value.split(","))
addWhitelistAddress(result, address);
- _whitelist.clear();
+ clearWhitelist();
_whitelist.addAll(result);
LOG.debug("Whitelisted IP addresses: {}", result);
}
+ /**
+ * Clears the list of whitelisted IP addresses
+ */
+ @ManagedOperation("clears the list of IP addresses that will not be rate limited")
public void clearWhitelist()
{
_whitelist.clear();
}
- public boolean addWhitelistAddress(String address)
+ /**
+ * Adds the given IP address, either in the form of a dotted decimal notation A.B.C.D
+ * or in the CIDR notation A.B.C.D/M, to the list of whitelisted IP addresses.
+ *
+ * @param address the address to add
+ * @return whether the address was added to the list
+ * @see #removeWhitelistAddress(String)
+ */
+ @ManagedOperation("adds an IP address that will not be rate limited")
+ public boolean addWhitelistAddress(@Name("address") String address)
{
return addWhitelistAddress(_whitelist, address);
}
@@ -1083,6 +987,14 @@ public class DoSFilter implements Filter
return false;
}
+ /**
+ * Removes the given address from the list of whitelisted IP addresses.
+ *
+ * @param address the address to remove
+ * @return whether the address was removed from the list
+ * @see #addWhitelistAddress(List, String)
+ */
+ @ManagedOperation("removes an IP address that will not be rate limited")
public boolean removeWhitelistAddress(String address)
{
return _whitelist.remove(address);
@@ -1099,12 +1011,7 @@ public class DoSFilter implements Filter
transient protected final long[] _timestamps;
transient protected int _next;
-<<<<<<< HEAD
-
- public RateTracker(String id, int type,int maxRequestsPerSecond)
-=======
public RateTracker(String id, int type, int maxRequestsPerSecond)
->>>>>>> jetty-8
{
_id = id;
_type = type;
@@ -1147,15 +1054,9 @@ public class DoSFilter implements Filter
public void valueUnbound(HttpSessionBindingEvent event)
{
//take the tracker out of the list of trackers
-<<<<<<< HEAD
- if (_rateTrackers != null)
- _rateTrackers.remove(_id);
- if (LOG.isDebugEnabled()) LOG.debug("Tracker removed: "+_id);
-=======
_rateTrackers.remove(_id);
if (LOG.isDebugEnabled())
LOG.debug("Tracker removed: {}", getId());
->>>>>>> jetty-8
}
public void sessionWillPassivate(HttpSessionEvent se)
@@ -1172,10 +1073,6 @@ public class DoSFilter implements Filter
LOG.warn("Unexpected session activation");
}
-<<<<<<< HEAD
-
-=======
->>>>>>> jetty-8
public void expired()
{
long now = _trackerTimeoutQ.getNow();
@@ -1194,11 +1091,6 @@ public class DoSFilter implements Filter
{
return "RateTracker/" + _id + "/" + _type;
}
-<<<<<<< HEAD
-
-
-=======
->>>>>>> jetty-8
}
class FixedRateTracker extends RateTracker
diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/DoSFilterJMXTest.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/DoSFilterJMXTest.java
index cd2ba3a857c..14a61574272 100644
--- a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/DoSFilterJMXTest.java
+++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/DoSFilterJMXTest.java
@@ -24,12 +24,12 @@ import java.util.Set;
import javax.management.Attribute;
import javax.management.MBeanServer;
import javax.management.ObjectName;
+import javax.servlet.DispatcherType;
import org.eclipse.jetty.jmx.MBeanContainer;
import org.eclipse.jetty.server.Connector;
-import org.eclipse.jetty.server.DispatcherType;
import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.server.nio.SelectChannelConnector;
+import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.servlet.FilterHolder;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.junit.Assert;
@@ -41,8 +41,7 @@ public class DoSFilterJMXTest
public void testDoSFilterJMX() throws Exception
{
Server server = new Server();
- Connector connector = new SelectChannelConnector();
- connector.setPort(0);
+ Connector connector = new ServerConnector(server);
server.addConnector(connector);
ServletContextHandler context = new ServletContextHandler(server, "/", ServletContextHandler.SESSIONS);
@@ -57,7 +56,6 @@ public class DoSFilterJMXTest
MBeanServer mbeanServer = ManagementFactory.getPlatformMBeanServer();
MBeanContainer mbeanContainer = new MBeanContainer(mbeanServer);
server.addBean(mbeanContainer);
- server.getContainer().addEventListener(mbeanContainer);
server.start();