486530 - Handler added to WebAppContext prevents ServletContext initialization

Added warnings for loops and inappropriate handlers.
Used insertHandler in more XML files
This commit is contained in:
Greg Wilkins 2016-02-03 10:54:39 +01:00
parent 79a7863ac8
commit 6c9a444b6c
18 changed files with 593 additions and 227 deletions

View File

@ -7,13 +7,13 @@
<Configure id="Server" class="org.eclipse.jetty.server.Server"> <Configure id="Server" class="org.eclipse.jetty.server.Server">
<Get id="oldhandler" name="handler" /> <Call name="insertHandler">
<Set name="handler"> <Arg>
<New id="JamonHandler" class="com.jamonapi.http.JAMonJettyHandlerNew"> <New id="JamonHandler" class="com.jamonapi.http.JAMonJettyHandlerNew">
<Set name="handler"><Ref refid="oldhandler" /></Set> <Set name="summaryLabels"><Property name="jamon.summaryLabels" /></Set>
<Set name="summaryLabels"><Property name="jamon.summaryLabels" /></Set> </New>
</New> </Arg>
</Set> </Call>
<Ref refid="Contexts"> <Ref refid="Contexts">
<Call name="addHandler"> <Call name="addHandler">

View File

@ -1,47 +1,41 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd"> <!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
<!-- =============================================================== -->
<!-- Mixin the RewriteHandler -->
<!-- =============================================================== -->
<Configure id="Server" class="org.eclipse.jetty.server.Server"> <Configure id="Server" class="org.eclipse.jetty.server.Server">
<!-- =========================================================== --> <!-- =========================================================== -->
<!-- configure rewrite handler --> <!-- configure rewrite handler -->
<!-- =========================================================== --> <!-- =========================================================== -->
<Get id="oldhandler" name="handler"/> <Call name="insertHandler">
<Arg>
<New id="Rewrite" class="org.eclipse.jetty.rewrite.handler.RewriteHandler">
<Set name="rewriteRequestURI"><Property name="jetty.rewrite.rewriteRequestURI" deprecated="rewrite.rewriteRequestURI" default="true"/></Set>
<Set name="rewritePathInfo"><Property name="jetty.rewrite.rewritePathInfo" deprecated="rewrite.rewritePathInfo" default="false"/></Set>
<Set name="originalPathAttribute"><Property name="jetty.rewrite.originalPathAttribute" deprecated="rewrite.originalPathAttribute" default="requestedPath"/></Set>
<!-- Set DispatcherTypes -->
<Set name="dispatcherTypes">
<Array type="javax.servlet.DispatcherType">
<Item><Call class="javax.servlet.DispatcherType" name="valueOf"><Arg>REQUEST</Arg></Call></Item>
<Item><Call class="javax.servlet.DispatcherType" name="valueOf"><Arg>ASYNC</Arg></Call></Item>
</Array>
</Set>
<Set name="handler"> <!-- example rule -->
<New id="Rewrite" class="org.eclipse.jetty.rewrite.handler.RewriteHandler"> <!--
<Set name="handler"><Ref refid="oldhandler"/></Set> <Call name="addRule">
<Set name="rewriteRequestURI"><Property name="jetty.rewrite.rewriteRequestURI" deprecated="rewrite.rewriteRequestURI" default="true"/></Set> <Arg>
<Set name="rewritePathInfo"><Property name="jetty.rewrite.rewritePathInfo" deprecated="rewrite.rewritePathInfo" default="false"/></Set> <New class="org.eclipse.jetty.rewrite.handler.HeaderPatternRule">
<Set name="originalPathAttribute"><Property name="jetty.rewrite.originalPathAttribute" deprecated="rewrite.originalPathAttribute" default="requestedPath"/></Set> <Set name="pattern">/favicon.ico</Set>
<Set name="name">Cache-Control</Set>
<!-- Set DispatcherTypes --> <Set name="value">Max-Age=3600,public</Set>
<Set name="dispatcherTypes"> <Set name="terminating">true</Set>
<Array type="javax.servlet.DispatcherType"> </New>
<Item><Call class="javax.servlet.DispatcherType" name="valueOf"><Arg>REQUEST</Arg></Call></Item> </Arg>
<Item><Call class="javax.servlet.DispatcherType" name="valueOf"><Arg>ASYNC</Arg></Call></Item> </Call>
</Array> -->
</Set>
<!-- example rule --> </New>
<!-- </Arg>
<Call name="addRule"> </Call>
<Arg>
<New class="org.eclipse.jetty.rewrite.handler.HeaderPatternRule">
<Set name="pattern">/favicon.ico</Set>
<Set name="name">Cache-Control</Set>
<Set name="value">Max-Age=3600,public</Set>
<Set name="terminating">true</Set>
</New>
</Arg>
</Call>
-->
</New>
</Set>
</Configure> </Configure>

