Merge branch 'jetty-10.0.x-3167-websocket-mapping' into jetty-10.0.x-3167-2175-websocket-close
This commit is contained in:
commit
878e51032d
|
@ -24,6 +24,8 @@ import javax.websocket.server.ServerContainer;
|
|||
import javax.websocket.server.ServerEndpoint;
|
||||
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.server.handler.DefaultHandler;
|
||||
import org.eclipse.jetty.server.handler.HandlerList;
|
||||
import org.eclipse.jetty.servlet.ServletContextHandler;
|
||||
import org.eclipse.jetty.websocket.javax.server.JavaxWebSocketServerContainerInitializer;
|
||||
|
||||
|
@ -49,10 +51,12 @@ public class WebSocketJsrServer
|
|||
{
|
||||
Server server = new Server(8080);
|
||||
|
||||
HandlerList handlers = new HandlerList();
|
||||
|
||||
ServletContextHandler context = new ServletContextHandler(
|
||||
ServletContextHandler.SESSIONS);
|
||||
context.setContextPath("/");
|
||||
server.setHandler(context);
|
||||
handlers.addHandler(context);
|
||||
|
||||
// Enable javax.websocket configuration for the context
|
||||
ServerContainer wsContainer = JavaxWebSocketServerContainerInitializer
|
||||
|
@ -61,6 +65,9 @@ public class WebSocketJsrServer
|
|||
// Add your websockets to the container
|
||||
wsContainer.addEndpoint(EchoJsrSocket.class);
|
||||
|
||||
handlers.addHandler(new DefaultHandler());
|
||||
|
||||
server.setHandler(handlers);
|
||||
server.start();
|
||||
context.dumpStdErr();
|
||||
server.join();
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||
|
||||
[depend]
|
||||
alpn-impl/alpn-9
|
|
@ -549,7 +549,7 @@ public abstract class AbstractProxyServlet extends HttpServlet
|
|||
}
|
||||
builder.append(System.lineSeparator());
|
||||
|
||||
_log.debug("{} proxying to upstream:{}{}{}{}",
|
||||
_log.debug("{} proxying to upstream:{}{}{}{}{}",
|
||||
getRequestId(clientRequest),
|
||||
System.lineSeparator(),
|
||||
builder,
|
||||
|
|
|
@ -620,6 +620,16 @@ public class ProxyConnectionFactory extends AbstractConnectionFactory
|
|||
return _remote;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("%s@%x[remote=%s,local=%s,endpoint=%s]",
|
||||
getClass().getSimpleName(),
|
||||
hashCode(),
|
||||
_remote,
|
||||
_local,
|
||||
_endp);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOpen()
|
||||
{
|
||||
|
|
|
@ -69,6 +69,15 @@ public interface Dumpable
|
|||
return b.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* The description of this/self found in the dump.
|
||||
* Allows for alternative representation of Object other then .toString()
|
||||
* where the long form output of toString() is represented in a cleaner way
|
||||
* within the dump infrastructure.
|
||||
*
|
||||
* @return the representation of self
|
||||
*/
|
||||
default String dumpSelf() { return toString(); }
|
||||
|
||||
/**
|
||||
* Dump just an Object (but not it's contained items) to an Appendable.
|
||||
|
@ -89,6 +98,8 @@ public interface Dumpable
|
|||
s = String.format("%s@%x[size=%d]",o.getClass().getComponentType(),o.hashCode(), Array.getLength(o));
|
||||
else if (o instanceof Map)
|
||||
s = String.format("%s@%x{size=%d}",o.getClass().getName(),o.hashCode(),((Map<?,?>)o).size());
|
||||
else if (o instanceof Dumpable)
|
||||
s = ((Dumpable)o).dumpSelf().replace("\r\n","|").replace("\n","|");
|
||||
else
|
||||
s = String.valueOf(o).replace("\r\n","|").replace("\n","|");
|
||||
|
||||
|
|
|
@ -32,6 +32,12 @@
|
|||
<artifactId>jetty-server</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-jmx</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.websocket</groupId>
|
||||
<artifactId>jetty-websocket-api</artifactId>
|
||||
|
|
|
@ -30,6 +30,7 @@ module org.eclipse.jetty.websocket.jetty.server
|
|||
requires org.eclipse.jetty.util;
|
||||
requires org.eclipse.jetty.http;
|
||||
requires org.eclipse.jetty.server;
|
||||
requires static org.eclipse.jetty.jmx;
|
||||
requires org.eclipse.jetty.servlet;
|
||||
requires org.eclipse.jetty.webapp;
|
||||
requires org.eclipse.jetty.websocket.jetty.api;
|
||||
|
|
|
@ -18,16 +18,19 @@
|
|||
|
||||
package org.eclipse.jetty.websocket.core;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.eclipse.jetty.io.ByteBufferPool;
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
import org.eclipse.jetty.util.annotation.ManagedAttribute;
|
||||
import org.eclipse.jetty.util.annotation.ManagedObject;
|
||||
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.internal.WebSocketChannel;
|
||||
|
||||
@ManagedObject("Abstract Extension")
|
||||
public abstract class AbstractExtension implements Extension
|
||||
public abstract class AbstractExtension implements Extension, Dumpable
|
||||
{
|
||||
private final Logger log;
|
||||
private ByteBufferPool bufferPool;
|
||||
|
@ -41,6 +44,27 @@ public abstract class AbstractExtension implements Extension
|
|||
log = Log.getLogger(this.getClass());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String dump()
|
||||
{
|
||||
return Dumpable.dump(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dump(Appendable out, String indent) throws IOException
|
||||
{
|
||||
// incoming
|
||||
dumpWithHeading(out, indent, "incoming", this.nextIncoming);
|
||||
dumpWithHeading(out, indent, "outgoing", this.nextOutgoing);
|
||||
}
|
||||
|
||||
protected void dumpWithHeading(Appendable out, String indent, String heading, Object bean) throws IOException
|
||||
{
|
||||
out.append(indent).append(" +- ");
|
||||
out.append(heading).append(" : ");
|
||||
out.append(bean.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(ExtensionConfig config, ByteBufferPool bufferPool)
|
||||
{
|
||||
|
|
|
@ -232,6 +232,12 @@ public class ExtensionStack implements IncomingFrames, OutgoingFrames, Dumpable
|
|||
Dumpable.dumpObjects(out, indent, this, extensions == null?Collections.emptyList():extensions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String dumpSelf()
|
||||
{
|
||||
return String.format("%s@%x[size=%d,queueSize=%d]", getClass().getSimpleName(), hashCode(), extensions.size(), getQueueSize());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
|
|
|
@ -20,7 +20,9 @@ package org.eclipse.jetty.websocket.servlet;
|
|||
|
||||
import org.eclipse.jetty.websocket.core.FrameHandler;
|
||||
|
||||
|
||||
/**
|
||||
* Factory for FrameHandler instances
|
||||
*/
|
||||
public interface FrameHandlerFactory
|
||||
{
|
||||
/**
|
||||
|
|
|
@ -18,15 +18,6 @@
|
|||
|
||||
package org.eclipse.jetty.websocket.servlet;
|
||||
|
||||
import org.eclipse.jetty.http.HttpHeader;
|
||||
import org.eclipse.jetty.websocket.core.ExtensionConfig;
|
||||
import org.eclipse.jetty.websocket.core.WebSocketConstants;
|
||||
import org.eclipse.jetty.websocket.core.server.Negotiation;
|
||||
import org.eclipse.jetty.websocket.servlet.internal.UpgradeHttpServletRequest;
|
||||
|
||||
import javax.servlet.http.Cookie;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpSession;
|
||||
import java.net.HttpCookie;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.SocketAddress;
|
||||
|
@ -42,8 +33,19 @@ import java.util.List;
|
|||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.http.Cookie;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpSession;
|
||||
|
||||
import org.eclipse.jetty.http.HttpHeader;
|
||||
import org.eclipse.jetty.websocket.core.ExtensionConfig;
|
||||
import org.eclipse.jetty.websocket.core.WebSocketConstants;
|
||||
import org.eclipse.jetty.websocket.core.server.Negotiation;
|
||||
import org.eclipse.jetty.websocket.servlet.internal.UpgradeHttpServletRequest;
|
||||
|
||||
/**
|
||||
* Servlet specific Upgrade Request implementation.
|
||||
* Holder of request data for a WebSocket upgrade request.
|
||||
*/
|
||||
public class ServletUpgradeRequest
|
||||
{
|
||||
|
@ -62,7 +64,9 @@ public class ServletUpgradeRequest
|
|||
this.queryString = httpRequest.getQueryString();
|
||||
this.secure = httpRequest.isSecure();
|
||||
|
||||
// TODO why is this URL and not URI?
|
||||
StringBuffer uri = httpRequest.getRequestURL();
|
||||
// WHY?
|
||||
if (this.queryString != null)
|
||||
uri.append("?").append(this.queryString);
|
||||
uri.replace(0, uri.indexOf(":"), secure?"wss":"ws");
|
||||
|
@ -70,11 +74,18 @@ public class ServletUpgradeRequest
|
|||
this.request = new UpgradeHttpServletRequest(httpRequest);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The {@link X509Certificate} instance at request attribute "javax.servlet.request.X509Certificate" or null.
|
||||
*/
|
||||
public X509Certificate[] getCertificates()
|
||||
{
|
||||
return (X509Certificate[])request.getAttribute("javax.servlet.request.X509Certificate");
|
||||
}
|
||||
|
||||
/**
|
||||
* @see HttpServletRequest#getCookies()
|
||||
* @return Request cookies
|
||||
*/
|
||||
public List<HttpCookie> getCookies()
|
||||
{
|
||||
if (cookies == null)
|
||||
|
@ -95,16 +106,30 @@ public class ServletUpgradeRequest
|
|||
return cookies;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The extensions offered
|
||||
* @see Negotiation#getOfferedExtensions()
|
||||
*/
|
||||
public List<ExtensionConfig> getExtensions()
|
||||
{
|
||||
return negotiation.getOfferedExtensions();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param name Header name
|
||||
* @return Header value or null
|
||||
* @see HttpServletRequest#getHeader(String)
|
||||
*/
|
||||
public String getHeader(String name)
|
||||
{
|
||||
return request.getHeader(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param name Header name
|
||||
* @return Header value as integer or -1
|
||||
* @see HttpServletRequest#getHeader(String)
|
||||
*/
|
||||
public int getHeaderInt(String name)
|
||||
{
|
||||
String val = request.getHeader(name);
|
||||
|
@ -115,57 +140,102 @@ public class ServletUpgradeRequest
|
|||
return Integer.parseInt(val);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Map of headers
|
||||
* @see UpgradeHttpServletRequest#getHeaders()
|
||||
*/
|
||||
public Map<String, List<String>> getHeadersMap()
|
||||
{
|
||||
return request.getHeaders();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param name Header name
|
||||
* @return List of header values or null
|
||||
* @see UpgradeHttpServletRequest#getHeaders()
|
||||
*/
|
||||
public List<String> getHeaders(String name)
|
||||
{
|
||||
return request.getHeaders().get(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The requested host
|
||||
* @see HttpServletRequest#getRequestURL()
|
||||
*/
|
||||
public String getHost()
|
||||
{
|
||||
// TODO why is this not HttpServletRequest#getHost ?
|
||||
return requestURI.getHost();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Immutable version of {@link HttpServletRequest}
|
||||
*/
|
||||
public HttpServletRequest getHttpServletRequest()
|
||||
{
|
||||
return request;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The HTTP protocol version
|
||||
* @see HttpServletRequest#getProtocol()
|
||||
*/
|
||||
public String getHttpVersion()
|
||||
{
|
||||
return request.getProtocol();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The requested Locale
|
||||
* @see HttpServletRequest#getLocale()
|
||||
*/
|
||||
public Locale getLocale()
|
||||
{
|
||||
return request.getLocale();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The requested Locales
|
||||
* @see HttpServletRequest#getLocales()
|
||||
*/
|
||||
public Enumeration<Locale> getLocales()
|
||||
{
|
||||
return request.getLocales();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The local requested address, which is typically an {@link InetSocketAddress}, but may be another derivation of {@link SocketAddress}
|
||||
* @see ServletRequest#getLocalAddr()
|
||||
* @see ServletRequest#getLocalPort()
|
||||
*/
|
||||
public SocketAddress getLocalSocketAddress()
|
||||
{
|
||||
// TODO: fix when HttpServletRequest can use Unix Socket stuff
|
||||
return new InetSocketAddress(request.getLocalAddr(), request.getLocalPort());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The requested method
|
||||
* @see HttpServletRequest#getMethod()
|
||||
*/
|
||||
public String getMethod()
|
||||
{
|
||||
return request.getMethod();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The origin header value
|
||||
*/
|
||||
public String getOrigin()
|
||||
{
|
||||
return getHeader("Origin");
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The request parameter map
|
||||
* @see ServletRequest#getParameterMap()
|
||||
*/
|
||||
public Map<String, List<String>> getParameterMap()
|
||||
{
|
||||
if (parameterMap == null)
|
||||
|
@ -181,6 +251,9 @@ public class ServletUpgradeRequest
|
|||
return parameterMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return WebSocket protocol version from "Sec-WebSocket-Version" header
|
||||
*/
|
||||
public String getProtocolVersion()
|
||||
{
|
||||
String version = request.getHeader(HttpHeader.SEC_WEBSOCKET_VERSION.asString());
|
||||
|
@ -191,19 +264,32 @@ public class ServletUpgradeRequest
|
|||
return version;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The request query string
|
||||
* @see HttpServletRequest#getQueryString()
|
||||
*/
|
||||
public String getQueryString()
|
||||
{
|
||||
return this.queryString;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The remote request address, which is typically an {@link InetSocketAddress}, but may be another derivation of {@link SocketAddress}
|
||||
* @see ServletRequest#getRemoteAddr()
|
||||
* @see ServletRequest#getRemotePort()
|
||||
*/
|
||||
public SocketAddress getRemoteSocketAddress()
|
||||
{
|
||||
return new InetSocketAddress(request.getRemoteAddr(), request.getRemotePort());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The request URI path within the context
|
||||
*/
|
||||
public String getRequestPath()
|
||||
{
|
||||
// Since this can be called from a filter, we need to be smart about determining the target request path.
|
||||
// TODO probably better adding servletPath and pathInfo
|
||||
String contextPath = request.getContextPath();
|
||||
String requestPath = request.getRequestURI();
|
||||
if (requestPath.startsWith(contextPath))
|
||||
|
@ -211,46 +297,78 @@ public class ServletUpgradeRequest
|
|||
return requestPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The request URI
|
||||
* @see HttpServletRequest#getRequestURL()
|
||||
*/
|
||||
public URI getRequestURI()
|
||||
{
|
||||
return requestURI;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param name Attribute name
|
||||
* @return Attribute value or null
|
||||
* @see ServletRequest#getAttribute(String)
|
||||
*/
|
||||
public Object getServletAttribute(String name)
|
||||
{
|
||||
return request.getAttribute(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Request attribute map
|
||||
* @see UpgradeHttpServletRequest#getAttributes()
|
||||
*/
|
||||
public Map<String, Object> getServletAttributes()
|
||||
{
|
||||
return request.getAttributes();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Request parameters
|
||||
* @see ServletRequest#getParameterMap()
|
||||
*/
|
||||
public Map<String, List<String>> getServletParameters()
|
||||
{
|
||||
return getParameterMap();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The HttpSession, which may be null or invalidated
|
||||
* @see HttpServletRequest#getSession(boolean)
|
||||
*/
|
||||
public HttpSession getSession()
|
||||
{
|
||||
return request.getSession(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Get WebSocket negotiation offered sub protocols
|
||||
*/
|
||||
public List<String> getSubProtocols()
|
||||
{
|
||||
return negotiation.getOfferedSubprotocols();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The User's {@link Principal} or null
|
||||
* @see HttpServletRequest#getUserPrincipal()
|
||||
*/
|
||||
public Principal getUserPrincipal()
|
||||
{
|
||||
return request.getUserPrincipal();
|
||||
}
|
||||
|
||||
public boolean hasSubProtocol(String test)
|
||||
/**
|
||||
* @param subprotocol A sub protocol name
|
||||
* @return True if the sub protocol was offered
|
||||
*/
|
||||
public boolean hasSubProtocol(String subprotocol)
|
||||
{
|
||||
for (String protocol : getSubProtocols())
|
||||
{
|
||||
if (protocol.equalsIgnoreCase(test))
|
||||
if (protocol.equalsIgnoreCase(subprotocol))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
@ -258,16 +376,30 @@ public class ServletUpgradeRequest
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return True if the request is secure
|
||||
* @see ServletRequest#isSecure()
|
||||
*/
|
||||
public boolean isSecure()
|
||||
{
|
||||
return this.secure;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param role The user role
|
||||
* @return True if the requests user has the role
|
||||
* @see HttpServletRequest#isUserInRole(String)
|
||||
*/
|
||||
public boolean isUserInRole(String role)
|
||||
{
|
||||
return request.isUserInRole(role);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param name Attribute name
|
||||
* @param value Attribute value to set
|
||||
* @see ServletRequest#setAttribute(String, Object)
|
||||
*/
|
||||
public void setServletAttribute(String name, Object value)
|
||||
{
|
||||
request.setAttribute(name, value);
|
||||
|
|
|
@ -33,6 +33,7 @@ import org.eclipse.jetty.servlet.ServletContextHandler;
|
|||
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.WebSocketExtensionRegistry;
|
||||
|
||||
/**
|
||||
* Abstract Servlet used to bridge the Servlet API to the WebSocket API.
|
||||
|
@ -173,6 +174,11 @@ public abstract class WebSocketServlet extends HttpServlet
|
|||
|
||||
private class CustomizedWebSocketServletFactory extends FrameHandler.ConfigurationCustomizer implements WebSocketServletFactory
|
||||
{
|
||||
public WebSocketExtensionRegistry getExtensionRegistry()
|
||||
{
|
||||
return mapping.getExtensionRegistry();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Duration getDefaultIdleTimeout()
|
||||
{
|
||||
|
|
|
@ -24,6 +24,7 @@ import java.time.Duration;
|
|||
|
||||
public interface WebSocketServletFactory
|
||||
{
|
||||
|
||||
Duration getDefaultIdleTimeout();
|
||||
|
||||
void setDefaultIdleTimeout(Duration duration);
|
||||
|
|
Loading…
Reference in New Issue