From 6ff56da2fbb89244cf265ce05c164d2c8ba75791 Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Mon, 3 May 2010 16:26:55 +0000 Subject: [PATCH] Fixes #308864 (Update test suite to JUnit4 - Module jetty-servlets). git-svn-id: svn+ssh://dev.eclipse.org/svnroot/rt/org.eclipse.jetty/jetty/trunk@1651 7e9141cc-0065-0410-87d8-b60c137991c4 --- VERSION.txt | 4 +- jetty-servlets/pom.xml | 1 + .../org/eclipse/jetty/servlets/DoSFilter.java | 180 ++++----- .../jetty/servlets/AbstractDoSFilterTest.java | 341 ++++++++++++++++++ .../servlets/CloseableDoSFilterTest.java | 69 +--- .../eclipse/jetty/servlets/DoSFilterTest.java | 319 +--------------- .../eclipse/jetty/servlets/PutFilterTest.java | 68 ++-- .../eclipse/jetty/servlets/QoSFilterTest.java | 82 ++--- 8 files changed, 538 insertions(+), 526 deletions(-) create mode 100644 jetty-servlets/src/test/java/org/eclipse/jetty/servlets/AbstractDoSFilterTest.java diff --git a/VERSION.txt b/VERSION.txt index 9e2a0cfff65..38313974937 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1,4 +1,3 @@ - jetty-7.1.0.RC1-SNAPSHOT + 291448 SessionManager has isCheckingRemoteSessionIdEncoding + 297104 HTTP CONNECT does not work correct with SSL destinations @@ -16,7 +15,8 @@ jetty-7.1.0.RC1-SNAPSHOT + 308865 Update test suite to JUnit4 - Module jetty-start + 309153 Hide extracted WEB-INF/lib when running a non-extracted war + 309686 Fixed response buffers usage - + 311362 Optional org.eclipse.jetty.util.log.stderr.SOURCE + + 311362 Optional org.eclipse.jetty.util.log.stderr.SOURCE + + 308864 Update test suite to JUnit4 - Module jetty-servlets jetty-7.1.0.RC0 27 April 2010 + 294563 Websocket client connection diff --git a/jetty-servlets/pom.xml b/jetty-servlets/pom.xml index dd6e2e336d1..b8b8dfc2665 100644 --- a/jetty-servlets/pom.xml +++ b/jetty-servlets/pom.xml @@ -45,6 +45,7 @@ junit junit + ${junit4-version} 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 3d48b4a8163..f2355f4014f 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 @@ -4,11 +4,11 @@ // All rights reserved. This program and the accompanying materials // are made available under the terms of the Eclipse Public License v1.0 // and Apache License v2.0 which accompanies this distribution. -// The Eclipse Public License is available at +// The Eclipse Public License is available at // http://www.eclipse.org/legal/epl-v10.html // The Apache License v2.0 is available at // http://www.opensource.org/licenses/apache2.0.php -// You may elect to redistribute this code under either of these licenses. +// You may elect to redistribute this code under either of these licenses. // ======================================================================== package org.eclipse.jetty.servlets; @@ -21,7 +21,6 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.Semaphore; import java.util.concurrent.TimeUnit; - import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; @@ -43,7 +42,7 @@ import org.eclipse.jetty.util.thread.Timeout; /** * Denial of Service filter - * + * *

* This filter is based on the {@link QoSFilter}. it is useful for limiting * exposure to abuse from request flooding, whether malicious, or as a result of @@ -62,33 +61,33 @@ import org.eclipse.jetty.util.thread.Timeout; * implemented, in order to uniquely identify authenticated users. *