View File

@ -6,20 +6,20 @@
<!-- =============================================================== --> <!-- =============================================================== -->
<Configure id="Server" class="org.eclipse.jetty.server.Server"> <Configure id="Server" class="org.eclipse.jetty.server.Server">
<Get id="oldhandler" name="handler"/> <Call name="insertHandler">
<Set name="handler"> <Arg>
<New id="DebugHandler" class="org.eclipse.jetty.server.handler.DebugHandler"> <New id="DebugHandler" class="org.eclipse.jetty.server.handler.DebugHandler">
<Set name="handler"><Ref refid="oldhandler"/></Set> <Set name="outputStream">
<Set name="outputStream"> <New class="org.eclipse.jetty.util.RolloverFileOutputStream">
<New class="org.eclipse.jetty.util.RolloverFileOutputStream"> <Arg type="String"><Property name="jetty.debuglog.dir" deprecated="jetty.logs" default="./logs"/>/yyyy_mm_dd.debug.log</Arg>
<Arg type="String"><Property name="jetty.debuglog.dir" deprecated="jetty.logs" default="./logs"/>/yyyy_mm_dd.debug.log</Arg> <Arg type="boolean"><Property name="jetty.debuglog.append" default="true"/></Arg>
<Arg type="boolean"><Property name="jetty.debuglog.append" default="true"/></Arg> <Arg type="int"><Property name="jetty.debuglog.retainDays" default="90"/></Arg>
<Arg type="int"><Property name="jetty.debuglog.retainDays" default="90"/></Arg> <Arg>
<Arg> <Call class="java.util.TimeZone" name="getTimeZone"><Arg><Property name="jetty.debuglog.timezone" default="GMT"/></Arg></Call>
<Call class="java.util.TimeZone" name="getTimeZone"><Arg><Property name="jetty.debuglog.timezone" default="GMT"/></Arg></Call> </Arg>
</Arg> </New>
</New> </Set>
</Set> </New>
</New> </Arg>
</Set> </Call>
</Configure> </Configure>

View File

