From 6a83a261e10d7522b9689b63e3eed8346442d579 Mon Sep 17 00:00:00 2001 From: Lachlan Roberts Date: Wed, 18 Nov 2020 21:27:25 +1100 Subject: [PATCH] Always add the default WebSocketUpgradeFilter as the first filter. Signed-off-by: Lachlan Roberts --- .../eclipse/jetty/servlet/ServletHandler.java | 17 +++++++++++ .../tests/JettyWebSocketFilterTest.java | 8 +++--- .../websocket/tests/JettyWebSocketWebApp.java | 18 ++++++++++++ .../src/test/resources/wsuf-ordering1.xml | 8 +++--- .../src/test/resources/wsuf-ordering2.xml | 28 +++++++++---------- .../util/server/WebSocketUpgradeFilter.java | 22 +++++++++++---- 6 files changed, 73 insertions(+), 28 deletions(-) diff --git a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHandler.java b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHandler.java index 04e1ffc7d1e..d1e635d4da9 100644 --- a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHandler.java +++ b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHandler.java @@ -1084,6 +1084,23 @@ public class ServletHandler extends ScopedHandler } } + /** + * Convenience method to add a preconstructed FilterHolder + * + * @param filter the filter holder + */ + public void prependFilter(FilterHolder filter) + { + if (filter == null) + return; + + try (AutoLock l = lock()) + { + if (!containsFilterHolder(filter)) + setFilters(ArrayUtil.prependToArray(filter, getFilters(), FilterHolder.class)); + } + } + /** * Convenience method to add a preconstructed FilterMapping * diff --git a/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/JettyWebSocketFilterTest.java b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/JettyWebSocketFilterTest.java index 3d102e9ede0..a11772e67e1 100644 --- a/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/JettyWebSocketFilterTest.java +++ b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/JettyWebSocketFilterTest.java @@ -311,7 +311,7 @@ public class JettyWebSocketFilterTest @Test public void testDefaultWebSocketUpgradeFilterOrdering() throws Exception { - String timeoutFromAltFilter = "5999"; + String defaultIdleTimeout = Long.toString(WebSocketConstants.DEFAULT_IDLE_TIMEOUT.toMillis()); JettyWebSocketWebApp webApp = new JettyWebSocketWebApp("wsuf-ordering1"); Path webXml = MavenTestingUtils.getTestResourcePath("wsuf-ordering1.xml"); webApp.copyWebXml(webXml); @@ -339,13 +339,13 @@ public class JettyWebSocketFilterTest } assertTrue(socket.closeLatch.await(5, TimeUnit.SECONDS)); assertThat(socket.textMessages.poll(), is("hello world")); - assertThat(socket.textMessages.poll(), is(timeoutFromAltFilter)); + assertThat(socket.textMessages.poll(), is(defaultIdleTimeout)); } @Test public void testWebSocketUpgradeFilterOrdering() throws Exception { - String defaultIdleTimeout = Long.toString(WebSocketConstants.DEFAULT_IDLE_TIMEOUT.toMillis()); + String timeoutFromAltFilter = "5999"; JettyWebSocketWebApp webApp = new JettyWebSocketWebApp("wsuf-ordering2"); Path webXml = MavenTestingUtils.getTestResourcePath("wsuf-ordering2.xml"); webApp.copyWebXml(webXml); @@ -373,7 +373,7 @@ public class JettyWebSocketFilterTest } assertTrue(socket.closeLatch.await(5, TimeUnit.SECONDS)); assertThat(socket.textMessages.poll(), is("hello world")); - assertThat(socket.textMessages.poll(), is(defaultIdleTimeout)); + assertThat(socket.textMessages.poll(), is(timeoutFromAltFilter)); } @WebListener diff --git a/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/JettyWebSocketWebApp.java b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/JettyWebSocketWebApp.java index c8845602201..cbfc6cd119f 100644 --- a/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/JettyWebSocketWebApp.java +++ b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/JettyWebSocketWebApp.java @@ -1,3 +1,21 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + package org.eclipse.jetty.websocket.tests; import java.io.File; diff --git a/jetty-websocket/websocket-jetty-tests/src/test/resources/wsuf-ordering1.xml b/jetty-websocket/websocket-jetty-tests/src/test/resources/wsuf-ordering1.xml index d5ef3f972e7..b93d673a43b 100644 --- a/jetty-websocket/websocket-jetty-tests/src/test/resources/wsuf-ordering1.xml +++ b/jetty-websocket/websocket-jetty-tests/src/test/resources/wsuf-ordering1.xml @@ -2,11 +2,11 @@ + xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" + metadata-complete="false" + version="4.0"> - + wsuf-alt org.eclipse.jetty.websocket.util.server.WebSocketUpgradeFilter diff --git a/jetty-websocket/websocket-jetty-tests/src/test/resources/wsuf-ordering2.xml b/jetty-websocket/websocket-jetty-tests/src/test/resources/wsuf-ordering2.xml index ca19ae86c7d..a733873a671 100644 --- a/jetty-websocket/websocket-jetty-tests/src/test/resources/wsuf-ordering2.xml +++ b/jetty-websocket/websocket-jetty-tests/src/test/resources/wsuf-ordering2.xml @@ -2,21 +2,11 @@ + xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" + metadata-complete="false" + version="4.0"> - - - org.eclipse.jetty.websocket.util.server.WebSocketUpgradeFilter - org.eclipse.jetty.websocket.util.server.WebSocketUpgradeFilter - - - org.eclipse.jetty.websocket.util.server.WebSocketUpgradeFilter - /* - - - + wsuf-alt org.eclipse.jetty.websocket.util.server.WebSocketUpgradeFilter @@ -29,4 +19,14 @@ wsuf-alt /* + + + + org.eclipse.jetty.websocket.util.server.WebSocketUpgradeFilter + org.eclipse.jetty.websocket.util.server.WebSocketUpgradeFilter + + + org.eclipse.jetty.websocket.util.server.WebSocketUpgradeFilter + /* + diff --git a/jetty-websocket/websocket-util-server/src/main/java/org/eclipse/jetty/websocket/util/server/WebSocketUpgradeFilter.java b/jetty-websocket/websocket-util-server/src/main/java/org/eclipse/jetty/websocket/util/server/WebSocketUpgradeFilter.java index dd45688a16d..546c082171a 100644 --- a/jetty-websocket/websocket-util-server/src/main/java/org/eclipse/jetty/websocket/util/server/WebSocketUpgradeFilter.java +++ b/jetty-websocket/websocket-util-server/src/main/java/org/eclipse/jetty/websocket/util/server/WebSocketUpgradeFilter.java @@ -35,6 +35,7 @@ import javax.servlet.http.HttpServletResponse; import org.eclipse.jetty.server.handler.ContextHandler; import org.eclipse.jetty.servlet.FilterHolder; +import org.eclipse.jetty.servlet.FilterMapping; import org.eclipse.jetty.servlet.ServletHandler; import org.eclipse.jetty.util.annotation.ManagedObject; import org.eclipse.jetty.util.component.Dumpable; @@ -78,12 +79,12 @@ public class WebSocketUpgradeFilter implements Filter, Dumpable private static final AutoLock LOCK = new AutoLock(); /** - * Return any {@link WebSocketUpgradeFilter} already present on the {@link ServletContext}. + * Return the default {@link WebSocketUpgradeFilter} if present on the {@link ServletContext}. * * @param servletContext the {@link ServletContext} to use. * @return the configured default {@link WebSocketUpgradeFilter} instance. */ - private static FilterHolder getFilter(ServletContext servletContext) + public static FilterHolder getFilter(ServletContext servletContext) { ContextHandler contextHandler = Objects.requireNonNull(ContextHandler.getContextHandler(servletContext)); ServletHandler servletHandler = contextHandler.getChildHandlerByClass(ServletHandler.class); @@ -111,14 +112,23 @@ public class WebSocketUpgradeFilter implements Filter, Dumpable if (existingFilter != null) return existingFilter; + ContextHandler contextHandler = Objects.requireNonNull(ContextHandler.getContextHandler(servletContext)); + ServletHandler servletHandler = contextHandler.getChildHandlerByClass(ServletHandler.class); + final String pathSpec = "/*"; FilterHolder holder = new FilterHolder(new WebSocketUpgradeFilter()); holder.setName(WebSocketUpgradeFilter.class.getName()); - holder.setAsyncSupported(true); - ContextHandler contextHandler = Objects.requireNonNull(ContextHandler.getContextHandler(servletContext)); - ServletHandler servletHandler = contextHandler.getChildHandlerByClass(ServletHandler.class); - servletHandler.addFilterWithMapping(holder, pathSpec, EnumSet.of(DispatcherType.REQUEST)); + + FilterMapping mapping = new FilterMapping(); + mapping.setFilterName(holder.getName()); + mapping.setPathSpec(pathSpec); + mapping.setDispatcherTypes(EnumSet.of(DispatcherType.REQUEST)); + + // Add the default WebSocketUpgradeFilter as the first filter in the list. + servletHandler.prependFilter(holder); + servletHandler.prependFilterMapping(mapping); + if (LOG.isDebugEnabled()) LOG.debug("Adding {} mapped to {} in {}", holder, pathSpec, servletContext); return holder;