Implemented support for RFC 8441's SETTING_ENABLE_CONNECT_PROTOCOL.
Signed-off-by: Simone Bordet <simone.bordet@gmail.com>
This commit is contained in:
parent
98574f28a0
commit
5e695919d9
|
@ -97,6 +97,7 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio
|
||||||
private int initialSessionRecvWindow;
|
private int initialSessionRecvWindow;
|
||||||
private int writeThreshold;
|
private int writeThreshold;
|
||||||
private boolean pushEnabled;
|
private boolean pushEnabled;
|
||||||
|
private boolean connectProtocolEnabled;
|
||||||
private long idleTime;
|
private long idleTime;
|
||||||
private GoAwayFrame closeFrame;
|
private GoAwayFrame closeFrame;
|
||||||
|
|
||||||
|
@ -370,6 +371,14 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio
|
||||||
generator.setMaxHeaderListSize(value);
|
generator.setMaxHeaderListSize(value);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case SettingsFrame.ENABLE_CONNECT_PROTOCOL:
|
||||||
|
{
|
||||||
|
boolean enabled = value == 1;
|
||||||
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("{} CONNECT protocol for {}", enabled ? "Enabling" : "Disabling", this);
|
||||||
|
connectProtocolEnabled = enabled;
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
if (LOG.isDebugEnabled())
|
if (LOG.isDebugEnabled())
|
||||||
|
@ -906,6 +915,17 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio
|
||||||
return pushEnabled;
|
return pushEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ManagedAttribute(value = "Whether CONNECT requests supports a protocol", readonly = true)
|
||||||
|
public boolean isConnectProtocolEnabled()
|
||||||
|
{
|
||||||
|
return connectProtocolEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setConnectProtocolEnabled(boolean connectProtocolEnabled)
|
||||||
|
{
|
||||||
|
this.connectProtocolEnabled = connectProtocolEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A typical close by a remote peer involves a GO_AWAY frame followed by TCP FIN.
|
* A typical close by a remote peer involves a GO_AWAY frame followed by TCP FIN.
|
||||||
* This method is invoked when the TCP FIN is received, or when an exception is
|
* This method is invoked when the TCP FIN is received, or when an exception is
|
||||||
|
|
|
@ -30,6 +30,7 @@ public class SettingsFrame extends Frame
|
||||||
public static final int INITIAL_WINDOW_SIZE = 4;
|
public static final int INITIAL_WINDOW_SIZE = 4;
|
||||||
public static final int MAX_FRAME_SIZE = 5;
|
public static final int MAX_FRAME_SIZE = 5;
|
||||||
public static final int MAX_HEADER_LIST_SIZE = 6;
|
public static final int MAX_HEADER_LIST_SIZE = 6;
|
||||||
|
public static final int ENABLE_CONNECT_PROTOCOL = 8;
|
||||||
|
|
||||||
private final Map<Integer, Integer> settings;
|
private final Map<Integer, Integer> settings;
|
||||||
private final boolean reply;
|
private final boolean reply;
|
||||||
|
|
|
@ -60,6 +60,7 @@ public abstract class AbstractHTTP2ServerConnectionFactory extends AbstractConne
|
||||||
private int maxHeaderBlockFragment = 0;
|
private int maxHeaderBlockFragment = 0;
|
||||||
private int maxFrameLength = Frame.DEFAULT_MAX_LENGTH;
|
private int maxFrameLength = Frame.DEFAULT_MAX_LENGTH;
|
||||||
private int maxSettingsKeys = SettingsFrame.DEFAULT_MAX_KEYS;
|
private int maxSettingsKeys = SettingsFrame.DEFAULT_MAX_KEYS;
|
||||||
|
private boolean connectProtocolEnabled = true;
|
||||||
private RateControl.Factory rateControlFactory = new WindowRateControl.Factory(20);
|
private RateControl.Factory rateControlFactory = new WindowRateControl.Factory(20);
|
||||||
private FlowControlStrategy.Factory flowControlStrategyFactory = () -> new BufferingFlowControlStrategy(0.5F);
|
private FlowControlStrategy.Factory flowControlStrategyFactory = () -> new BufferingFlowControlStrategy(0.5F);
|
||||||
private long streamIdleTimeout;
|
private long streamIdleTimeout;
|
||||||
|
@ -185,6 +186,17 @@ public abstract class AbstractHTTP2ServerConnectionFactory extends AbstractConne
|
||||||
this.maxSettingsKeys = maxSettingsKeys;
|
this.maxSettingsKeys = maxSettingsKeys;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ManagedAttribute("Whether CONNECT requests supports a protocol")
|
||||||
|
public boolean isConnectProtocolEnabled()
|
||||||
|
{
|
||||||
|
return connectProtocolEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setConnectProtocolEnabled(boolean connectProtocolEnabled)
|
||||||
|
{
|
||||||
|
this.connectProtocolEnabled = connectProtocolEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the factory that creates RateControl objects
|
* @return the factory that creates RateControl objects
|
||||||
*/
|
*/
|
||||||
|
@ -237,6 +249,7 @@ public abstract class AbstractHTTP2ServerConnectionFactory extends AbstractConne
|
||||||
if (maxConcurrentStreams >= 0)
|
if (maxConcurrentStreams >= 0)
|
||||||
settings.put(SettingsFrame.MAX_CONCURRENT_STREAMS, maxConcurrentStreams);
|
settings.put(SettingsFrame.MAX_CONCURRENT_STREAMS, maxConcurrentStreams);
|
||||||
settings.put(SettingsFrame.MAX_HEADER_LIST_SIZE, getHttpConfiguration().getRequestHeaderSize());
|
settings.put(SettingsFrame.MAX_HEADER_LIST_SIZE, getHttpConfiguration().getRequestHeaderSize());
|
||||||
|
settings.put(SettingsFrame.ENABLE_CONNECT_PROTOCOL, isConnectProtocolEnabled() ? 1 : 0);
|
||||||
return settings;
|
return settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -259,6 +272,7 @@ public abstract class AbstractHTTP2ServerConnectionFactory extends AbstractConne
|
||||||
session.setStreamIdleTimeout(streamIdleTimeout);
|
session.setStreamIdleTimeout(streamIdleTimeout);
|
||||||
session.setInitialSessionRecvWindow(getInitialSessionRecvWindow());
|
session.setInitialSessionRecvWindow(getInitialSessionRecvWindow());
|
||||||
session.setWriteThreshold(getHttpConfiguration().getOutputBufferSize());
|
session.setWriteThreshold(getHttpConfiguration().getOutputBufferSize());
|
||||||
|
session.setConnectProtocolEnabled(isConnectProtocolEnabled());
|
||||||
|
|
||||||
ServerParser parser = newServerParser(connector, session, getRateControlFactory().newRateControl(endPoint));
|
ServerParser parser = newServerParser(connector, session, getRateControlFactory().newRateControl(endPoint));
|
||||||
parser.setMaxFrameLength(getMaxFrameLength());
|
parser.setMaxFrameLength(getMaxFrameLength());
|
||||||
|
|
|
@ -108,6 +108,16 @@ public class HTTP2ServerSession extends HTTP2Session implements ServerParser.Lis
|
||||||
if (stream != null)
|
if (stream != null)
|
||||||
{
|
{
|
||||||
onStreamOpened(stream);
|
onStreamOpened(stream);
|
||||||
|
|
||||||
|
if (metaData instanceof MetaData.ConnectRequest)
|
||||||
|
{
|
||||||
|
if (!isConnectProtocolEnabled() && ((MetaData.ConnectRequest)metaData).getProtocol() != null)
|
||||||
|
{
|
||||||
|
stream.reset(new ResetFrame(streamId, ErrorCode.PROTOCOL_ERROR.code), Callback.NOOP);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
stream.process(frame, Callback.NOOP);
|
stream.process(frame, Callback.NOOP);
|
||||||
Stream.Listener listener = notifyNewStream(stream, frame);
|
Stream.Listener listener = notifyNewStream(stream, frame);
|
||||||
stream.setListener(listener);
|
stream.setListener(listener);
|
||||||
|
|
|
@ -378,7 +378,7 @@ public class Session implements SessionHandler.SessionIf
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
HttpSessionEvent event = new HttpSessionEvent(this);
|
HttpSessionEvent event = new HttpSessionEvent(this);
|
||||||
for (String name : _sessionData.getKeys())
|
for (String name : _sessionData.getKeys())
|
||||||
{
|
{
|
||||||
Object value = _sessionData.getAttribute(name);
|
Object value = _sessionData.getAttribute(name);
|
||||||
if (value instanceof HttpSessionActivationListener)
|
if (value instanceof HttpSessionActivationListener)
|
||||||
|
|
|
@ -45,6 +45,18 @@
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.eclipse.jetty</groupId>
|
||||||
|
<artifactId>jetty-alpn-server</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.eclipse.jetty</groupId>
|
||||||
|
<artifactId>jetty-alpn-java-server</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.eclipse.jetty.http2</groupId>
|
<groupId>org.eclipse.jetty.http2</groupId>
|
||||||
<artifactId>http2-http-client-transport</artifactId>
|
<artifactId>http2-http-client-transport</artifactId>
|
||||||
|
|
|
@ -19,23 +19,32 @@
|
||||||
package org.eclipse.jetty.websocket.tests;
|
package org.eclipse.jetty.websocket.tests;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
import org.eclipse.jetty.alpn.server.ALPNServerConnectionFactory;
|
||||||
import org.eclipse.jetty.client.HttpClient;
|
import org.eclipse.jetty.client.HttpClient;
|
||||||
import org.eclipse.jetty.client.dynamic.HttpClientTransportDynamic;
|
import org.eclipse.jetty.client.dynamic.HttpClientTransportDynamic;
|
||||||
import org.eclipse.jetty.client.http.HttpClientConnectionFactory;
|
import org.eclipse.jetty.client.http.HttpClientConnectionFactory;
|
||||||
|
import org.eclipse.jetty.http2.ErrorCode;
|
||||||
|
import org.eclipse.jetty.http2.HTTP2Cipher;
|
||||||
import org.eclipse.jetty.http2.client.HTTP2Client;
|
import org.eclipse.jetty.http2.client.HTTP2Client;
|
||||||
import org.eclipse.jetty.http2.client.http.ClientConnectionFactoryOverHTTP2;
|
import org.eclipse.jetty.http2.client.http.ClientConnectionFactoryOverHTTP2;
|
||||||
|
import org.eclipse.jetty.http2.server.AbstractHTTP2ServerConnectionFactory;
|
||||||
import org.eclipse.jetty.http2.server.HTTP2CServerConnectionFactory;
|
import org.eclipse.jetty.http2.server.HTTP2CServerConnectionFactory;
|
||||||
|
import org.eclipse.jetty.http2.server.HTTP2ServerConnectionFactory;
|
||||||
import org.eclipse.jetty.io.ClientConnectionFactory;
|
import org.eclipse.jetty.io.ClientConnectionFactory;
|
||||||
import org.eclipse.jetty.io.ClientConnector;
|
import org.eclipse.jetty.io.ClientConnector;
|
||||||
import org.eclipse.jetty.server.HttpConfiguration;
|
import org.eclipse.jetty.server.HttpConfiguration;
|
||||||
import org.eclipse.jetty.server.HttpConnectionFactory;
|
import org.eclipse.jetty.server.HttpConnectionFactory;
|
||||||
|
import org.eclipse.jetty.server.SecureRequestCustomizer;
|
||||||
import org.eclipse.jetty.server.Server;
|
import org.eclipse.jetty.server.Server;
|
||||||
import org.eclipse.jetty.server.ServerConnector;
|
import org.eclipse.jetty.server.ServerConnector;
|
||||||
|
import org.eclipse.jetty.server.SslConnectionFactory;
|
||||||
import org.eclipse.jetty.servlet.ServletContextHandler;
|
import org.eclipse.jetty.servlet.ServletContextHandler;
|
||||||
import org.eclipse.jetty.servlet.ServletHolder;
|
import org.eclipse.jetty.servlet.ServletHolder;
|
||||||
|
import org.eclipse.jetty.util.ssl.SslContextFactory;
|
||||||
import org.eclipse.jetty.util.thread.QueuedThreadPool;
|
import org.eclipse.jetty.util.thread.QueuedThreadPool;
|
||||||
import org.eclipse.jetty.websocket.api.Session;
|
import org.eclipse.jetty.websocket.api.Session;
|
||||||
import org.eclipse.jetty.websocket.api.StatusCode;
|
import org.eclipse.jetty.websocket.api.StatusCode;
|
||||||
|
@ -44,9 +53,12 @@ import org.eclipse.jetty.websocket.server.JettyWebSocketServlet;
|
||||||
import org.eclipse.jetty.websocket.server.JettyWebSocketServletFactory;
|
import org.eclipse.jetty.websocket.server.JettyWebSocketServletFactory;
|
||||||
import org.eclipse.jetty.websocket.server.config.JettyWebSocketServletContainerInitializer;
|
import org.eclipse.jetty.websocket.server.config.JettyWebSocketServletContainerInitializer;
|
||||||
import org.junit.jupiter.api.AfterEach;
|
import org.junit.jupiter.api.AfterEach;
|
||||||
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
import static org.hamcrest.Matchers.containsStringIgnoringCase;
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||||
|
@ -56,6 +68,7 @@ public class WebSocketOverHTTP2Test
|
||||||
{
|
{
|
||||||
private Server server;
|
private Server server;
|
||||||
private ServerConnector connector;
|
private ServerConnector connector;
|
||||||
|
private ServerConnector tlsConnector;
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
public void startServer() throws Exception
|
public void startServer() throws Exception
|
||||||
|
@ -63,12 +76,27 @@ public class WebSocketOverHTTP2Test
|
||||||
QueuedThreadPool serverThreads = new QueuedThreadPool();
|
QueuedThreadPool serverThreads = new QueuedThreadPool();
|
||||||
serverThreads.setName("server");
|
serverThreads.setName("server");
|
||||||
server = new Server(serverThreads);
|
server = new Server(serverThreads);
|
||||||
HttpConfiguration httpConfiguration = new HttpConfiguration();
|
HttpConfiguration httpConfig = new HttpConfiguration();
|
||||||
HttpConnectionFactory h1 = new HttpConnectionFactory(httpConfiguration);
|
HttpConnectionFactory h1c = new HttpConnectionFactory(httpConfig);
|
||||||
HTTP2CServerConnectionFactory h2c = new HTTP2CServerConnectionFactory(httpConfiguration);
|
HTTP2CServerConnectionFactory h2c = new HTTP2CServerConnectionFactory(httpConfig);
|
||||||
connector = new ServerConnector(server, 1, 1, h1, h2c);
|
connector = new ServerConnector(server, 1, 1, h1c, h2c);
|
||||||
server.addConnector(connector);
|
server.addConnector(connector);
|
||||||
|
|
||||||
|
SslContextFactory.Server sslContextFactory = new SslContextFactory.Server();
|
||||||
|
sslContextFactory.setKeyStorePath("src/test/resources/keystore.p12");
|
||||||
|
sslContextFactory.setKeyStorePassword("storepwd");
|
||||||
|
sslContextFactory.setCipherComparator(HTTP2Cipher.COMPARATOR);
|
||||||
|
|
||||||
|
HttpConfiguration httpsConfig = new HttpConfiguration(httpConfig);
|
||||||
|
httpsConfig.addCustomizer(new SecureRequestCustomizer());
|
||||||
|
HttpConnectionFactory h1s = new HttpConnectionFactory(httpsConfig);
|
||||||
|
HTTP2ServerConnectionFactory h2s = new HTTP2ServerConnectionFactory(httpsConfig);
|
||||||
|
ALPNServerConnectionFactory alpn = new ALPNServerConnectionFactory();
|
||||||
|
alpn.setDefaultProtocol(h1c.getProtocol());
|
||||||
|
SslConnectionFactory ssl = new SslConnectionFactory(sslContextFactory, alpn.getProtocol());
|
||||||
|
tlsConnector = new ServerConnector(server, 1, 1, ssl, alpn, h2s, h1s);
|
||||||
|
server.addConnector(tlsConnector);
|
||||||
|
|
||||||
ServletContextHandler context = new ServletContextHandler(server, "/");
|
ServletContextHandler context = new ServletContextHandler(server, "/");
|
||||||
context.addServlet(new ServletHolder(new JettyWebSocketServlet()
|
context.addServlet(new ServletHolder(new JettyWebSocketServlet()
|
||||||
{
|
{
|
||||||
|
@ -128,4 +156,30 @@ public class WebSocketOverHTTP2Test
|
||||||
assertEquals(StatusCode.NORMAL, wsEndPoint.statusCode);
|
assertEquals(StatusCode.NORMAL, wsEndPoint.statusCode);
|
||||||
assertNull(wsEndPoint.error);
|
assertNull(wsEndPoint.error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testConnectProtocolDisabled() throws Exception
|
||||||
|
{
|
||||||
|
AbstractHTTP2ServerConnectionFactory h2c = connector.getBean(AbstractHTTP2ServerConnectionFactory.class);
|
||||||
|
h2c.setConnectProtocolEnabled(false);
|
||||||
|
|
||||||
|
ClientConnector clientConnector = new ClientConnector();
|
||||||
|
QueuedThreadPool clientThreads = new QueuedThreadPool();
|
||||||
|
clientThreads.setName("client");
|
||||||
|
clientConnector.setExecutor(clientThreads);
|
||||||
|
HTTP2Client http2Client = new HTTP2Client(clientConnector);
|
||||||
|
HttpClient httpClient = new HttpClient(new HttpClientTransportDynamic(clientConnector, new ClientConnectionFactoryOverHTTP2.H2C(http2Client)));
|
||||||
|
|
||||||
|
WebSocketClient wsClient = new WebSocketClient(httpClient);
|
||||||
|
wsClient.start();
|
||||||
|
|
||||||
|
EventSocket wsEndPoint = new EventSocket();
|
||||||
|
URI uri = URI.create("ws://localhost:" + connector.getLocalPort() + "/ws/echo");
|
||||||
|
|
||||||
|
ExecutionException failure = Assertions.assertThrows(ExecutionException.class, () ->
|
||||||
|
wsClient.connect(wsEndPoint, uri).get(5, TimeUnit.SECONDS));
|
||||||
|
|
||||||
|
Throwable cause = failure.getCause();
|
||||||
|
assertThat(cause.getMessage(), containsStringIgnoringCase(ErrorCode.PROTOCOL_ERROR.name()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Binary file not shown.
|
@ -53,7 +53,7 @@ import org.eclipse.jetty.websocket.core.server.WebSocketNegotiator;
|
||||||
|
|
||||||
public abstract class AbstractHandshaker implements Handshaker
|
public abstract class AbstractHandshaker implements Handshaker
|
||||||
{
|
{
|
||||||
protected static final Logger LOG = Log.getLogger(RFC8441Handshaker.class);
|
protected static final Logger LOG = Log.getLogger(AbstractHandshaker.class);
|
||||||
private static final HttpField SERVER_VERSION = new PreEncodedHttpField(HttpHeader.SERVER, HttpConfiguration.SERVER_VERSION);
|
private static final HttpField SERVER_VERSION = new PreEncodedHttpField(HttpHeader.SERVER, HttpConfiguration.SERVER_VERSION);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -98,7 +98,6 @@ public abstract class AbstractHandshaker implements Handshaker
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Validate negotiated protocol
|
// Validate negotiated protocol
|
||||||
String protocol = negotiation.getSubprotocol();
|
String protocol = negotiation.getSubprotocol();
|
||||||
List<String> offeredProtocols = negotiation.getOfferedSubprotocols();
|
List<String> offeredProtocols = negotiation.getOfferedSubprotocols();
|
||||||
|
|
|
@ -66,7 +66,7 @@ public final class RFC6455Handshaker extends AbstractHandshaker
|
||||||
@Override
|
@Override
|
||||||
protected Negotiation newNegotiation(HttpServletRequest request, HttpServletResponse response, WebSocketComponents webSocketComponents)
|
protected Negotiation newNegotiation(HttpServletRequest request, HttpServletResponse response, WebSocketComponents webSocketComponents)
|
||||||
{
|
{
|
||||||
return new RFC6544Negotiation(Request.getBaseRequest(request), request, response, webSocketComponents);
|
return new RFC6455Negotiation(Request.getBaseRequest(request), request, response, webSocketComponents);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -75,7 +75,7 @@ public final class RFC6455Handshaker extends AbstractHandshaker
|
||||||
boolean result = super.validateNegotiation(negotiation);
|
boolean result = super.validateNegotiation(negotiation);
|
||||||
if (!result)
|
if (!result)
|
||||||
return false;
|
return false;
|
||||||
if (((RFC6544Negotiation)negotiation).getKey() == null)
|
if (((RFC6455Negotiation)negotiation).getKey() == null)
|
||||||
throw new BadMessageException("Missing request header 'Sec-WebSocket-Key'");
|
throw new BadMessageException("Missing request header 'Sec-WebSocket-Key'");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -95,6 +95,6 @@ public final class RFC6455Handshaker extends AbstractHandshaker
|
||||||
HttpFields responseFields = response.getHttpFields();
|
HttpFields responseFields = response.getHttpFields();
|
||||||
responseFields.put(UPGRADE_WEBSOCKET);
|
responseFields.put(UPGRADE_WEBSOCKET);
|
||||||
responseFields.put(CONNECTION_UPGRADE);
|
responseFields.put(CONNECTION_UPGRADE);
|
||||||
responseFields.put(HttpHeader.SEC_WEBSOCKET_ACCEPT, WebSocketCore.hashKey(((RFC6544Negotiation)negotiation).getKey()));
|
responseFields.put(HttpHeader.SEC_WEBSOCKET_ACCEPT, WebSocketCore.hashKey(((RFC6455Negotiation)negotiation).getKey()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,12 +29,12 @@ import org.eclipse.jetty.server.Request;
|
||||||
import org.eclipse.jetty.websocket.core.WebSocketComponents;
|
import org.eclipse.jetty.websocket.core.WebSocketComponents;
|
||||||
import org.eclipse.jetty.websocket.core.server.Negotiation;
|
import org.eclipse.jetty.websocket.core.server.Negotiation;
|
||||||
|
|
||||||
public class RFC6544Negotiation extends Negotiation
|
public class RFC6455Negotiation extends Negotiation
|
||||||
{
|
{
|
||||||
private boolean successful;
|
private boolean successful;
|
||||||
private String key;
|
private String key;
|
||||||
|
|
||||||
public RFC6544Negotiation(Request baseRequest, HttpServletRequest request, HttpServletResponse response, WebSocketComponents components) throws BadMessageException
|
public RFC6455Negotiation(Request baseRequest, HttpServletRequest request, HttpServletResponse response, WebSocketComponents components) throws BadMessageException
|
||||||
{
|
{
|
||||||
super(baseRequest, request, response, components);
|
super(baseRequest, request, response, components);
|
||||||
}
|
}
|
Loading…
Reference in New Issue