@ -9,59 +9,59 @@
<!-- =============================================================== --> <!-- =============================================================== -->
<Configure id="Server" class="org.eclipse.jetty.server.Server"> <Configure id="Server" class="org.eclipse.jetty.server.Server">
<Get id="next" name="handler" /> <Call name="insertHandler">
<Set name="handler"> <Arg>
<New id="GzipHandler" class="org.eclipse.jetty.server.handler.gzip.GzipHandler"> <New id="GzipHandler" class="org.eclipse.jetty.server.handler.gzip.GzipHandler">
<Set name="handler"><Ref refid="next" /></Set> <Set name="minGzipSize"><Property name="jetty.gzip.minGzipSize" deprecated="gzip.minGzipSize" default="2048"/></Set>
<Set name="minGzipSize"><Property name="jetty.gzip.minGzipSize" deprecated="gzip.minGzipSize" default="2048"/></Set> <Set name="checkGzExists"><Property name="jetty.gzip.checkGzExists" deprecated="gzip.checkGzExists" default="false"/></Set>
<Set name="checkGzExists"><Property name="jetty.gzip.checkGzExists" deprecated="gzip.checkGzExists" default="false"/></Set> <Set name="compressionLevel"><Property name="jetty.gzip.compressionLevel" deprecated="gzip.compressionLevel" default="-1"/></Set>
<Set name="compressionLevel"><Property name="jetty.gzip.compressionLevel" deprecated="gzip.compressionLevel" default="-1"/></Set> <Set name="excludedAgentPatterns">
<Set name="excludedAgentPatterns"> <Array type="String">
<Array type="String"> <Item><Property name="jetty.gzip.excludedUserAgent" deprecated="gzip.excludedUserAgent" default=".*MSIE.6\.0.*"/></Item>
<Item><Property name="jetty.gzip.excludedUserAgent" deprecated="gzip.excludedUserAgent" default=".*MSIE.6\.0.*"/></Item> </Array>
</Array> </Set>
</Set>
<Set name="includedMethods"> <Set name="includedMethods">
<Array type="String"> <Array type="String">
<Item>GET</Item> <Item>GET</Item>
</Array> </Array>
</Set> </Set>
<!-- <!--
<Set name="includedPaths"> <Set name="includedPaths">
<Array type="String"> <Array type="String">
<Item>/*</Item> <Item>/*</Item>
</Array> </Array>
</Set> </Set>
--> -->
<!-- <!--
<Set name="excludedPaths"> <Set name="excludedPaths">
<Array type="String"> <Array type="String">
<Item>*.gz</Item> <Item>*.gz</Item>
</Array> </Array>
</Set> </Set>
--> -->
<!-- <!--
<Call name="addIncludedMimeTypes"> <Call name="addIncludedMimeTypes">
<Arg><Array type="String"> <Arg><Array type="String">
<Item>some/type</Item> <Item>some/type</Item>
</Array></Arg> </Array></Arg>
</Call> </Call>
--> -->
<!-- <!--
<Call name="addExcludedMimeTypes"> <Call name="addExcludedMimeTypes">
<Arg><Array type="String"> <Arg><Array type="String">
<Item>some/type</Item> <Item>some/type</Item>
</Array></Arg> </Array></Arg>
</Call> </Call>
--> -->
</New> </New>
</Set> </Arg>
</Call>
</Configure> </Configure>

View File

@ -6,26 +6,23 @@
<!-- =============================================================== --> <!-- =============================================================== -->
<Configure id="Server" class="org.eclipse.jetty.server.Server"> <Configure id="Server" class="org.eclipse.jetty.server.Server">
<Call name="insertHandler">
<Get id="oldhandler" name="handler"/> <Arg>
<New id="IPAccessHandler" class="org.eclipse.jetty.server.handler.IPAccessHandler">
<Set name="handler"> <Set name="white">
<New id="IPAccessHandler" class="org.eclipse.jetty.server.handler.IPAccessHandler"> <Array type="String">
<Set name="handler"><Ref refid="oldhandler"/></Set> <Item>127.0.0.1</Item>
<Set name="white"> <Item>127.0.0.2/*.html</Item>
<Array type="String"> </Array>
<Item>127.0.0.1</Item> </Set>
<Item>127.0.0.2/*.html</Item> <Set name="black">
</Array> <Array type="String">
</Set> <Item>127.0.0.1/blacklisted</Item>
<Set name="black"> <Item>127.0.0.2/black.html</Item>
<Array type="String"> </Array>
<Item>127.0.0.1/blacklisted</Item> </Set>
<Item>127.0.0.2/black.html</Item> <Set name="whiteListByPath">false</Set>
</Array> </New>
</Set> </Arg>
<Set name="whiteListByPath">false</Set> </Call>
</New>
</Set>
</Configure> </Configure>

View File

@ -6,12 +6,12 @@
<!-- =============================================================== --> <!-- =============================================================== -->
<Configure id="Server" class="org.eclipse.jetty.server.Server"> <Configure id="Server" class="org.eclipse.jetty.server.Server">
<Get id="oldhandler" name="handler" /> <Call name="insertHandler">
<Set name="handler"> <Arg>
<New id="StatsHandler" class="org.eclipse.jetty.server.handler.StatisticsHandler"> <New id="StatsHandler" class="org.eclipse.jetty.server.handler.StatisticsHandler">
<Set name="handler"><Ref refid="oldhandler" /></Set> </New>
</New> </Arg>
</Set> </Call>
<Call class="org.eclipse.jetty.server.ConnectorStatistics" name="addToAllConnectors"> <Call class="org.eclipse.jetty.server.ConnectorStatistics" name="addToAllConnectors">
<Arg><Ref refid="Server"/></Arg> <Arg><Ref refid="Server"/></Arg>
</Call> </Call>

View File

@ -100,7 +100,7 @@ import org.eclipse.jetty.util.resource.Resource;
* The maximum size of a form that can be processed by this context is controlled by the system properties org.eclipse.jetty.server.Request.maxFormKeys * The maximum size of a form that can be processed by this context is controlled by the system properties org.eclipse.jetty.server.Request.maxFormKeys
* and org.eclipse.jetty.server.Request.maxFormContentSize. These can also be configured with {@link #setMaxFormContentSize(int)} and {@link #setMaxFormKeys(int)} * and org.eclipse.jetty.server.Request.maxFormContentSize. These can also be configured with {@link #setMaxFormContentSize(int)} and {@link #setMaxFormKeys(int)}
* <p> * <p>
* This servers executore is made available via a context attributed "org.eclipse.jetty.server.Executor". * This servers executor is made available via a context attributed "org.eclipse.jetty.server.Executor".
* <p> * <p>
* By default, the context is created with alias checkers for {@link AllowSymLinkAliasChecker} (unix only) and {@link ApproveNonExistentDirectoryAliases}. * By default, the context is created with alias checkers for {@link AllowSymLinkAliasChecker} (unix only) and {@link ApproveNonExistentDirectoryAliases}.
* If these alias checkers are not required, then {@link #clearAliasChecks()} or {@link #setAliasChecks(List)} should be called. * If these alias checkers are not required, then {@link #clearAliasChecks()} or {@link #setAliasChecks(List)} should be called.

View File

@ -27,6 +27,7 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.server.Handler; import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.HandlerContainer;
import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.util.ArrayUtil; import org.eclipse.jetty.util.ArrayUtil;
@ -82,9 +83,18 @@ public class HandlerCollection extends AbstractHandlerContainer
throw new IllegalStateException(STARTED); throw new IllegalStateException(STARTED);
if (handlers!=null) if (handlers!=null)
{
// check for loops
for (Handler handler:handlers)
if (handler == this || (handler instanceof HandlerContainer &&
Arrays.asList(((HandlerContainer)handler).getChildHandlers()).contains(this)))
throw new IllegalStateException("setHandler loop");
// Set server
for (Handler handler:handlers) for (Handler handler:handlers)
if (handler.getServer()!=getServer()) if (handler.getServer()!=getServer())
handler.setServer(getServer()); handler.setServer(getServer());
}
Handler[] old=_handlers;; Handler[] old=_handlers;;
_handlers = handlers; _handlers = handlers;
updateBeans(old, handlers); updateBeans(old, handlers);

View File

@ -19,6 +19,7 @@
package org.eclipse.jetty.server.handler; package org.eclipse.jetty.server.handler;
import java.io.IOException; import java.io.IOException;
import java.util.Arrays;
import java.util.List; import java.util.List;
import javax.servlet.ServletException; import javax.servlet.ServletException;
@ -27,6 +28,7 @@ import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.server.Handler; import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.HandlerContainer;
import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.util.annotation.ManagedAttribute; import org.eclipse.jetty.util.annotation.ManagedAttribute;
@ -82,6 +84,11 @@ public class HandlerWrapper extends AbstractHandlerContainer
if (isStarted()) if (isStarted())
throw new IllegalStateException(STARTED); throw new IllegalStateException(STARTED);
// check for loops
if (handler==this || (handler instanceof HandlerContainer &&
Arrays.asList(((HandlerContainer)handler).getChildHandlers()).contains(this)))
throw new IllegalStateException("setHandler loop");
if (handler!=null) if (handler!=null)
handler.setServer(getServer()); handler.setServer(getServer());
@ -104,10 +111,18 @@ public class HandlerWrapper extends AbstractHandlerContainer
*/ */
public void insertHandler(HandlerWrapper wrapper) public void insertHandler(HandlerWrapper wrapper)
{ {
if (wrapper==null || wrapper.getHandler()!=null) if (wrapper==null)
throw new IllegalArgumentException(); throw new IllegalArgumentException();
wrapper.setHandler(getHandler());
HandlerWrapper tail = wrapper;
while(tail.getHandler() instanceof HandlerWrapper)
tail=(HandlerWrapper)tail.getHandler();
if (tail.getHandler()!=null)
throw new IllegalArgumentException("bad tail of inserted wrapper chain");
Handler next=getHandler();
setHandler(wrapper); setHandler(wrapper);
tail.setHandler(next);
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */

View File

@ -0,0 +1,342 @@
//
// ========================================================================
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// 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
// 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.
// ========================================================================
//
package org.eclipse.jetty.server.handler;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.nullValue;
import static org.junit.Assert.*;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.handler.HandlerWrapper;
import org.hamcrest.Matchers;
import org.junit.Test;
public class HandlerTest
{
@Test
public void testWrapperSetServer()
{
Server s=new Server();
HandlerWrapper a = new HandlerWrapper();
HandlerWrapper b = new HandlerWrapper();
HandlerWrapper c = new HandlerWrapper();
a.setHandler(b);
b.setHandler(c);
a.setServer(s);
assertThat(b.getServer(),equalTo(s));
assertThat(c.getServer(),equalTo(s));
}
@Test
public void testWrapperServerSet()
{
Server s=new Server();
HandlerWrapper a = new HandlerWrapper();
HandlerWrapper b = new HandlerWrapper();
HandlerWrapper c = new HandlerWrapper();
a.setServer(s);
b.setHandler(c);
a.setHandler(b);
assertThat(b.getServer(),equalTo(s));
assertThat(c.getServer(),equalTo(s));
}
@Test
public void testWrapperThisLoop()
{
HandlerWrapper a = new HandlerWrapper();
try
{
a.setHandler(a);
fail();
}
catch(IllegalStateException e)
{
assertThat(e.getMessage(),containsString("loop"));
}
}
@Test
public void testWrapperSimpleLoop()
{
HandlerWrapper a = new HandlerWrapper();
HandlerWrapper b = new HandlerWrapper();
a.setHandler(b);
try
{
b.setHandler(a);
fail();
}
catch(IllegalStateException e)
{
assertThat(e.getMessage(),containsString("loop"));
}
}
@Test
public void testWrapperDeepLoop()
{
HandlerWrapper a = new HandlerWrapper();
HandlerWrapper b = new HandlerWrapper();
HandlerWrapper c = new HandlerWrapper();
a.setHandler(b);
b.setHandler(c);
try
{
c.setHandler(a);
fail();
}
catch(IllegalStateException e)
{
assertThat(e.getMessage(),containsString("loop"));
}
}
@Test
public void testWrapperChainLoop()
{
HandlerWrapper a = new HandlerWrapper();
HandlerWrapper b = new HandlerWrapper();
HandlerWrapper c = new HandlerWrapper();
a.setHandler(b);
c.setHandler(a);
try
{
b.setHandler(c);
fail();
}
catch(IllegalStateException e)
{
assertThat(e.getMessage(),containsString("loop"));
}
}
@Test
public void testCollectionSetServer()
{
Server s=new Server();
HandlerCollection a = new HandlerCollection();
HandlerCollection b = new HandlerCollection();
HandlerCollection b1 = new HandlerCollection();
HandlerCollection b2 = new HandlerCollection();
HandlerCollection c = new HandlerCollection();
HandlerCollection c1 = new HandlerCollection();
HandlerCollection c2 = new HandlerCollection();
a.addHandler(b);
a.addHandler(c);
b.setHandlers(new Handler[]{b1,b2});
c.setHandlers(new Handler[]{c1,c2});
a.setServer(s);
assertThat(b.getServer(),equalTo(s));
assertThat(c.getServer(),equalTo(s));
assertThat(b1.getServer(),equalTo(s));
assertThat(b2.getServer(),equalTo(s));
assertThat(c1.getServer(),equalTo(s));
assertThat(c2.getServer(),equalTo(s));
}
@Test
public void testCollectionServerSet()
{
Server s=new Server();
HandlerCollection a = new HandlerCollection();
HandlerCollection b = new HandlerCollection();
HandlerCollection b1 = new HandlerCollection();
HandlerCollection b2 = new HandlerCollection();
HandlerCollection c = new HandlerCollection();
HandlerCollection c1 = new HandlerCollection();
HandlerCollection c2 = new HandlerCollection();
a.setServer(s);
a.addHandler(b);
a.addHandler(c);
b.setHandlers(new Handler[]{b1,b2});
c.setHandlers(new Handler[]{c1,c2});
assertThat(b.getServer(),equalTo(s));
assertThat(c.getServer(),equalTo(s));
assertThat(b1.getServer(),equalTo(s));
assertThat(b2.getServer(),equalTo(s));
assertThat(c1.getServer(),equalTo(s));
assertThat(c2.getServer(),equalTo(s));
}
@Test
public void testCollectionThisLoop()
{
HandlerCollection a = new HandlerCollection();
try
{
a.addHandler(a);
fail();
}
catch(IllegalStateException e)
{
assertThat(e.getMessage(),containsString("loop"));
}
}
@Test
public void testCollectionDeepLoop()
{
HandlerCollection a = new HandlerCollection();
HandlerCollection b = new HandlerCollection();
HandlerCollection b1 = new HandlerCollection();
HandlerCollection b2 = new HandlerCollection();
HandlerCollection c = new HandlerCollection();
HandlerCollection c1 = new HandlerCollection();
HandlerCollection c2 = new HandlerCollection();
a.addHandler(b);
a.addHandler(c);
b.setHandlers(new Handler[]{b1,b2});
c.setHandlers(new Handler[]{c1,c2});
try
{
b2.addHandler(a);
fail();
}
catch(IllegalStateException e)
{
assertThat(e.getMessage(),containsString("loop"));
}
}
@Test
public void testCollectionChainLoop()
{
HandlerCollection a = new HandlerCollection();
HandlerCollection b = new HandlerCollection();
HandlerCollection b1 = new HandlerCollection();
HandlerCollection b2 = new HandlerCollection();
HandlerCollection c = new HandlerCollection();
HandlerCollection c1 = new HandlerCollection();
HandlerCollection c2 = new HandlerCollection();
a.addHandler(c);
b.setHandlers(new Handler[]{b1,b2});
c.setHandlers(new Handler[]{c1,c2});
b2.addHandler(a);
try
{
a.addHandler(b);
fail();
}
catch(IllegalStateException e)
{
assertThat(e.getMessage(),containsString("loop"));
}
}
@Test
public void testInsertWrapperTail()
{
HandlerWrapper a = new HandlerWrapper();
HandlerWrapper b = new HandlerWrapper();
a.insertHandler(b);
assertThat(a.getHandler(),equalTo(b));
assertThat(b.getHandler(),nullValue());
}
@Test
public void testInsertWrapper()
{
HandlerWrapper a = new HandlerWrapper();
HandlerWrapper b = new HandlerWrapper();
HandlerWrapper c = new HandlerWrapper();
a.insertHandler(c);
a.insertHandler(b);
assertThat(a.getHandler(),equalTo(b));
assertThat(b.getHandler(),equalTo(c));
assertThat(c.getHandler(),nullValue());
}
@Test
public void testInsertWrapperChain()
{
HandlerWrapper a = new HandlerWrapper();
HandlerWrapper b = new HandlerWrapper();
HandlerWrapper c = new HandlerWrapper();
HandlerWrapper d = new HandlerWrapper();
a.insertHandler(d);
b.insertHandler(c);
a.insertHandler(b);
assertThat(a.getHandler(),equalTo(b));
assertThat(b.getHandler(),equalTo(c));
assertThat(c.getHandler(),equalTo(d));
assertThat(d.getHandler(),nullValue());
}
@Test
public void testInsertWrapperBadChain()
{
HandlerWrapper a = new HandlerWrapper();
HandlerWrapper b = new HandlerWrapper();
HandlerWrapper c = new HandlerWrapper();
HandlerWrapper d = new HandlerWrapper();
a.insertHandler(d);
b.insertHandler(c);
c.setHandler(new AbstractHandler()
{
@Override
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
}
});
try
{
a.insertHandler(b);
fail();
}
catch(IllegalArgumentException e)
{
assertThat(e.getMessage(),containsString("bad tail"));
}
}
}

View File

@ -66,6 +66,8 @@ import org.eclipse.jetty.util.DeprecationWarning;
import org.eclipse.jetty.util.annotation.ManagedAttribute; import org.eclipse.jetty.util.annotation.ManagedAttribute;
import org.eclipse.jetty.util.annotation.ManagedObject; import org.eclipse.jetty.util.annotation.ManagedObject;
import org.eclipse.jetty.util.component.LifeCycle; import org.eclipse.jetty.util.component.LifeCycle;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
/** /**
* Servlet Context. * Servlet Context.
@ -83,6 +85,8 @@ import org.eclipse.jetty.util.component.LifeCycle;
@ManagedObject("Servlet Context Handler") @ManagedObject("Servlet Context Handler")
public class ServletContextHandler extends ContextHandler public class ServletContextHandler extends ContextHandler
{ {
private static final Logger LOG = Log.getLogger(ServletContextHandler.class);
public final static int SESSIONS=1; public final static int SESSIONS=1;
public final static int SECURITY=2; public final static int SECURITY=2;
public final static int GZIP=4; public final static int GZIP=4;
@ -169,7 +173,21 @@ public class ServletContextHandler extends ContextHandler
if (errorHandler!=null) if (errorHandler!=null)
setErrorHandler(errorHandler); setErrorHandler(errorHandler);
}
@Override
public void setHandler(Handler handler)
{
LOG.warn("ServletContextHandler.setHandler should not be called directly. Use insertHandler or setSessionHandler etc.");
super.setHandler(handler);
}
private void doSetHandler(HandlerWrapper wrapper, Handler handler)
{
if (wrapper==this)
super.setHandler(handler);
else
wrapper.setHandler(handler);
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
@ -189,12 +207,7 @@ public class ServletContextHandler extends ContextHandler
handler=(HandlerWrapper)handler.getHandler(); handler=(HandlerWrapper)handler.getHandler();
if (handler.getHandler()!=_sessionHandler) if (handler.getHandler()!=_sessionHandler)
{ doSetHandler(handler,_sessionHandler);
if (handler== this)
super.setHandler(_sessionHandler);
else
handler.setHandler(_sessionHandler);
}
handler=_sessionHandler; handler=_sessionHandler;
} }
@ -208,12 +221,7 @@ public class ServletContextHandler extends ContextHandler
handler=(HandlerWrapper)handler.getHandler(); handler=(HandlerWrapper)handler.getHandler();
if (handler.getHandler()!=_securityHandler) if (handler.getHandler()!=_securityHandler)
{ doSetHandler(handler,_securityHandler);
if (handler== this)
super.setHandler(_securityHandler);
else
handler.setHandler(_securityHandler);
}
handler=_securityHandler; handler=_securityHandler;
} }
@ -226,12 +234,7 @@ public class ServletContextHandler extends ContextHandler
handler=(HandlerWrapper)handler.getHandler(); handler=(HandlerWrapper)handler.getHandler();
if (handler.getHandler()!=_gzipHandler) if (handler.getHandler()!=_gzipHandler)
{ doSetHandler(handler,_gzipHandler);
if (handler== this)
super.setHandler(_gzipHandler);
else
handler.setHandler(_gzipHandler);
}
handler=_gzipHandler; handler=_gzipHandler;
} }
@ -244,12 +247,7 @@ public class ServletContextHandler extends ContextHandler
handler=(HandlerWrapper)handler.getHandler(); handler=(HandlerWrapper)handler.getHandler();
if (handler.getHandler()!=_servletHandler) if (handler.getHandler()!=_servletHandler)
{ doSetHandler(handler,_servletHandler);
if (handler== this)
super.setHandler(_servletHandler);
else
handler.setHandler(_servletHandler);
}
handler=_servletHandler; handler=_servletHandler;
} }
@ -554,7 +552,7 @@ public class ServletContextHandler extends ContextHandler
{ {
if (wrapper.getHandler()==handler) if (wrapper.getHandler()==handler)
{ {
wrapper.setHandler(replace); doSetHandler(wrapper,replace);
return true; return true;
} }
@ -664,20 +662,38 @@ public class ServletContextHandler extends ContextHandler
*/ */
public void insertHandler(HandlerWrapper handler) public void insertHandler(HandlerWrapper handler)
{ {
HandlerWrapper h=this; if (handler instanceof SessionHandler)
setSessionHandler((SessionHandler)handler);
// Skip any injected handlers else if (handler instanceof SecurityHandler)
while (h.getHandler() instanceof HandlerWrapper) setSecurityHandler((SecurityHandler)handler);
else if (handler instanceof GzipHandler)
setGzipHandler((GzipHandler)handler);
else if (handler instanceof ServletHandler)
setServletHandler((ServletHandler)handler);
else
{ {
HandlerWrapper wrapper = (HandlerWrapper)h.getHandler(); HandlerWrapper tail = handler;
if (wrapper instanceof SessionHandler || while(tail.getHandler() instanceof HandlerWrapper)
wrapper instanceof SecurityHandler || tail=(HandlerWrapper)tail.getHandler();
wrapper instanceof ServletHandler) if (tail.getHandler()!=null)
break; throw new IllegalArgumentException("bad tail of inserted wrapper chain");
h=wrapper;
// Skip any injected handlers
HandlerWrapper h=this;
while (h.getHandler() instanceof HandlerWrapper)
{
HandlerWrapper wrapper = (HandlerWrapper)h.getHandler();
if (wrapper instanceof SessionHandler ||
wrapper instanceof SecurityHandler ||
wrapper instanceof ServletHandler)
break;
h=wrapper;
}
Handler next=h.getHandler();
doSetHandler(h,handler);
doSetHandler(tail,next);
} }
h.setHandler(handler);
relinkHandlers(); relinkHandlers();
} }

View File

@ -81,7 +81,6 @@ public class GzipHandlerTest
_server.setHandler(gzipHandler); _server.setHandler(gzipHandler);
gzipHandler.setHandler(context); gzipHandler.setHandler(context);
context.setHandler(servlets);
servlets.addServletWithMapping(TestServlet.class,"/content"); servlets.addServletWithMapping(TestServlet.class,"/content");
servlets.addServletWithMapping(ForwardServlet.class,"/forward"); servlets.addServletWithMapping(ForwardServlet.class,"/forward");
servlets.addServletWithMapping(IncludeServlet.class,"/include"); servlets.addServletWithMapping(IncludeServlet.class,"/include");
@ -91,7 +90,6 @@ public class GzipHandlerTest
public static class TestServlet extends HttpServlet public static class TestServlet extends HttpServlet
{ {
@Override @Override
protected void doGet(HttpServletRequest req, HttpServletResponse response) throws ServletException, IOException protected void doGet(HttpServletRequest req, HttpServletResponse response) throws ServletException, IOException
{ {

View File

@ -26,6 +26,7 @@ import java.util.EnumSet;
import javax.servlet.DispatcherType; import javax.servlet.DispatcherType;
import org.eclipse.jetty.server.handler.HandlerWrapper;
import org.eclipse.jetty.servlet.BaseHolder.Source; import org.eclipse.jetty.servlet.BaseHolder.Source;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
@ -428,5 +429,4 @@ public class ServletHandlerTest
} }
} }

View File

@ -89,8 +89,7 @@ public class IncludedGzipTest
tester.getContext().addServlet(org.eclipse.jetty.servlet.DefaultServlet.class, "/"); tester.getContext().addServlet(org.eclipse.jetty.servlet.DefaultServlet.class, "/");
GzipHandler gzipHandler = new GzipHandler(); GzipHandler gzipHandler = new GzipHandler();
gzipHandler.setHandler(tester.getContext().getHandler()); tester.getContext().insertHandler(gzipHandler);
tester.getContext().setHandler(gzipHandler);
tester.start(); tester.start();
} }

