Issue #1057 - Improve WebSocketUpgradeFilter performance
+ Tests for WebSocket upgrade now evaluates the request from least common feature to most common feature, so as minimize the testing of the request object on every request
This commit is contained in:
parent
4cc5178944
commit
c665106fc5
|
@ -188,7 +188,7 @@ public class WebSocketServerFactory extends ContainerLifeCycle implements WebSoc
|
|||
catch (URISyntaxException e)
|
||||
{
|
||||
throw new IOException("Unable to accept websocket due to mangled URI", e);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
Thread.currentThread().setContextClassLoader(old);
|
||||
|
@ -340,13 +340,22 @@ public class WebSocketServerFactory extends ContainerLifeCycle implements WebSoc
|
|||
@Override
|
||||
public boolean isUpgradeRequest(HttpServletRequest request, HttpServletResponse response)
|
||||
{
|
||||
if (!"GET".equalsIgnoreCase(request.getMethod()))
|
||||
// Tests sorted by least common to most common.
|
||||
|
||||
String upgrade = request.getHeader("Upgrade");
|
||||
if (upgrade == null)
|
||||
{
|
||||
// not a "GET" request (not a websocket upgrade)
|
||||
// no "Upgrade: websocket" header present.
|
||||
return false;
|
||||
}
|
||||
|
||||
String connection = request.getHeader("connection");
|
||||
|
||||
if (!"websocket".equalsIgnoreCase(upgrade))
|
||||
{
|
||||
// Not a websocket upgrade
|
||||
return false;
|
||||
}
|
||||
|
||||
String connection = request.getHeader("Connection");
|
||||
if (connection == null)
|
||||
{
|
||||
// no "Connection: upgrade" header present.
|
||||
|
@ -370,17 +379,10 @@ public class WebSocketServerFactory extends ContainerLifeCycle implements WebSoc
|
|||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
String upgrade = request.getHeader("Upgrade");
|
||||
if (upgrade == null)
|
||||
|
||||
if (!"GET".equalsIgnoreCase(request.getMethod()))
|
||||
{
|
||||
// no "Upgrade: websocket" header present.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!"websocket".equalsIgnoreCase(upgrade))
|
||||
{
|
||||
LOG.debug("Not a 'Upgrade: WebSocket' (was [Upgrade: " + upgrade + "])");
|
||||
// not a "GET" request (not a websocket upgrade)
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ package org.eclipse.jetty.websocket.server;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.util.EnumSet;
|
||||
|
||||
import javax.servlet.DispatcherType;
|
||||
import javax.servlet.Filter;
|
||||
import javax.servlet.FilterChain;
|
||||
|
@ -160,17 +161,19 @@ public class WebSocketUpgradeFilter extends ContainerLifeCycle implements Filter
|
|||
chain.doFilter(request,response);
|
||||
return;
|
||||
}
|
||||
|
||||
if (LOG.isDebugEnabled())
|
||||
|
||||
try
|
||||
{
|
||||
LOG.debug(".doFilter({}) - {}",fname,chain);
|
||||
}
|
||||
|
||||
if ((request instanceof HttpServletRequest) && (response instanceof HttpServletResponse))
|
||||
{
|
||||
HttpServletRequest httpreq = (HttpServletRequest)request;
|
||||
HttpServletResponse httpresp = (HttpServletResponse)response;
|
||||
|
||||
HttpServletRequest httpreq = (HttpServletRequest) request;
|
||||
HttpServletResponse httpresp = (HttpServletResponse) response;
|
||||
|
||||
if (!factory.isUpgradeRequest(httpreq, httpresp))
|
||||
{
|
||||
// Not an upgrade request, skip it
|
||||
chain.doFilter(request, response);
|
||||
return;
|
||||
}
|
||||
|
||||
// Since this is a filter, we need to be smart about determining the target path
|
||||
String contextPath = httpreq.getContextPath();
|
||||
String target = httpreq.getRequestURI();
|
||||
|
@ -178,45 +181,52 @@ public class WebSocketUpgradeFilter extends ContainerLifeCycle implements Filter
|
|||
{
|
||||
target = target.substring(contextPath.length());
|
||||
}
|
||||
|
||||
if (factory.isUpgradeRequest(httpreq,httpresp))
|
||||
|
||||
MappedResource<WebSocketCreator> resource = pathmap.getMatch(target);
|
||||
if (resource == null)
|
||||
{
|
||||
LOG.debug("target = [{}]",target);
|
||||
|
||||
MappedResource<WebSocketCreator> resource = pathmap.getMatch(target);
|
||||
if (resource == null)
|
||||
if (LOG.isDebugEnabled())
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
{
|
||||
LOG.debug("WebSocket Upgrade on {} has no associated endpoint",target);
|
||||
LOG.debug("PathMappings: {}",pathmap.dump());
|
||||
}
|
||||
// no match.
|
||||
chain.doFilter(request,response);
|
||||
return;
|
||||
}
|
||||
LOG.debug("WebSocket Upgrade detected on {} for endpoint {}",target,resource);
|
||||
|
||||
WebSocketCreator creator = resource.getResource();
|
||||
|
||||
// Store PathSpec resource mapping as request attribute
|
||||
httpreq.setAttribute(PathSpec.class.getName(),resource.getPathSpec());
|
||||
|
||||
// We have an upgrade request
|
||||
if (factory.acceptWebSocket(creator,httpreq,httpresp))
|
||||
{
|
||||
// We have a socket instance created
|
||||
return;
|
||||
}
|
||||
|
||||
// If we reach this point, it means we had an incoming request to upgrade
|
||||
// but it was either not a proper websocket upgrade, or it was possibly rejected
|
||||
// due to incoming request constraints (controlled by WebSocketCreator)
|
||||
if (response.isCommitted())
|
||||
{
|
||||
// not much we can do at this point.
|
||||
return;
|
||||
LOG.debug("WebSocket Upgrade on {} has no associated endpoint", target);
|
||||
LOG.debug("PathMappings: {}", pathmap.dump());
|
||||
}
|
||||
// no match.
|
||||
chain.doFilter(request, response);
|
||||
return;
|
||||
}
|
||||
|
||||
if(LOG.isDebugEnabled())
|
||||
{
|
||||
LOG.debug("WebSocket Upgrade detected on {} for endpoint {}", target, resource);
|
||||
}
|
||||
|
||||
WebSocketCreator creator = resource.getResource();
|
||||
|
||||
// Store PathSpec resource mapping as request attribute
|
||||
httpreq.setAttribute(PathSpec.class.getName(), resource.getPathSpec());
|
||||
|
||||
// We have an upgrade request
|
||||
if (factory.acceptWebSocket(creator, httpreq, httpresp))
|
||||
{
|
||||
// We have a socket instance created
|
||||
return;
|
||||
}
|
||||
|
||||
// If we reach this point, it means we had an incoming request to upgrade
|
||||
// but it was either not a proper websocket upgrade, or it was possibly rejected
|
||||
// due to incoming request constraints (controlled by WebSocketCreator)
|
||||
if (response.isCommitted())
|
||||
{
|
||||
// not much we can do at this point.
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (ClassCastException e)
|
||||
{
|
||||
// We are in some kind of funky non-http environment.
|
||||
if (LOG.isDebugEnabled())
|
||||
{
|
||||
LOG.debug("Not a HttpServletRequest, skipping WebSocketUpgradeFilter");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue