Issue #1090 - Use WebSocketUpgradeFilter from WEB-INF/web.xml if present

This commit is contained in:
Joakim Erdfelt 2016-11-10 14:26:04 -07:00
parent de18e4540b
commit 2295bd59e3
2 changed files with 36 additions and 42 deletions

View File

@ -66,23 +66,12 @@ public class WebSocketServerContainerInitializer implements ServletContainerInit
}
/**
* Servlet 3.1 approach.
* <p>
* This will use Servlet 3.1 techniques on the {@link ServletContext} to add a filter at the start of the filter chain.
* @deprecated use {@link #configureContext(ServletContextHandler)} instead
*/
@Deprecated
public static ServerContainer configureContext(ServletContext context, ServletContextHandler jettyContext) throws ServletException
{
// Create Filter
WebSocketUpgradeFilter filter = WebSocketUpgradeFilter.configureContext(context);
// Create the Jetty ServerContainer implementation
ServerContainer jettyContainer = new ServerContainer(filter,filter.getFactory(),jettyContext.getServer().getThreadPool());
jettyContext.addBean(jettyContainer);
// Store a reference to the ServerContainer per javax.websocket spec 1.0 final section 6.4 Programmatic Server Deployment
context.setAttribute(javax.websocket.server.ServerContainer.class.getName(),jettyContainer);
return jettyContainer;
return configureContext(jettyContext);
}
private boolean isEnabled(Set<Class<?>> c, ServletContext context)
@ -159,7 +148,7 @@ public class WebSocketServerContainerInitializer implements ServletContainerInit
Thread.currentThread().setContextClassLoader(context.getClassLoader());
// Create the Jetty ServerContainer implementation
ServerContainer jettyContainer = configureContext(context,jettyContext);
ServerContainer jettyContainer = configureContext(jettyContext);
// Store a reference to the ServerContainer per javax.websocket spec 1.0 final section 6.4 Programmatic Server Deployment
context.setAttribute(javax.websocket.server.ServerContainer.class.getName(),jettyContainer);

View File

@ -25,7 +25,6 @@ import javax.servlet.DispatcherType;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.FilterRegistration;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
@ -35,6 +34,7 @@ import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.io.MappedByteBufferPool;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.servlet.FilterHolder;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.util.annotation.ManagedAttribute;
@ -67,6 +67,19 @@ public class WebSocketUpgradeFilter extends ContainerLifeCycle implements Filter
return filter;
}
// Use WEB-INF/web.xml instantiated version, if present
FilterHolder filters[] = context.getServletHandler().getFilters();
for (FilterHolder registeredFilter: filters)
{
if (WebSocketUpgradeFilter.class.isAssignableFrom(registeredFilter.getClass()))
{
WebSocketUpgradeFilter wsuf = (WebSocketUpgradeFilter) registeredFilter.getFilter();
// need async supported
context.setAttribute(WebSocketUpgradeFilter.class.getName(), wsuf);
return wsuf;
}
}
// Dynamically add filter
filter = new WebSocketUpgradeFilter();
filter.setToAttribute(context, WebSocketUpgradeFilter.class.getName());
@ -89,36 +102,25 @@ public class WebSocketUpgradeFilter extends ContainerLifeCycle implements Filter
return filter;
}
/**
* @deprecated use {@link #configureContext(ServletContextHandler)} instead
*/
@Deprecated
public static WebSocketUpgradeFilter configureContext(ServletContext context) throws ServletException
{
// Prevent double configure
WebSocketUpgradeFilter filter = (WebSocketUpgradeFilter)context.getAttribute(WebSocketUpgradeFilter.class.getName());
if (filter != null)
ContextHandler handler = ContextHandler.getContextHandler(context);
if (handler == null)
{
return filter;
throw new ServletException("Not running on Jetty, WebSocket support unavailable");
}
// Dynamically add filter
filter = new WebSocketUpgradeFilter();
filter.setToAttribute(context, WebSocketUpgradeFilter.class.getName());
String name = "Jetty_Dynamic_WebSocketUpgradeFilter";
String pathSpec = "/*";
EnumSet<DispatcherType> dispatcherTypes = EnumSet.of(DispatcherType.REQUEST);
boolean isMatchAfter = false;
String urlPatterns[] = { pathSpec };
FilterRegistration.Dynamic dyn = context.addFilter(name,filter);
dyn.setAsyncSupported(true);
dyn.setInitParameter(CONTEXT_ATTRIBUTE_KEY,WebSocketUpgradeFilter.class.getName());
dyn.addMappingForUrlPatterns(dispatcherTypes,isMatchAfter,urlPatterns);
if (LOG.isDebugEnabled())
if (!(handler instanceof ServletContextHandler))
{
LOG.debug("Adding [{}] {} mapped to {} to {}",name,filter,pathSpec,context);
throw new ServletException("Not running in Jetty ServletContextHandler, WebSocket support via " + WebSocketUpgradeFilter.class.getName() + " unavailable");
}
return filter;
return configureContext((ServletContextHandler) handler);
}
private final WebSocketServerFactory factory;
@ -140,6 +142,9 @@ public class WebSocketUpgradeFilter extends ContainerLifeCycle implements Filter
@Override
public void addMapping(PathSpec spec, WebSocketCreator creator)
{
// TODO: ideally should throw warning/error if attempting to map to something
// not covered by the filter pathSpec/url-patterns. But how do we get the filter mappings
// in a sane way? and then apply them to the PathSpec object properly?
pathmap.put(spec,creator);
}