View File

@ -41,8 +41,8 @@
<New id="defcontext" class="org.eclipse.jetty.server.handler.ContextHandler"> <New id="defcontext" class="org.eclipse.jetty.server.handler.ContextHandler">
<Set name="contextPath">/tests</Set> <Set name="contextPath">/tests</Set>
<Set name="ResourceBase"><Property name="test.docroot.base"/>/default</Set> <Set name="ResourceBase"><Property name="test.docroot.base"/>/default</Set>
<Set name="Handler"><New id="reshandler" class="org.eclipse.jetty.server.handler.ResourceHandler"/></Set> <Set name="Handler"><New id="reshandler" class="org.eclipse.jetty.server.handler.ResourceHandler"/></Set>
<Set name="DisplayName">default</Set> <Set name="DisplayName">default</Set>
</New> </New>
</Item> </Item>
</Array> </Array>

View File

@ -102,12 +102,10 @@
</Arg> </Arg>
</Call> </Call>
<!-- =========================================================== -->
<!-- extra options -->
<!-- =========================================================== --> <!-- =========================================================== -->
<!-- extra options --> <Set name="stopAtShutdown">true</Set>
<!-- =========================================================== --> <Set name="stopTimeout">1000</Set>
<Set name="stopAtShutdown">true</Set>
<Set name="stopTimeout">1000</Set>
</Configure> </Configure>

