From a81611400d08a52692698794a4487016c84509c4 Mon Sep 17 00:00:00 2001 From: Michael Gorovoy Date: Wed, 24 Aug 2011 18:11:06 -0400 Subject: [PATCH] 354080 ServletContextHandler allows to replace any subordinate handler when restarted --- VERSION.txt | 1 + .../jetty/servlet/ServletContextHandler.java | 20 +- .../servlet/ServletContextHandlerTest.java | 181 +++++++++++++++++- 3 files changed, 186 insertions(+), 16 deletions(-) diff --git a/VERSION.txt b/VERSION.txt index 3deb8c528aa..e60de54f0a9 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1,4 +1,5 @@ jetty-7.5.0-SNAPSHOT + + 354080 ServletContextHandler allows to replace any subordinate handler when restarted jetty-7.5.0.RC1 - 19 August 2011 + 276670 SLF4J loggers show correct location information diff --git a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletContextHandler.java b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletContextHandler.java index 92fa5656f4a..09b60680021 100644 --- a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletContextHandler.java +++ b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletContextHandler.java @@ -72,6 +72,7 @@ public class ServletContextHandler extends ContextHandler protected SessionHandler _sessionHandler; protected SecurityHandler _securityHandler; protected ServletHandler _servletHandler; + protected HandlerWrapper _wrapper; protected int _options; protected Object _restrictedContextListeners; @@ -142,6 +143,7 @@ public class ServletContextHandler extends ContextHandler { super.doStop(); _decorators.clear(); + _wrapper.setHandler(null); } /* ------------------------------------------------------------ */ @@ -214,16 +216,16 @@ public class ServletContextHandler extends ContextHandler } // skip any wrapped handlers - HandlerWrapper wrapper=this; - while (wrapper!=handler && wrapper.getHandler() instanceof HandlerWrapper) - wrapper=(HandlerWrapper)wrapper.getHandler(); + _wrapper=this; + while (_wrapper!=handler && _wrapper.getHandler() instanceof HandlerWrapper) + _wrapper=(HandlerWrapper)_wrapper.getHandler(); // if we are not already linked - if (wrapper!=handler) + if (_wrapper!=handler) { - if (wrapper.getHandler()!=null ) + if (_wrapper.getHandler()!=null ) throw new IllegalStateException("!ScopedHandler"); - wrapper.setHandler(handler); + _wrapper.setHandler(handler); } super.startContext(); @@ -376,7 +378,7 @@ public class ServletContextHandler extends ContextHandler { if (isStarted()) throw new IllegalStateException("STARTED"); - + _sessionHandler = sessionHandler; } @@ -388,7 +390,7 @@ public class ServletContextHandler extends ContextHandler { if (isStarted()) throw new IllegalStateException("STARTED"); - + _securityHandler = securityHandler; } @@ -400,7 +402,7 @@ public class ServletContextHandler extends ContextHandler { if (isStarted()) throw new IllegalStateException("STARTED"); - + _servletHandler = servletHandler; } diff --git a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/ServletContextHandlerTest.java b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/ServletContextHandlerTest.java index 9d9e4a3dfb1..522643605ff 100644 --- a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/ServletContextHandlerTest.java +++ b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/ServletContextHandlerTest.java @@ -2,25 +2,54 @@ package org.eclipse.jetty.servlet; import static org.junit.Assert.assertEquals; +import java.io.IOException; +import java.io.PrintWriter; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import junit.framework.AssertionFailedError; + import org.eclipse.jetty.security.ConstraintSecurityHandler; import org.eclipse.jetty.security.SecurityHandler; +import org.eclipse.jetty.server.LocalConnector; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.handler.AbstractHandlerContainer; import org.eclipse.jetty.server.handler.ContextHandler; import org.eclipse.jetty.server.handler.ContextHandlerCollection; import org.eclipse.jetty.server.session.SessionHandler; +import org.junit.After; +import org.junit.Before; import org.junit.Test; public class ServletContextHandlerTest { + private Server _server; + private LocalConnector _connector; + + @Before + public void createServer() + { + _server = new Server(); + _connector = new LocalConnector(); + _server.addConnector(_connector); + } + + @After + public void destroyServer() throws Exception + { + _server.stop(); + _server.join(); + } + @Test public void testFindContainer() throws Exception { - Server server = new Server(); - ContextHandlerCollection contexts = new ContextHandlerCollection(); - server.setHandler(contexts); + _server.setHandler(contexts); ServletContextHandler root = new ServletContextHandler(contexts,"/",ServletContextHandler.SESSIONS); @@ -28,10 +57,148 @@ public class ServletContextHandlerTest ServletHandler servlet = root.getServletHandler(); SecurityHandler security = new ConstraintSecurityHandler(); root.setSecurityHandler(security); - server.start(); - assertEquals(root, AbstractHandlerContainer.findContainerOf(server, ContextHandler.class, session)); - assertEquals(root, AbstractHandlerContainer.findContainerOf(server, ContextHandler.class, security)); - assertEquals(root, AbstractHandlerContainer.findContainerOf(server, ContextHandler.class, servlet)); + _server.start(); + + assertEquals(root, AbstractHandlerContainer.findContainerOf(_server, ContextHandler.class, session)); + assertEquals(root, AbstractHandlerContainer.findContainerOf(_server, ContextHandler.class, security)); + assertEquals(root, AbstractHandlerContainer.findContainerOf(_server, ContextHandler.class, servlet)); + } + + @Test + public void testAddServletAfterStart() throws Exception + { + ServletContextHandler context = new ServletContextHandler(); + context.addServlet(TestServlet.class,"/test"); + context.setContextPath("/"); + _server.setHandler(context); + _server.start(); + + StringBuffer request = new StringBuffer(); + request.append("GET /test HTTP/1.1\n"); + request.append("Host: localhost\n"); + request.append("\n"); + + String response = _connector.getResponses(request.toString()); + assertResponseContains("Test", response); + + context.addServlet(HelloServlet.class, "/hello"); + + request = new StringBuffer(); + request.append("GET /hello HTTP/1.1\n"); + request.append("Host: localhost\n"); + request.append("\n"); + + response = _connector.getResponses(request.toString()); + assertResponseContains("Hello World", response); + } + + @Test + public void testReplaceServletHandlerWithServlet() throws Exception + { + ServletContextHandler context = new ServletContextHandler(); + context.addServlet(TestServlet.class,"/test"); + context.setContextPath("/"); + _server.setHandler(context); + _server.start(); + + StringBuffer request = new StringBuffer(); + request.append("GET /test HTTP/1.1\n"); + request.append("Host: localhost\n"); + request.append("\n"); + + String response = _connector.getResponses(request.toString()); + assertResponseContains("Test", response); + + context.stop(); + ServletHandler srvHnd = new ServletHandler(); + srvHnd.addServletWithMapping(HelloServlet.class,"/hello"); + context.setServletHandler(srvHnd); + context.start(); + + request = new StringBuffer(); + request.append("GET /hello HTTP/1.1\n"); + request.append("Host: localhost\n"); + request.append("\n"); + + response = _connector.getResponses(request.toString()); + assertResponseContains("Hello World", response); + } + + @Test + public void testReplaceServletHandlerWithoutServlet() throws Exception + { + ServletContextHandler context = new ServletContextHandler(); + context.addServlet(TestServlet.class,"/test"); + context.setContextPath("/"); + _server.setHandler(context); + _server.start(); + + StringBuffer request = new StringBuffer(); + request.append("GET /test HTTP/1.1\n"); + request.append("Host: localhost\n"); + request.append("\n"); + + String response = _connector.getResponses(request.toString()); + assertResponseContains("Test", response); + + context.stop(); + ServletHandler srvHnd = new ServletHandler(); + context.setServletHandler(srvHnd); + context.start(); + + context.addServlet(HelloServlet.class,"/hello"); + + request = new StringBuffer(); + request.append("GET /hello HTTP/1.1\n"); + request.append("Host: localhost\n"); + request.append("\n"); + + response = _connector.getResponses(request.toString()); + assertResponseContains("Hello World", response); + } + + private int assertResponseContains(String expected, String response) + { + int idx = response.indexOf(expected); + if (idx == (-1)) + { + // Not found + StringBuffer err = new StringBuffer(); + err.append("Response does not contain expected string \"").append(expected).append("\""); + err.append("\n").append(response); + + System.err.println(err); + throw new AssertionFailedError(err.toString()); + } + return idx; + } + + public static class HelloServlet extends HttpServlet + { + private static final long serialVersionUID = 1L; + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) + throws ServletException, IOException + { + resp.setStatus(HttpServletResponse.SC_OK); + PrintWriter writer = resp.getWriter(); + writer.write("Hello World"); + } + } + + public static class TestServlet extends HttpServlet + { + private static final long serialVersionUID = 1L; + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) + throws ServletException, IOException + { + resp.setStatus(HttpServletResponse.SC_OK); + PrintWriter writer = resp.getWriter(); + writer.write("Test"); + } } }