do not set WebSocketMapping in WSUpgradeFilter if already set

the WSUpgradeFilter now has to be registered at "/" or "/*"

Signed-off-by: Lachlan Roberts <lachlan@webtide.com>
This commit is contained in:
Lachlan Roberts 2019-01-22 18:17:33 +11:00
parent 3c2f728574
commit 15c6f5250d
3 changed files with 62 additions and 20 deletions

View File

@ -37,6 +37,7 @@ import org.eclipse.jetty.util.TypeUtil;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.thread.ThreadClassLoaderScope;
import org.eclipse.jetty.websocket.core.WebSocketResources;
import org.eclipse.jetty.websocket.servlet.WebSocketMapping;
import org.eclipse.jetty.websocket.servlet.WebSocketUpgradeFilter;
@ -81,14 +82,20 @@ public class JavaxWebSocketServletContainerInitializer implements ServletContain
return null;
}
public static JavaxWebSocketServerContainer configureContext(ServletContextHandler context)
throws ServletException
public static JavaxWebSocketServerContainer configureContext(ServletContextHandler context) throws ServletException
{
WebSocketMapping mapping = WebSocketMapping.ensureMapping(context.getServletContext());
FilterHolder upgradeFilter = WebSocketUpgradeFilter.ensureFilter(context.getServletContext());
WebSocketResources resources = WebSocketResources.ensureWebSocketResources(context.getServletContext());
FilterHolder filterHolder = WebSocketUpgradeFilter.ensureFilter(context.getServletContext());
WebSocketUpgradeFilter upgradeFilter = ((WebSocketUpgradeFilter)filterHolder.getFilter());
if (upgradeFilter.getMapping() == null)
upgradeFilter.setMapping(new WebSocketMapping(resources));
JavaxWebSocketServerContainer container = JavaxWebSocketServerContainer.ensureContainer(context.getServletContext());
if (LOG.isDebugEnabled())
LOG.debug("configureContext {} {} {}",mapping,upgradeFilter,container);
LOG.debug("configureContext {} {} {} {}", upgradeFilter.getMapping(), resources, upgradeFilter, container);
return container;
}

View File

@ -29,6 +29,7 @@ import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.util.component.AbstractLifeCycle;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.websocket.core.WebSocketResources;
/**
* ServletContext configuration for Jetty Native WebSockets API.
@ -72,9 +73,10 @@ public class JettyWebSocketServletContainerInitializer implements ServletContain
@Override
public void onStartup(Set<Class<?>> c, ServletContext servletContext) throws ServletException
{
WebSocketResources resources = WebSocketResources.ensureWebSocketResources(servletContext);
JettyServerFrameHandlerFactory factory = JettyServerFrameHandlerFactory.ensureFactory(servletContext);
if (LOG.isDebugEnabled())
LOG.debug("onStartup {}", factory);
LOG.debug("onStartup {} {}", resources, factory);
}
}

View File

@ -33,9 +33,9 @@ import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.http.pathmap.PathSpec;
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.ManagedAttribute;
import org.eclipse.jetty.util.annotation.ManagedObject;
@ -43,8 +43,6 @@ import org.eclipse.jetty.util.component.Dumpable;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.websocket.core.FrameHandler;
import org.eclipse.jetty.websocket.core.server.Handshaker;
import org.eclipse.jetty.websocket.core.server.WebSocketNegotiator;
/**
* Inline Servlet Filter to capture WebSocket upgrade requests.
@ -78,25 +76,57 @@ public class WebSocketUpgradeFilter implements Filter, Dumpable
{
private static final Logger LOG = Log.getLogger(WebSocketUpgradeFilter.class);
public static FilterHolder ensureFilter(ServletContext servletContext) throws ServletException
public static FilterHolder getFilter(ServletContext servletContext)
{
ServletHandler servletHandler = ContextHandler.getContextHandler(servletContext).getChildHandlerByClass(ServletHandler.class);
for (FilterHolder holder : servletHandler.getFilters())
{
if (holder.getClassName().equals(WebSocketUpgradeFilter.class.getName()))
return holder;
if (holder.getHeldClass()!=null && WebSocketUpgradeFilter.class.isAssignableFrom(holder.getHeldClass()))
return holder;
if (holder.getClassName().equals(WebSocketUpgradeFilter.class.getName()) ||
(holder.getHeldClass() != null && WebSocketUpgradeFilter.class.isAssignableFrom(holder.getHeldClass())))
{
for (FilterMapping mapping : servletHandler.getFilterMappings())
{
if (mapping.getFilterName().equals(holder.getName()))
{
for (String path : mapping.getPathSpecs())
{
if (path.equals("/") || path.equals("/*"))
return holder;
}
}
}
}
}
return null;
}
public static WebSocketMapping getMapping(ServletContext servletContext)
{
FilterHolder existingFilter = WebSocketUpgradeFilter.getFilter(servletContext);
if (existingFilter == null)
return null;
return ((WebSocketUpgradeFilter)existingFilter.getFilter()).getMapping();
}
public static FilterHolder ensureFilter(ServletContext servletContext)
{
FilterHolder existingFilter = WebSocketUpgradeFilter.getFilter(servletContext);
if (existingFilter != null)
return existingFilter;
String name = "WebSocketUpgradeFilter";
// TODO this should be registered at pathSpec "/" (NOTE: also remove from getFilter)
String pathSpec = "/*";
EnumSet<DispatcherType> dispatcherTypes = EnumSet.of(DispatcherType.REQUEST);
FilterHolder holder = new FilterHolder(new WebSocketUpgradeFilter());
holder.setName(name);
holder.setAsyncSupported(true);
ServletHandler servletHandler = ContextHandler.getContextHandler(servletContext).getChildHandlerByClass(ServletHandler.class);
servletHandler.addFilterWithMapping(holder, pathSpec, dispatcherTypes);
if (LOG.isDebugEnabled())
LOG.debug("Adding {} mapped to {} in {}", holder, pathSpec, servletContext);
@ -106,10 +136,6 @@ public class WebSocketUpgradeFilter implements Filter, Dumpable
private final FrameHandler.ConfigurationCustomizer defaultCustomizer = new FrameHandler.ConfigurationCustomizer();
private WebSocketMapping mapping;
public WebSocketUpgradeFilter()
{
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException
{
@ -141,6 +167,11 @@ public class WebSocketUpgradeFilter implements Filter, Dumpable
Dumpable.dumpObjects(out, indent, this, mapping);
}
public void setMapping(WebSocketMapping mapping)
{
this.mapping = mapping;
}
@ManagedAttribute(value = "factory", readonly = true)
public WebSocketMapping getMapping()
{
@ -151,7 +182,9 @@ public class WebSocketUpgradeFilter implements Filter, Dumpable
public void init(FilterConfig config) throws ServletException
{
final ServletContext context = config.getServletContext();
mapping = WebSocketMapping.ensureMapping(context);
if (mapping == null)
throw new IllegalStateException("no websocket mapping set in container");
String max = config.getInitParameter("maxIdleTime");
if (max != null)