View File

@ -2,53 +2,51 @@
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd"> <!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
<Configure id="Server" class="org.eclipse.jetty.server.Server"> <Configure id="Server" class="org.eclipse.jetty.server.Server">
<!-- =========================================================== --> <!-- =========================================================== -->
<!-- Configure Rewrite Handler --> <!-- Configure Rewrite Handler -->
<!-- =========================================================== --> <!-- =========================================================== -->
<Get id="oldhandler" name="handler"/>
<Set name="handler"> <Call name="insertHandler">
<Arg>
<New id="Rewrite" class="org.eclipse.jetty.rewrite.handler.RewriteHandler"> <New id="Rewrite" class="org.eclipse.jetty.rewrite.handler.RewriteHandler">
<Set name="handler"><Ref refid="oldhandler"/></Set>
<Set name="rewriteRequestURI">true</Set> <Set name="rewriteRequestURI">true</Set>
<Set name="rewritePathInfo">false</Set> <Set name="rewritePathInfo">false</Set>
<Set name="originalPathAttribute">requestedPath</Set> <Set name="originalPathAttribute">requestedPath</Set>
<Set name="rules"> <Set name="rules">
<Array type="org.eclipse.jetty.rewrite.handler.Rule"> <Array type="org.eclipse.jetty.rewrite.handler.Rule">
<!-- add a response rule --> <!-- add a response rule -->
<!-- <!--
<Item> <Item>
<New id="response" class="org.eclipse.jetty.rewrite.handler.ResponsePatternRule"> <New id="response" class="org.eclipse.jetty.rewrite.handler.ResponsePatternRule">
<Set name="pattern">/rewrite/session/</Set> <Set name="pattern">/rewrite/session/</Set>
<Set name="code">401</Set> <Set name="code">401</Set>
<Set name="reason">Setting error code 401</Set> <Set name="reason">Setting error code 401</Set>
</New> </New>
</Item> </Item>
--> -->
<!-- add a simple redirect --> <!-- add a simple redirect -->
<!-- <!--
<Item> <Item>
<New id="redirect" class="org.eclipse.jetty.rewrite.handler.RedirectPatternRule"> <New id="redirect" class="org.eclipse.jetty.rewrite.handler.RedirectPatternRule">
<Set name="pattern">/redirect/*</Set> <Set name="pattern">/redirect/*</Set>
<Set name="location">/tests/</Set> <Set name="location">/tests/</Set>
</New> </New>
</Item> </Item>
--> -->
<!-- add a regex rewrite redirect --> <!-- add a regex rewrite redirect -->
<Item> <Item>
<New id="redirect" class="org.eclipse.jetty.rewrite.handler.RedirectRegexRule"> <New id="redirect" class="org.eclipse.jetty.rewrite.handler.RedirectRegexRule">
<Set name="regex">/redirect/(.*)</Set> <Set name="regex">/redirect/(.*)</Set>
<Set name="replacement">/tests/$1</Set> <Set name="replacement">/tests/$1</Set>
</New> </New>
</Item> </Item>
</Array> </Array>
</Set> </Set>
</New> </New>
</Set> </Arg>
</Call>
</Configure> </Configure>

View File

@ -13,7 +13,6 @@ detected.
<Configure class="org.eclipse.jetty.webapp.WebAppContext"> <Configure class="org.eclipse.jetty.webapp.WebAppContext">
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<!-- Required minimal context configuration : --> <!-- Required minimal context configuration : -->
<!-- + contextPath --> <!-- + contextPath -->