* The following init parameters control the behavior of the filter: - * + * * maxRequestsPerSec the maximum number of requests from a connection per - * second. Requests in excess of this are first delayed, + * second. Requests in excess of this are first delayed, * then throttled. - * - * delayMs is the delay given to all requests over the rate limit, - * before they are considered at all. -1 means just reject request, + * + * delayMs is the delay given to all requests over the rate limit, + * before they are considered at all. -1 means just reject request, * 0 means no delay, otherwise it is the delay. - * + * * maxWaitMs how long to blocking wait for the throttle semaphore. - * + * * throttledRequests is the number of requests over the rate limit able to be * considered at once. - * + * * throttleMs how long to async wait for semaphore. - * + * * maxRequestMs how long to allow this request to run. - * - * maxIdleTrackerMs how long to keep track of request rates for a connection, + * + * maxIdleTrackerMs how long to keep track of request rates for a connection, * before deciding that the user has gone away, and discarding it - * + * * insertHeaders if true , insert the DoSFilter headers into the response. Defaults to true. - * + * * trackSessions if true, usage rate is tracked by session if a session exists. Defaults to true. - * + * * remotePort if true and session tracking is not used, then rate is tracked by IP+port (effectively connection). Defaults to false. - * + * * ipWhitelist a comma-separated list of IP addresses that will not be rate limited */ @@ -138,8 +137,8 @@ public class DoSFilter implements Filter protected int _maxRequestsPerSec; protected final ConcurrentHashMap _rateTrackers=new ConcurrentHashMap(); - private HashSet _whitelist; - + private final HashSet _whitelist = new HashSet(); + private final Timeout _requestTimeoutQ = new Timeout(); private final Timeout _trackerTimeoutQ = new Timeout(); @@ -155,12 +154,13 @@ public class DoSFilter implements Filter for (int p = 0; p < _queue.length; p++) { _queue[p] = new ConcurrentLinkedQueue(); - + final int priority=p; _listener[p] = new ContinuationListener() { public void onComplete(Continuation continuation) - {} + { + } public void onTimeout(Continuation continuation) { @@ -169,6 +169,9 @@ public class DoSFilter implements Filter }; } + _rateTrackers.clear(); + _whitelist.clear(); + int baseRateLimit = __DEFAULT_MAX_REQUESTS_PER_SEC; if (filterConfig.getInitParameter(MAX_REQUESTS_PER_S_INIT_PARAM) != null) baseRateLimit = Integer.parseInt(filterConfig.getInitParameter(MAX_REQUESTS_PER_S_INIT_PARAM)); @@ -203,39 +206,35 @@ public class DoSFilter implements Filter if (filterConfig.getInitParameter(MAX_IDLE_TRACKER_MS_INIT_PARAM) != null ) maxIdleTrackerMs = Long.parseLong(filterConfig.getInitParameter(MAX_IDLE_TRACKER_MS_INIT_PARAM)); _maxIdleTrackerMs = maxIdleTrackerMs; - + String whitelistString = ""; if (filterConfig.getInitParameter(IP_WHITELIST_INIT_PARAM) !=null ) whitelistString = filterConfig.getInitParameter(IP_WHITELIST_INIT_PARAM); - - // empty - if (whitelistString.length() == 0 ) - _whitelist = new HashSet(); - else + + if (whitelistString.length() > 0) { StringTokenizer tokenizer = new StringTokenizer(whitelistString, ","); - _whitelist = new HashSet(tokenizer.countTokens()); while (tokenizer.hasMoreTokens()) _whitelist.add(tokenizer.nextToken().trim()); - + Log.info("Whitelisted IP addresses: {}", _whitelist.toString()); } String tmp = filterConfig.getInitParameter(INSERT_HEADERS_INIT_PARAM); - _insertHeaders = tmp==null || Boolean.parseBoolean(tmp); - + _insertHeaders = tmp==null || Boolean.parseBoolean(tmp); + tmp = filterConfig.getInitParameter(TRACK_SESSIONS_INIT_PARAM); _trackSessions = tmp==null || Boolean.parseBoolean(tmp); - + tmp = filterConfig.getInitParameter(REMOTE_PORT_INIT_PARAM); _remotePort = tmp!=null&& Boolean.parseBoolean(tmp); _requestTimeoutQ.setNow(); _requestTimeoutQ.setDuration(_maxRequestMs); - + _trackerTimeoutQ.setNow(); _trackerTimeoutQ.setDuration(_maxIdleTrackerMs); - + _running=true; _timerThread = (new Thread() { @@ -245,12 +244,15 @@ public class DoSFilter implements Filter { while (_running) { + long now; synchronized (_requestTimeoutQ) { - _requestTimeoutQ.setNow(); + now = _requestTimeoutQ.setNow(); _requestTimeoutQ.tick(); - - _trackerTimeoutQ.setNow(_requestTimeoutQ.getNow()); + } + synchronized (_trackerTimeoutQ) + { + _trackerTimeoutQ.setNow(now); _trackerTimeoutQ.tick(); } try @@ -271,25 +273,25 @@ public class DoSFilter implements Filter }); _timerThread.start(); } - + public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterchain) throws IOException, ServletException { final HttpServletRequest srequest = (HttpServletRequest)request; final HttpServletResponse sresponse = (HttpServletResponse)response; - + final long now=_requestTimeoutQ.getNow(); - + // Look for the rate tracker for this request RateTracker tracker = (RateTracker)request.getAttribute(__TRACKER); - + if (tracker==null) { // This is the first time we have seen this request. - + // get a rate tracker associated with this request, and record one hit tracker = getRateTracker(request); - + // Calculate the rate and check it is over the allowed limit final boolean overRateLimit = tracker.isRateExceeded(now); @@ -298,15 +300,15 @@ public class DoSFilter implements Filter { doFilterChain(filterchain,srequest,sresponse); return; - } - + } + // We are over the limit. Log.warn("DOS ALERT: ip="+srequest.getRemoteAddr()+",session="+srequest.getRequestedSessionId()+",user="+srequest.getUserPrincipal()); - + // So either reject it, delay it or throttle it switch((int)_delayMs) { - case -1: + case -1: { // Reject this request if (_insertHeaders) @@ -346,7 +348,7 @@ public class DoSFilter implements Filter { // we were not accepted, so either we suspend to wait,or if we were woken up we insist or we fail final Continuation continuation = ContinuationSupport.getContinuation(request); - + Boolean throttled = (Boolean)request.getAttribute(__THROTTLED); if (throttled!=Boolean.TRUE && _throttleMs>0) { @@ -370,12 +372,12 @@ public class DoSFilter implements Filter accepted = true; } } - + // if we were accepted (either immediately or after throttle) - if (accepted) + if (accepted) // call the chain doFilterChain(filterchain,srequest,sresponse); - else + else { // fail the request if (_insertHeaders) @@ -414,11 +416,11 @@ public class DoSFilter implements Filter * @throws IOException * @throws ServletException */ - protected void doFilterChain(FilterChain chain, final HttpServletRequest request, final HttpServletResponse response) + protected void doFilterChain(FilterChain chain, final HttpServletRequest request, final HttpServletResponse response) throws IOException, ServletException { final Thread thread=Thread.currentThread(); - + final Timeout.Task requestTimeout = new Timeout.Task() { public void expired() @@ -458,7 +460,7 @@ public class DoSFilter implements Filter { response.setHeader("Connection", "close"); } - try + try { try { @@ -473,14 +475,14 @@ public class DoSFilter implements Filter { Log.warn(e); } - + // interrupt the handling thread thread.interrupt(); } - + /** * Get priority for this request, based on user type - * + * * @param request * @param tracker * @return priority @@ -507,39 +509,44 @@ public class DoSFilter implements Filter * track of this connection's request rate. If this is not the first request * from this connection, return the existing object with the stored stats. * If it is the first request, then create a new request tracker. - * + * * Assumes that each connection has an identifying characteristic, and goes * through them in order, taking the first that matches: user id (logged * in), session id, client IP address. Unidentifiable connections are lumped * into one. - * + * * When a session expires, its rate tracker is automatically deleted. - * + * * @param request * @return the request rate tracker for the current connection */ public RateTracker getRateTracker(ServletRequest request) { HttpServletRequest srequest = (HttpServletRequest)request; - - String loadId; - final int type; - - loadId = extractUserId(request); HttpSession session=srequest.getSession(false); - if (_trackSessions && session!=null && !session.isNew()) + + String loadId = extractUserId(request); + final int type; + if (loadId != null) { - loadId=session.getId(); - type = USER_SESSION; + type = USER_AUTH; } else { - loadId = _remotePort?(request.getRemoteAddr()+request.getRemotePort()):request.getRemoteAddr(); - type = USER_IP; + if (_trackSessions && session!=null && !session.isNew()) + { + loadId=session.getId(); + type = USER_SESSION; + } + else + { + loadId = _remotePort?(request.getRemoteAddr()+request.getRemotePort()):request.getRemoteAddr(); + type = USER_IP; + } } RateTracker tracker=_rateTrackers.get(loadId); - + if (tracker==null) { RateTracker t; @@ -551,11 +558,11 @@ public class DoSFilter implements Filter { t = new RateTracker(loadId,type,_maxRequestsPerSec); } - + tracker=_rateTrackers.putIfAbsent(loadId,t); if (tracker==null) tracker=t; - + if (type == USER_IP) { // USER_IP expiration from _rateTrackers is handled by the _trackerTimeoutQ @@ -579,14 +586,19 @@ public class DoSFilter implements Filter synchronized (_requestTimeoutQ) { _requestTimeoutQ.cancelAll(); + } + synchronized (_trackerTimeoutQ) + { _trackerTimeoutQ.cancelAll(); } + _rateTrackers.clear(); + _whitelist.clear(); } /** * Returns the user id, used to track this connection. * This SHOULD be overridden by subclasses. - * + * * @param request * @return a unique user id, if logged in; otherwise null. */ @@ -605,7 +617,7 @@ public class DoSFilter implements Filter protected final int _type; protected final long[] _timestamps; protected int _next; - + public RateTracker(String id, int type,int maxRequestsPerSecond) { _id = id; @@ -642,7 +654,7 @@ public class DoSFilter implements Filter return _type; } - + public void valueBound(HttpSessionBindingEvent event) { } @@ -651,14 +663,14 @@ public class DoSFilter implements Filter { _rateTrackers.remove(_id); } - + public void expired() { long now = _trackerTimeoutQ.getNow(); - int latestIndex = _next == 0 ? 3 : (_next - 1 ) % _timestamps.length; + int latestIndex = _next == 0 ? 3 : (_next - 1 ) % _timestamps.length; long last=_timestamps[latestIndex]; boolean hasRecentRequest = last != 0 && (now-last)<1000L; - + if (hasRecentRequest) reschedule(); else @@ -671,7 +683,7 @@ public class DoSFilter implements Filter return "RateTracker/"+_id+"/"+_type; } } - + class FixedRateTracker extends RateTracker { public FixedRateTracker(String id, int type, int numRecentRequestsTracked) @@ -693,11 +705,11 @@ public class DoSFilter implements Filter return false; } - + @Override public String toString() { return "Fixed"+super.toString(); } } -} \ No newline at end of file +} diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/AbstractDoSFilterTest.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/AbstractDoSFilterTest.java new file mode 100644 index 00000000000..2bad601e06a --- /dev/null +++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/AbstractDoSFilterTest.java @@ -0,0 +1,341 @@ +package org.eclipse.jetty.servlets; + +import java.io.IOException; +import java.net.Socket; +import javax.servlet.Filter; +import javax.servlet.Servlet; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.eclipse.jetty.http.HttpURI; +import org.eclipse.jetty.servlet.FilterHolder; +import org.eclipse.jetty.testing.ServletTester; +import org.eclipse.jetty.util.IO; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +/** + * @version $Revision$ $Date$ + */ +public abstract class AbstractDoSFilterTest +{ + private static ServletTester _tester; + private static String _host; + private static int _port; + private static long _requestMaxTime = 200; + private static FilterHolder _dosFilter; + private static FilterHolder _timeoutFilter; + + public static void startServer(Class filter) throws Exception + { + _tester = new ServletTester(); + HttpURI uri = new HttpURI(_tester.createChannelConnector(true)); + _host = uri.getHost(); + _port = uri.getPort(); + + _tester.setContextPath("/ctx"); + _tester.addServlet(TestServlet.class, "/*"); + + _dosFilter = _tester.addFilter(filter, "/dos/*", 0); + _dosFilter.setInitParameter("maxRequestsPerSec", "4"); + _dosFilter.setInitParameter("delayMs", "200"); + _dosFilter.setInitParameter("throttledRequests", "1"); + _dosFilter.setInitParameter("waitMs", "10"); + _dosFilter.setInitParameter("throttleMs", "4000"); + _dosFilter.setInitParameter("remotePort", "false"); + _dosFilter.setInitParameter("insertHeaders", "true"); + + _timeoutFilter = _tester.addFilter(filter, "/timeout/*", 0); + _timeoutFilter.setInitParameter("maxRequestsPerSec", "4"); + _timeoutFilter.setInitParameter("delayMs", "200"); + _timeoutFilter.setInitParameter("throttledRequests", "1"); + _timeoutFilter.setInitParameter("waitMs", "10"); + _timeoutFilter.setInitParameter("throttleMs", "4000"); + _timeoutFilter.setInitParameter("remotePort", "false"); + _timeoutFilter.setInitParameter("insertHeaders", "true"); + _timeoutFilter.setInitParameter("maxRequestMs", _requestMaxTime + ""); + + _tester.start(); + } + + @AfterClass + public static void stopServer() throws Exception + { + _tester.stop(); + } + + @Before + public void startFilters() throws Exception + { + _dosFilter.start(); + _timeoutFilter.start(); + } + + @After + public void stopFilters() throws Exception + { + _timeoutFilter.stop(); + _dosFilter.stop(); + } + + private String doRequests(String requests, int loops, long pause0, long pause1, String request) throws Exception + { + Socket socket = new Socket(_host, _port); + socket.setSoTimeout(30000); + + for (int i=loops;i-->0;) + { + socket.getOutputStream().write(requests.getBytes("UTF-8")); + socket.getOutputStream().flush(); + if (i>0 && pause0>0) + Thread.sleep(pause0); + } + if (pause1>0) + Thread.sleep(pause1); + socket.getOutputStream().write(request.getBytes("UTF-8")); + socket.getOutputStream().flush(); + + + String response; + if (requests.contains("/unresponsive")) + { + // don't read in anything, forcing the request to time out + Thread.sleep(_requestMaxTime * 2); + response = IO.toString(socket.getInputStream(),"UTF-8"); + } + else + { + response = IO.toString(socket.getInputStream(),"UTF-8"); + } + socket.close(); + return response; + } + + private int count(String responses,String substring) + { + int count=0; + int i=responses.indexOf(substring); + while (i>=0) + { + count++; + i=responses.indexOf(substring,i+substring.length()); + } + + return count; + } + + @Test + public void testEvenLowRateIP() throws Exception + { + String request="GET /ctx/dos/test HTTP/1.1\r\nHost: localhost\r\n\r\n"; + String last="GET /ctx/dos/test HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n"; + String responses = doRequests(request,11,300,300,last); + assertEquals(12,count(responses,"HTTP/1.1 200 OK")); + assertEquals(0,count(responses,"DoSFilter:")); + } + + @Test + public void testBurstLowRateIP() throws Exception + { + String request="GET /ctx/dos/test HTTP/1.1\r\nHost: localhost\r\n\r\n"; + String last="GET /ctx/dos/test HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n"; + String responses = doRequests(request+request+request+request,2,1100,1100,last); + + assertEquals(9,count(responses,"HTTP/1.1 200 OK")); + assertEquals(0,count(responses,"DoSFilter:")); + } + + @Test + public void testDelayedIP() throws Exception + { + String request="GET /ctx/dos/test HTTP/1.1\r\nHost: localhost\r\n\r\n"; + String last="GET /ctx/dos/test HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n"; + String responses = doRequests(request+request+request+request+request,2,1100,1100,last); + + assertEquals(11,count(responses,"HTTP/1.1 200 OK")); + assertEquals(2,count(responses,"DoSFilter: delayed")); + } + + @Test + public void testThrottledIP() throws Exception + { + Thread other = new Thread() + { + public void run() + { + try + { + // Cause a delay, then sleep while holding pass + String request="GET /ctx/dos/sleeper HTTP/1.1\r\nHost: localhost\r\n\r\n"; + String last="GET /ctx/dos/sleeper?sleep=2000 HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n"; + String responses = doRequests(request+request+request+request,1,0,0,last); + } + catch(Exception e) + { + e.printStackTrace(); + } + } + }; + other.start(); + Thread.sleep(1500); + + String request="GET /ctx/dos/test HTTP/1.1\r\nHost: localhost\r\n\r\n"; + String last="GET /ctx/dos/test HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n"; + String responses = doRequests(request+request+request+request,1,0,0,last); + //System.out.println("responses are " + responses); + assertEquals(5,count(responses,"HTTP/1.1 200 OK")); + assertEquals(1,count(responses,"DoSFilter: delayed")); + assertEquals(1,count(responses,"DoSFilter: throttled")); + assertEquals(0,count(responses,"DoSFilter: unavailable")); + + other.join(); + } + + @Test + public void testUnavailableIP() throws Exception + { + Thread other = new Thread() + { + public void run() + { + try + { + // Cause a delay, then sleep while holding pass + String request="GET /ctx/dos/test HTTP/1.1\r\nHost: localhost\r\n\r\n"; + String last="GET /ctx/dos/test?sleep=5000 HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n"; + String responses = doRequests(request+request+request+request,1,0,0,last); + } + catch(Exception e) + { + e.printStackTrace(); + } + } + }; + other.start(); + Thread.sleep(500); + + String request="GET /ctx/dos/test HTTP/1.1\r\nHost: localhost\r\n\r\n"; + String last="GET /ctx/dos/test HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n"; + String responses = doRequests(request+request+request+request,1,0,0,last); + + assertEquals(4,count(responses,"HTTP/1.1 200 OK")); + assertEquals(1,count(responses,"HTTP/1.1 503")); + assertEquals(1,count(responses,"DoSFilter: delayed")); + assertEquals(1,count(responses,"DoSFilter: throttled")); + assertEquals(1,count(responses,"DoSFilter: unavailable")); + + other.join(); + } + + @Test + public void testSessionTracking() throws Exception + { + // get a session, first + String requestSession="GET /ctx/dos/test?session=true HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n"; + String response=doRequests("",1,0,0,requestSession); + String sessionId=response.substring(response.indexOf("Set-Cookie: ")+12, response.indexOf(";")); + + // all other requests use this session + String request="GET /ctx/dos/test HTTP/1.1\r\nHost: localhost\r\nCookie: " + sessionId + "\r\n\r\n"; + String last="GET /ctx/dos/test HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\nCookie: " + sessionId + "\r\n\r\n"; + String responses = doRequests(request+request+request+request+request,2,1100,1100,last); + + assertEquals(11,count(responses,"HTTP/1.1 200 OK")); + assertEquals(2,count(responses,"DoSFilter: delayed")); + } + + @Test + public void testMultipleSessionTracking() throws Exception + { + // get some session ids, first + String requestSession="GET /ctx/dos/test?session=true HTTP/1.1\r\nHost: localhost\r\n\r\n"; + String closeRequest="GET /ctx/dos/test?session=true HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n"; + String response=doRequests(requestSession+requestSession,1,0,0,closeRequest); + + String[] sessions = response.split("\r\n\r\n"); + + String sessionId1=sessions[0].substring(sessions[0].indexOf("Set-Cookie: ")+12, sessions[0].indexOf(";")); + String sessionId2=sessions[1].substring(sessions[1].indexOf("Set-Cookie: ")+12, sessions[1].indexOf(";")); + + // alternate between sessions + String request1="GET /ctx/dos/test HTTP/1.1\r\nHost: localhost\r\nCookie: " + sessionId1 + "\r\n\r\n"; + String request2="GET /ctx/dos/test HTTP/1.1\r\nHost: localhost\r\nCookie: " + sessionId2 + "\r\n\r\n"; + String last="GET /ctx/dos/test HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\nCookie: " + sessionId2 + "\r\n\r\n"; + + // ensure the sessions are new + String responses = doRequests(request1+request2,1,1100,1100,last); + Thread.sleep(1000); + + responses = doRequests(request1+request2+request1+request2+request1,2,1100,1100,last); + + assertEquals(11,count(responses,"HTTP/1.1 200 OK")); + assertEquals(0,count(responses,"DoSFilter: delayed")); + + // alternate between sessions + responses = doRequests(request1+request2+request1+request2+request1,2,550,550,last); + + assertEquals(11,count(responses,"HTTP/1.1 200 OK")); + int delayedRequests = count(responses,"DoSFilter: delayed"); + assertTrue(delayedRequests >= 2 && delayedRequests <= 3); + } + + @Test + public void testUnresponsiveClient() throws Exception + { + int numRequests = 1000; + + String last="GET /ctx/timeout/unresponsive?lines="+numRequests+" HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n"; + String responses = doRequests("",0,0,0,last); + // was expired, and stopped before reaching the end of the requests + int responseLines = count(responses, "Line:"); + assertTrue(responses.contains("DoSFilter: timeout")); + assertTrue(responseLines > 0 && responseLines < numRequests); + } + + public static class TestServlet extends HttpServlet implements Servlet + { + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException + { + if (request.getParameter("session")!=null) + request.getSession(true); + if (request.getParameter("sleep")!=null) + { + try + { + Thread.sleep(Long.parseLong(request.getParameter("sleep"))); + } + catch(InterruptedException e) + { + } + } + + if (request.getParameter("lines")!=null) + { + int count = Integer.parseInt(request.getParameter("lines")); + for(int i = 0; i < count; ++i) + { + response.getWriter().append("Line: " + i+"\n"); + response.flushBuffer(); + + try + { + Thread.sleep(10); + } + catch(InterruptedException e) + { + } + + } + } + + response.setContentType("text/plain"); + } + } +} diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/CloseableDoSFilterTest.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/CloseableDoSFilterTest.java index 99e7bb96497..99cd5f419f9 100644 --- a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/CloseableDoSFilterTest.java +++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/CloseableDoSFilterTest.java @@ -4,11 +4,11 @@ // All rights reserved. This program and the accompanying materials // are made available under the terms of the Eclipse Public License v1.0 // and Apache License v2.0 which accompanies this distribution. -// The Eclipse Public License is available at +// The Eclipse Public License is available at // http://www.eclipse.org/legal/epl-v10.html // The Apache License v2.0 is available at // http://www.opensource.org/licenses/apache2.0.php -// You may elect to redistribute this code under either of these licenses. +// You may elect to redistribute this code under either of these licenses. // ======================================================================== package org.eclipse.jetty.servlets; @@ -16,60 +16,31 @@ package org.eclipse.jetty.servlets; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import org.eclipse.jetty.http.HttpURI; -import org.eclipse.jetty.servlet.FilterHolder; -import org.eclipse.jetty.testing.ServletTester; import org.eclipse.jetty.util.log.Log; +import org.junit.BeforeClass; -public class CloseableDoSFilterTest extends DoSFilterTest +public class CloseableDoSFilterTest extends AbstractDoSFilterTest { - protected void setUp() throws Exception + @BeforeClass + public static void setUp() throws Exception { - _tester = new ServletTester(); - HttpURI uri=new HttpURI(_tester.createSocketConnector(true)); - _host=uri.getHost(); - _port=uri.getPort(); - - _tester.setContextPath("/ctx"); - _tester.addServlet(TestServlet.class, "/*"); - - FilterHolder dos=_tester.addFilter(CloseableDoSFilter2.class,"/dos/*",0); - dos.setInitParameter("maxRequestsPerSec","4"); - dos.setInitParameter("delayMs","200"); - dos.setInitParameter("throttledRequests","1"); - dos.setInitParameter("waitMs","10"); - dos.setInitParameter("throttleMs","4000"); - dos.setInitParameter("remotePort", "false"); - dos.setInitParameter("insertHeaders", "true"); - - FilterHolder quickTimeout = _tester.addFilter(CloseableDoSFilter2.class,"/timeout/*",0); - quickTimeout.setInitParameter("maxRequestsPerSec","4"); - quickTimeout.setInitParameter("delayMs","200"); - quickTimeout.setInitParameter("throttledRequests","1"); - quickTimeout.setInitParameter("waitMs","10"); - quickTimeout.setInitParameter("throttleMs","4000"); - quickTimeout.setInitParameter("remotePort", "false"); - quickTimeout.setInitParameter("insertHeaders", "true"); - quickTimeout.setInitParameter("maxRequestMs", _maxRequestMs + ""); - - _tester.start(); - + startServer(CloseableDoSFilter2.class); } - + public static class CloseableDoSFilter2 extends CloseableDoSFilter - { + { public void closeConnection(HttpServletRequest request, HttpServletResponse response, Thread thread) { - try - { - response.getWriter().append("DoSFilter: timeout"); - response.flushBuffer(); - super.closeConnection(request,response,thread); - } - catch (Exception e) - { - Log.warn(e); - } - } + try + { + response.getWriter().append("DoSFilter: timeout"); + response.flushBuffer(); + super.closeConnection(request, response, thread); + } + catch (Exception e) + { + Log.warn(e); + } } + } } diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/DoSFilterTest.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/DoSFilterTest.java index 1cae8c0f957..bbf169f5831 100644 --- a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/DoSFilterTest.java +++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/DoSFilterTest.java @@ -3,7 +3,7 @@ // ------------------------------------------------------------------------ // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. -// You may obtain a copy of the License at +// You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, @@ -14,325 +14,20 @@ package org.eclipse.jetty.servlets; -import java.io.IOException; -import java.net.Socket; - -import javax.servlet.Servlet; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import junit.framework.TestCase; - -import org.eclipse.jetty.http.HttpURI; -import org.eclipse.jetty.servlet.FilterHolder; -import org.eclipse.jetty.testing.ServletTester; -import org.eclipse.jetty.util.IO; import org.eclipse.jetty.util.log.Log; +import org.junit.BeforeClass; -public class DoSFilterTest extends TestCase +public class DoSFilterTest extends AbstractDoSFilterTest { - protected ServletTester _tester; - protected String _host; - protected int _port; - - protected int _maxRequestMs = 200; - protected void setUp() throws Exception + @BeforeClass + public static void setUp() throws Exception { - _tester = new ServletTester(); - HttpURI uri=new HttpURI(_tester.createChannelConnector(true)); - _host=uri.getHost(); - _port=uri.getPort(); - - _tester.setContextPath("/ctx"); - _tester.addServlet(TestServlet.class, "/*"); - - FilterHolder dos=_tester.addFilter(DoSFilter2.class,"/dos/*",0); - dos.setInitParameter("maxRequestsPerSec","4"); - dos.setInitParameter("delayMs","200"); - dos.setInitParameter("throttledRequests","1"); - dos.setInitParameter("waitMs","10"); - dos.setInitParameter("throttleMs","4000"); - dos.setInitParameter("remotePort", "false"); - dos.setInitParameter("insertHeaders", "true"); - - FilterHolder quickTimeout = _tester.addFilter(DoSFilter2.class,"/timeout/*",0); - quickTimeout.setInitParameter("maxRequestsPerSec","4"); - quickTimeout.setInitParameter("delayMs","200"); - quickTimeout.setInitParameter("throttledRequests","1"); - quickTimeout.setInitParameter("waitMs","10"); - quickTimeout.setInitParameter("throttleMs","4000"); - quickTimeout.setInitParameter("remotePort", "false"); - quickTimeout.setInitParameter("insertHeaders", "true"); - quickTimeout.setInitParameter("maxRequestMs", _maxRequestMs + ""); - - _tester.start(); - - } - - protected void tearDown() throws Exception - { - _tester.stop(); - } - - private String doRequests(String requests, int loops, long pause0,long pause1,String request) - throws Exception - { - Socket socket = new Socket(_host,_port); - socket.setSoTimeout(30000); - - for (int i=loops;i-->0;) - { - socket.getOutputStream().write(requests.getBytes("UTF-8")); - socket.getOutputStream().flush(); - if (i>0 && pause0>0) - Thread.sleep(pause0); - } - if (pause1>0) - Thread.sleep(pause1); - socket.getOutputStream().write(request.getBytes("UTF-8")); - socket.getOutputStream().flush(); - - - String response = ""; - - if (requests.contains("/unresponsive")) - { - // don't read in anything, forcing the request to time out - Thread.sleep(_maxRequestMs * 2); - response = IO.toString(socket.getInputStream(),"UTF-8"); - } - else - { - response = IO.toString(socket.getInputStream(),"UTF-8"); - } - socket.close(); - return response; - } - - private int count(String responses,String substring) - { - int count=0; - int i=responses.indexOf(substring); - while (i>=0) - { - count++; - i=responses.indexOf(substring,i+substring.length()); - } - - return count; - } - - public void testEvenLowRateIP() - throws Exception - { - String request="GET /ctx/dos/test HTTP/1.1\r\nHost: localhost\r\n\r\n"; - String last="GET /ctx/dos/test HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n"; - String responses = doRequests(request,11,300,300,last); - assertEquals(12,count(responses,"HTTP/1.1 200 OK")); - assertEquals(0,count(responses,"DoSFilter:")); - } - - public void testBurstLowRateIP() - throws Exception - { - String request="GET /ctx/dos/test HTTP/1.1\r\nHost: localhost\r\n\r\n"; - String last="GET /ctx/dos/test HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n"; - String responses = doRequests(request+request+request+request,2,1100,1100,last); - - assertEquals(9,count(responses,"HTTP/1.1 200 OK")); - assertEquals(0,count(responses,"DoSFilter:")); - } - - public void testDelayedIP() - throws Exception - { - String request="GET /ctx/dos/test HTTP/1.1\r\nHost: localhost\r\n\r\n"; - String last="GET /ctx/dos/test HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n"; - String responses = doRequests(request+request+request+request+request,2,1100,1100,last); - - assertEquals(11,count(responses,"HTTP/1.1 200 OK")); - assertEquals(2,count(responses,"DoSFilter: delayed")); - } - - public void testThrottledIP() - throws Exception - { - Thread other = new Thread() - { - public void run() - { - try - { - // Cause a delay, then sleep while holding pass - String request="GET /ctx/dos/sleeper HTTP/1.1\r\nHost: localhost\r\n\r\n"; - String last="GET /ctx/dos/sleeper?sleep=2000 HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n"; - String responses = doRequests(request+request+request+request,1,0,0,last); - } - catch(Exception e) - { - e.printStackTrace(); - } - } - }; - other.start(); - Thread.sleep(1500); - - String request="GET /ctx/dos/test HTTP/1.1\r\nHost: localhost\r\n\r\n"; - String last="GET /ctx/dos/test HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n"; - String responses = doRequests(request+request+request+request,1,0,0,last); - //System.out.println("responses are " + responses); - assertEquals(5,count(responses,"HTTP/1.1 200 OK")); - assertEquals(1,count(responses,"DoSFilter: delayed")); - assertEquals(1,count(responses,"DoSFilter: throttled")); - assertEquals(0,count(responses,"DoSFilter: unavailable")); - - other.join(); - } - - public void testUnavailableIP() - throws Exception - { - Thread other = new Thread() - { - public void run() - { - try - { - // Cause a delay, then sleep while holding pass - String request="GET /ctx/dos/test HTTP/1.1\r\nHost: localhost\r\n\r\n"; - String last="GET /ctx/dos/test?sleep=5000 HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n"; - String responses = doRequests(request+request+request+request,1,0,0,last); - } - catch(Exception e) - { - e.printStackTrace(); - } - } - }; - other.start(); - Thread.sleep(500); - - String request="GET /ctx/dos/test HTTP/1.1\r\nHost: localhost\r\n\r\n"; - String last="GET /ctx/dos/test HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n"; - String responses = doRequests(request+request+request+request,1,0,0,last); - - assertEquals(4,count(responses,"HTTP/1.1 200 OK")); - assertEquals(1,count(responses,"HTTP/1.1 503")); - assertEquals(1,count(responses,"DoSFilter: delayed")); - assertEquals(1,count(responses,"DoSFilter: throttled")); - assertEquals(1,count(responses,"DoSFilter: unavailable")); - - other.join(); - } - - public void testSessionTracking() - throws Exception - { - // get a session, first - String requestSession="GET /ctx/dos/test?session=true HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n"; - String response=doRequests("",1,0,0,requestSession); - String sessionId=response.substring(response.indexOf("Set-Cookie: ")+12, response.indexOf(";")); - - // all other requests use this session - String request="GET /ctx/dos/test HTTP/1.1\r\nHost: localhost\r\nCookie: " + sessionId + "\r\n\r\n"; - String last="GET /ctx/dos/test HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\nCookie: " + sessionId + "\r\n\r\n"; - String responses = doRequests(request+request+request+request+request,2,1100,1100,last); - - assertEquals(11,count(responses,"HTTP/1.1 200 OK")); - assertEquals(2,count(responses,"DoSFilter: delayed")); + startServer(DoSFilter2.class); } - public void testMultipleSessionTracking() - throws Exception - { - // get some session ids, first - String requestSession="GET /ctx/dos/test?session=true HTTP/1.1\r\nHost: localhost\r\n\r\n"; - String closeRequest="GET /ctx/dos/test?session=true HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n"; - String response=doRequests(requestSession+requestSession,1,0,0,closeRequest); - - String[] sessions = response.split("\r\n\r\n"); - - String sessionId1=sessions[0].substring(sessions[0].indexOf("Set-Cookie: ")+12, sessions[0].indexOf(";")); - String sessionId2=sessions[1].substring(sessions[1].indexOf("Set-Cookie: ")+12, sessions[1].indexOf(";")); - - // alternate between sessions - String request1="GET /ctx/dos/test HTTP/1.1\r\nHost: localhost\r\nCookie: " + sessionId1 + "\r\n\r\n"; - String request2="GET /ctx/dos/test HTTP/1.1\r\nHost: localhost\r\nCookie: " + sessionId2 + "\r\n\r\n"; - String last="GET /ctx/dos/test HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\nCookie: " + sessionId2 + "\r\n\r\n"; - - // ensure the sessions are new - String responses = doRequests(request1+request2,1,1100,1100,last); - Thread.sleep(1000); - - responses = doRequests(request1+request2+request1+request2+request1,2,1100,1100,last); - - assertEquals(11,count(responses,"HTTP/1.1 200 OK")); - assertEquals(0,count(responses,"DoSFilter: delayed")); - - // alternate between sessions - responses = doRequests(request1+request2+request1+request2+request1,2,550,550,last); - - assertEquals(11,count(responses,"HTTP/1.1 200 OK")); - int delayedRequests = count(responses,"DoSFilter: delayed"); - assertTrue(delayedRequests >= 2 && delayedRequests <= 3); - } - - public void testUnresponsiveClient() - throws Exception - { - int numRequests = 1000; - - String last="GET /ctx/timeout/unresponsive?lines="+numRequests+" HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n"; - String responses = doRequests("",0,0,0,last); - // was expired, and stopped before reaching the end of the requests - int responseLines = count(responses, "Line:"); - assertTrue(responses.contains("DoSFilter: timeout")); - assertTrue(responseLines > 0 && responseLines < numRequests); - } - - public static class TestServlet extends HttpServlet implements Servlet - { - protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException - { - if (request.getParameter("session")!=null) - request.getSession(true); - if (request.getParameter("sleep")!=null) - { - try - { - Thread.sleep(Long.parseLong(request.getParameter("sleep"))); - } - catch(InterruptedException e) - { - } - } - - if (request.getParameter("lines")!=null) - { - int count = Integer.parseInt(request.getParameter("lines")); - for(int i = 0; i < count; ++i) - { - response.getWriter().append("Line: " + i+"\n"); - response.flushBuffer(); - - try - { - Thread.sleep(10); - } - catch(InterruptedException e) - { - } - - } - } - - response.setContentType("text/plain"); - - } - } - public static class DoSFilter2 extends DoSFilter { public void closeConnection(HttpServletRequest request, HttpServletResponse response, Thread thread) @@ -346,5 +41,5 @@ public class DoSFilterTest extends TestCase Log.warn(e); } } - } + } } diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/PutFilterTest.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/PutFilterTest.java index deb68aa7a86..e2f2d0e6a72 100644 --- a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/PutFilterTest.java +++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/PutFilterTest.java @@ -4,11 +4,11 @@ // All rights reserved. This program and the accompanying materials // are made available under the terms of the Eclipse Public License v1.0 // and Apache License v2.0 which accompanies this distribution. -// The Eclipse Public License is available at +// The Eclipse Public License is available at // http://www.eclipse.org/legal/epl-v10.html // The Apache License v2.0 is available at // http://www.opensource.org/licenses/apache2.0.php -// You may elect to redistribute this code under either of these licenses. +// You may elect to redistribute this code under either of these licenses. // ======================================================================== package org.eclipse.jetty.servlets; @@ -18,30 +18,33 @@ import java.io.FileInputStream; import java.io.OutputStream; import java.net.Socket; import java.net.URL; - import javax.servlet.http.HttpServletResponse; -import junit.framework.TestCase; - import org.eclipse.jetty.servlet.FilterHolder; import org.eclipse.jetty.testing.HttpTester; import org.eclipse.jetty.testing.ServletTester; import org.eclipse.jetty.util.IO; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; -public class PutFilterTest extends TestCase +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +public class PutFilterTest { - File _dir; - ServletTester tester; - - protected void setUp() throws Exception + private File _dir; + private ServletTester tester; + + @Before + public void setUp() throws Exception { _dir = File.createTempFile("testPutFilter",null); - _dir.delete(); - _dir.mkdir(); + assertTrue(_dir.delete()); + assertTrue(_dir.mkdir()); _dir.deleteOnExit(); assertTrue(_dir.isDirectory()); - - super.setUp(); + tester=new ServletTester(); tester.setContextPath("/context"); tester.setResourceBase(_dir.getCanonicalPath()); @@ -49,21 +52,21 @@ public class PutFilterTest extends TestCase FilterHolder holder = tester.addFilter(PutFilter.class,"/*",0); holder.setInitParameter("delAllowed","true"); tester.start(); - - } - protected void tearDown() throws Exception + @After + public void tearDown() throws Exception { - super.tearDown(); + tester.stop(); } + @Test public void testHandlePut() throws Exception { // generated and parsed test HttpTester request = new HttpTester(); HttpTester response = new HttpTester(); - + // test GET request.setMethod("GET"); request.setVersion("HTTP/1.0"); @@ -82,7 +85,7 @@ public class PutFilterTest extends TestCase response.parse(tester.getResponses(request.generate())); assertTrue(response.getMethod()==null); assertEquals(HttpServletResponse.SC_CREATED,response.getStatus()); - + File file=new File(_dir,"file.txt"); assertTrue(file.exists()); assertEquals(data0,IO.toString(new FileInputStream(file))); @@ -106,12 +109,10 @@ public class PutFilterTest extends TestCase response.parse(tester.getResponses(request.generate())); assertTrue(response.getMethod()==null); assertEquals(HttpServletResponse.SC_OK,response.getStatus()); - + file=new File(_dir,"file.txt"); assertTrue(file.exists()); assertEquals(data1,IO.toString(new FileInputStream(file))); - - // test PUT2 request.setMethod("PUT"); @@ -142,7 +143,7 @@ public class PutFilterTest extends TestCase out.write(to_send.substring(l-5).getBytes()); out.flush(); String in=IO.toString(socket.getInputStream()); - + request.setMethod("GET"); request.setVersion("HTTP/1.0"); request.setHeader("Host","tester"); @@ -151,10 +152,9 @@ public class PutFilterTest extends TestCase assertTrue(response.getMethod()==null); assertEquals(HttpServletResponse.SC_OK,response.getStatus()); assertEquals(data2,response.getContent()); - - } + @Test public void testHandleDelete() throws Exception { // generated and parsed test @@ -172,20 +172,18 @@ public class PutFilterTest extends TestCase response.parse(tester.getResponses(request.generate())); assertTrue(response.getMethod()==null); assertEquals(HttpServletResponse.SC_CREATED,response.getStatus()); - + File file=new File(_dir,"file.txt"); assertTrue(file.exists()); FileInputStream fis = new FileInputStream(file); assertEquals(data1,IO.toString(fis)); fis.close(); - request.setMethod("DELETE"); request.setURI("/context/file.txt"); response.parse(tester.getResponses(request.generate())); assertTrue(response.getMethod()==null); assertEquals(HttpServletResponse.SC_NO_CONTENT,response.getStatus()); - assertTrue(!file.exists()); @@ -194,10 +192,9 @@ public class PutFilterTest extends TestCase response.parse(tester.getResponses(request.generate())); assertTrue(response.getMethod()==null); assertEquals(HttpServletResponse.SC_FORBIDDEN,response.getStatus()); - - } + @Test public void testHandleMove() throws Exception { // generated and parsed test @@ -215,13 +212,12 @@ public class PutFilterTest extends TestCase response.parse(tester.getResponses(request.generate())); assertTrue(response.getMethod()==null); assertEquals(HttpServletResponse.SC_CREATED,response.getStatus()); - + File file=new File(_dir,"file.txt"); assertTrue(file.exists()); FileInputStream fis = new FileInputStream(file); assertEquals(data1,IO.toString(fis)); fis.close(); - request.setMethod("MOVE"); request.setURI("/context/file.txt"); @@ -229,22 +225,22 @@ public class PutFilterTest extends TestCase response.parse(tester.getResponses(request.generate())); assertTrue(response.getMethod()==null); assertEquals(HttpServletResponse.SC_NO_CONTENT,response.getStatus()); - + assertTrue(!file.exists()); File n_file=new File(_dir,"blah.txt"); assertTrue(n_file.exists()); - } + @Test public void testHandleOptions() { // TODO implement } + @Test public void testPassConditionalHeaders() { // TODO implement } - } diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/QoSFilterTest.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/QoSFilterTest.java index ecd7b840f6a..8c871aa1995 100644 --- a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/QoSFilterTest.java +++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/QoSFilterTest.java @@ -4,20 +4,18 @@ // All rights reserved. This program and the accompanying materials // are made available under the terms of the Eclipse Public License v1.0 // and Apache License v2.0 which accompanies this distribution. -// The Eclipse Public License is available at +// The Eclipse Public License is available at // http://www.eclipse.org/legal/epl-v10.html // The Apache License v2.0 is available at // http://www.opensource.org/licenses/apache2.0.php -// You may elect to redistribute this code under either of these licenses. +// You may elect to redistribute this code under either of these licenses. // ======================================================================== package org.eclipse.jetty.servlets; import java.io.IOException; -import java.io.InputStream; import java.net.URL; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; - import javax.servlet.Servlet; import javax.servlet.ServletException; import javax.servlet.ServletRequest; @@ -25,16 +23,20 @@ import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import junit.framework.TestCase; - import org.eclipse.jetty.server.LocalConnector; import org.eclipse.jetty.servlet.FilterHolder; import org.eclipse.jetty.servlet.FilterMapping; import org.eclipse.jetty.testing.HttpTester; import org.eclipse.jetty.testing.ServletTester; import org.eclipse.jetty.util.log.Log; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; -public class QoSFilterTest extends TestCase +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +public class QoSFilterTest { private ServletTester _tester; private LocalConnector[] _connectors; @@ -42,42 +44,46 @@ public class QoSFilterTest extends TestCase private final int NUM_CONNECTIONS = 8; private final int NUM_LOOPS = 6; private final int MAX_QOS = 4; - - protected void setUp() throws Exception + + @Before + public void setUp() throws Exception { _tester = new ServletTester(); _tester.setContextPath("/context"); _tester.addServlet(TestServlet.class, "/test"); TestServlet.__maxSleepers=0; TestServlet.__sleepers=0; - + _connectors = new LocalConnector[NUM_CONNECTIONS]; for(int i = 0; i < _connectors.length; ++i) _connectors[i] = _tester.createLocalConnector(); - + _doneRequests = new CountDownLatch(NUM_CONNECTIONS*NUM_LOOPS); - + _tester.start(); } - - protected void tearDown() throws Exception + + @After + public void tearDown() throws Exception { _tester.stop(); } + @Test public void testNoFilter() throws Exception - { + { for(int i = 0; i < NUM_CONNECTIONS; ++i ) { new Thread(new Worker(i)).start(); } - + _doneRequests.await(10,TimeUnit.SECONDS); - + assertFalse("TEST WAS NOT PARALLEL ENOUGH!",TestServlet.__maxSleepers<=MAX_QOS); assertTrue(TestServlet.__maxSleepers<=NUM_CONNECTIONS); } + @Test public void testBlockingQosFilter() throws Exception { FilterHolder holder = new FilterHolder(QoSFilter2.class); @@ -95,23 +101,24 @@ public class QoSFilterTest extends TestCase assertTrue(TestServlet.__maxSleepers==MAX_QOS); } + @Test public void testQosFilter() throws Exception - { + { FilterHolder holder = new FilterHolder(QoSFilter2.class); holder.setAsyncSupported(true); holder.setInitParameter(QoSFilter.MAX_REQUESTS_INIT_PARAM, ""+MAX_QOS); _tester.getContext().getServletHandler().addFilterWithMapping(holder,"/*",FilterMapping.DEFAULT); - + for(int i = 0; i < NUM_CONNECTIONS; ++i ) { new Thread(new Worker2(i)).start(); } - + _doneRequests.await(20,TimeUnit.SECONDS); assertFalse("TEST WAS NOT PARALLEL ENOUGH!",TestServlet.__maxSleepers