Issue #5378 - guard against concurrent requests lazily initializing the filter
Signed-off-by: Lachlan Roberts <lachlan@webtide.com>
This commit is contained in:
parent
2a4d672fc1
commit
7003b3c42e
|
@ -21,6 +21,7 @@ package org.eclipse.jetty.websocket.util.server;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
|
import java.util.Objects;
|
||||||
import javax.servlet.DispatcherType;
|
import javax.servlet.DispatcherType;
|
||||||
import javax.servlet.Filter;
|
import javax.servlet.Filter;
|
||||||
import javax.servlet.FilterChain;
|
import javax.servlet.FilterChain;
|
||||||
|
@ -37,6 +38,7 @@ import org.eclipse.jetty.servlet.FilterHolder;
|
||||||
import org.eclipse.jetty.servlet.ServletHandler;
|
import org.eclipse.jetty.servlet.ServletHandler;
|
||||||
import org.eclipse.jetty.util.annotation.ManagedObject;
|
import org.eclipse.jetty.util.annotation.ManagedObject;
|
||||||
import org.eclipse.jetty.util.component.Dumpable;
|
import org.eclipse.jetty.util.component.Dumpable;
|
||||||
|
import org.eclipse.jetty.util.thread.AutoLock;
|
||||||
import org.eclipse.jetty.websocket.core.Configuration;
|
import org.eclipse.jetty.websocket.core.Configuration;
|
||||||
import org.eclipse.jetty.websocket.core.server.WebSocketServerComponents;
|
import org.eclipse.jetty.websocket.core.server.WebSocketServerComponents;
|
||||||
import org.eclipse.jetty.websocket.util.server.internal.WebSocketMapping;
|
import org.eclipse.jetty.websocket.util.server.internal.WebSocketMapping;
|
||||||
|
@ -74,10 +76,12 @@ import org.slf4j.LoggerFactory;
|
||||||
public class WebSocketUpgradeFilter implements Filter, Dumpable
|
public class WebSocketUpgradeFilter implements Filter, Dumpable
|
||||||
{
|
{
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(WebSocketUpgradeFilter.class);
|
private static final Logger LOG = LoggerFactory.getLogger(WebSocketUpgradeFilter.class);
|
||||||
|
private static final AutoLock LOCK = new AutoLock();
|
||||||
|
|
||||||
private static FilterHolder getFilter(ServletContext servletContext)
|
private static FilterHolder getFilter(ServletContext servletContext)
|
||||||
{
|
{
|
||||||
ServletHandler servletHandler = ContextHandler.getContextHandler(servletContext).getChildHandlerByClass(ServletHandler.class);
|
ContextHandler contextHandler = Objects.requireNonNull(ContextHandler.getContextHandler(servletContext));
|
||||||
|
ServletHandler servletHandler = contextHandler.getChildHandlerByClass(ServletHandler.class);
|
||||||
|
|
||||||
for (FilterHolder holder : servletHandler.getFilters())
|
for (FilterHolder holder : servletHandler.getFilters())
|
||||||
{
|
{
|
||||||
|
@ -104,6 +108,9 @@ public class WebSocketUpgradeFilter implements Filter, Dumpable
|
||||||
* @return the configured default {@link WebSocketUpgradeFilter} instance
|
* @return the configured default {@link WebSocketUpgradeFilter} instance
|
||||||
*/
|
*/
|
||||||
public static FilterHolder ensureFilter(ServletContext servletContext)
|
public static FilterHolder ensureFilter(ServletContext servletContext)
|
||||||
|
{
|
||||||
|
// Lock in case two concurrent requests are initializing the filter lazily.
|
||||||
|
try (AutoLock l = LOCK.lock())
|
||||||
{
|
{
|
||||||
FilterHolder existingFilter = WebSocketUpgradeFilter.getFilter(servletContext);
|
FilterHolder existingFilter = WebSocketUpgradeFilter.getFilter(servletContext);
|
||||||
if (existingFilter != null)
|
if (existingFilter != null)
|
||||||
|
@ -116,12 +123,14 @@ public class WebSocketUpgradeFilter implements Filter, Dumpable
|
||||||
holder.setInitParameter(MAPPING_ATTRIBUTE_INIT_PARAM, WebSocketMapping.DEFAULT_KEY);
|
holder.setInitParameter(MAPPING_ATTRIBUTE_INIT_PARAM, WebSocketMapping.DEFAULT_KEY);
|
||||||
|
|
||||||
holder.setAsyncSupported(true);
|
holder.setAsyncSupported(true);
|
||||||
ServletHandler servletHandler = ContextHandler.getContextHandler(servletContext).getChildHandlerByClass(ServletHandler.class);
|
ContextHandler contextHandler = Objects.requireNonNull(ContextHandler.getContextHandler(servletContext));
|
||||||
|
ServletHandler servletHandler = contextHandler.getChildHandlerByClass(ServletHandler.class);
|
||||||
servletHandler.addFilterWithMapping(holder, pathSpec, EnumSet.of(DispatcherType.REQUEST));
|
servletHandler.addFilterWithMapping(holder, pathSpec, EnumSet.of(DispatcherType.REQUEST));
|
||||||
if (LOG.isDebugEnabled())
|
if (LOG.isDebugEnabled())
|
||||||
LOG.debug("Adding {} mapped to {} in {}", holder, pathSpec, servletContext);
|
LOG.debug("Adding {} mapped to {} in {}", holder, pathSpec, servletContext);
|
||||||
return holder;
|
return holder;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static final String MAPPING_ATTRIBUTE_INIT_PARAM = "org.eclipse.jetty.websocket.util.server.internal.WebSocketMapping.key";
|
public static final String MAPPING_ATTRIBUTE_INIT_PARAM = "org.eclipse.jetty.websocket.util.server.internal.WebSocketMapping.key";
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue