Fixed bug where subprotocol not sent by client
This commit is contained in:
parent
49142f36c8
commit
1bf045a7ba
@ -35,7 +35,7 @@ public abstract class WebSocketClientHandshaker {
|
|||||||
|
|
||||||
private final String expectedSubprotocol;
|
private final String expectedSubprotocol;
|
||||||
|
|
||||||
private String actualSubprotocol;
|
private String actualSubprotocol = null;
|
||||||
|
|
||||||
protected final Map<String, String> customHeaders;
|
protected final Map<String, String> customHeaders;
|
||||||
|
|
||||||
@ -68,7 +68,7 @@ public abstract class WebSocketClientHandshaker {
|
|||||||
* @param version
|
* @param version
|
||||||
* Version of web socket specification to use to connect to the server
|
* Version of web socket specification to use to connect to the server
|
||||||
* @param subprotocol
|
* @param subprotocol
|
||||||
* Sub protocol request sent to the server.
|
* CSV of requested subprotocol(s) sent to the server.
|
||||||
* @param customHeaders
|
* @param customHeaders
|
||||||
* Map of custom headers to add to the client request
|
* Map of custom headers to add to the client request
|
||||||
* @param maxFramePayloadLength
|
* @param maxFramePayloadLength
|
||||||
@ -78,7 +78,7 @@ public abstract class WebSocketClientHandshaker {
|
|||||||
Map<String, String> customHeaders, long maxFramePayloadLength) {
|
Map<String, String> customHeaders, long maxFramePayloadLength) {
|
||||||
this.webSocketUrl = webSocketUrl;
|
this.webSocketUrl = webSocketUrl;
|
||||||
this.version = version;
|
this.version = version;
|
||||||
expectedSubprotocol = subprotocol;
|
this.expectedSubprotocol = subprotocol;
|
||||||
this.customHeaders = customHeaders;
|
this.customHeaders = customHeaders;
|
||||||
this.maxFramePayloadLength = maxFramePayloadLength;
|
this.maxFramePayloadLength = maxFramePayloadLength;
|
||||||
}
|
}
|
||||||
@ -116,14 +116,15 @@ public abstract class WebSocketClientHandshaker {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the sub protocol request sent to the server as specified in the constructor
|
* Returns the CSV of requested subprotocol(s) sent to the server as specified in the constructor
|
||||||
*/
|
*/
|
||||||
public String getExpectedSubprotocol() {
|
public String getExpectedSubprotocol() {
|
||||||
return expectedSubprotocol;
|
return expectedSubprotocol;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the sub protocol response and sent by the server. Only available after end of handshake.
|
* Returns the subprotocol response sent by the server. Only available after end of handshake.
|
||||||
|
* Null if no subprotocol was requested or confirmed by the server.
|
||||||
*/
|
*/
|
||||||
public String getActualSubprotocol() {
|
public String getActualSubprotocol() {
|
||||||
return actualSubprotocol;
|
return actualSubprotocol;
|
||||||
|
@ -170,8 +170,9 @@ public class WebSocketClientHandshaker00 extends WebSocketClientHandshaker {
|
|||||||
|
|
||||||
request.addHeader(Names.SEC_WEBSOCKET_KEY1, key1);
|
request.addHeader(Names.SEC_WEBSOCKET_KEY1, key1);
|
||||||
request.addHeader(Names.SEC_WEBSOCKET_KEY2, key2);
|
request.addHeader(Names.SEC_WEBSOCKET_KEY2, key2);
|
||||||
if (getExpectedSubprotocol() != null && !getExpectedSubprotocol().equals("")) {
|
String expectedSubprotocol = this.getExpectedSubprotocol();
|
||||||
request.addHeader(Names.SEC_WEBSOCKET_PROTOCOL, getExpectedSubprotocol());
|
if (expectedSubprotocol != null && !expectedSubprotocol.equals("")) {
|
||||||
|
request.addHeader(Names.SEC_WEBSOCKET_PROTOCOL, expectedSubprotocol);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (customHeaders != null) {
|
if (customHeaders != null) {
|
||||||
@ -236,8 +237,8 @@ public class WebSocketClientHandshaker00 extends WebSocketClientHandshaker {
|
|||||||
throw new WebSocketHandshakeException("Invalid challenge");
|
throw new WebSocketHandshakeException("Invalid challenge");
|
||||||
}
|
}
|
||||||
|
|
||||||
String protocol = response.getHeader(Names.SEC_WEBSOCKET_PROTOCOL);
|
String subprotocol = response.getHeader(Names.SEC_WEBSOCKET_PROTOCOL);
|
||||||
setActualSubprotocol(protocol);
|
setActualSubprotocol(subprotocol);
|
||||||
|
|
||||||
channel.getPipeline().replace(HttpResponseDecoder.class, "ws-decoder",
|
channel.getPipeline().replace(HttpResponseDecoder.class, "ws-decoder",
|
||||||
new WebSocket00FrameDecoder(this.getMaxFramePayloadLength()));
|
new WebSocket00FrameDecoder(this.getMaxFramePayloadLength()));
|
||||||
|
@ -49,8 +49,6 @@ public class WebSocketClientHandshaker08 extends WebSocketClientHandshaker {
|
|||||||
|
|
||||||
private String expectedChallengeResponseString;
|
private String expectedChallengeResponseString;
|
||||||
|
|
||||||
private static final String protocol = null;
|
|
||||||
|
|
||||||
private final boolean allowExtensions;
|
private final boolean allowExtensions;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -158,10 +156,11 @@ public class WebSocketClientHandshaker08 extends WebSocketClientHandshaker {
|
|||||||
// See https://github.com/netty/netty/issues/264
|
// See https://github.com/netty/netty/issues/264
|
||||||
request.addHeader(Names.SEC_WEBSOCKET_ORIGIN, originValue);
|
request.addHeader(Names.SEC_WEBSOCKET_ORIGIN, originValue);
|
||||||
|
|
||||||
|
String expectedSubprotocol = this.getExpectedSubprotocol();
|
||||||
if (protocol != null && !protocol.equals("")) {
|
if (expectedSubprotocol != null && !expectedSubprotocol.equals("")) {
|
||||||
request.addHeader(Names.SEC_WEBSOCKET_PROTOCOL, protocol);
|
request.addHeader(Names.SEC_WEBSOCKET_PROTOCOL, expectedSubprotocol);
|
||||||
}
|
}
|
||||||
|
|
||||||
request.addHeader(Names.SEC_WEBSOCKET_VERSION, "8");
|
request.addHeader(Names.SEC_WEBSOCKET_VERSION, "8");
|
||||||
|
|
||||||
if (customHeaders != null) {
|
if (customHeaders != null) {
|
||||||
@ -226,6 +225,9 @@ public class WebSocketClientHandshaker08 extends WebSocketClientHandshaker {
|
|||||||
expectedChallengeResponseString));
|
expectedChallengeResponseString));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String subprotocol = response.getHeader(Names.SEC_WEBSOCKET_PROTOCOL);
|
||||||
|
setActualSubprotocol(subprotocol);
|
||||||
|
|
||||||
channel.getPipeline().replace(HttpResponseDecoder.class, "ws-decoder",
|
channel.getPipeline().replace(HttpResponseDecoder.class, "ws-decoder",
|
||||||
new WebSocket08FrameDecoder(false, allowExtensions, this.getMaxFramePayloadLength()));
|
new WebSocket08FrameDecoder(false, allowExtensions, this.getMaxFramePayloadLength()));
|
||||||
|
|
||||||
|
@ -49,8 +49,6 @@ public class WebSocketClientHandshaker13 extends WebSocketClientHandshaker {
|
|||||||
|
|
||||||
private String expectedChallengeResponseString;
|
private String expectedChallengeResponseString;
|
||||||
|
|
||||||
private static final String protocol = null;
|
|
||||||
|
|
||||||
private final boolean allowExtensions;
|
private final boolean allowExtensions;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -154,9 +152,11 @@ public class WebSocketClientHandshaker13 extends WebSocketClientHandshaker {
|
|||||||
}
|
}
|
||||||
request.addHeader(Names.ORIGIN, originValue);
|
request.addHeader(Names.ORIGIN, originValue);
|
||||||
|
|
||||||
if (protocol != null && !protocol.equals("")) {
|
String expectedSubprotocol = this.getExpectedSubprotocol();
|
||||||
request.addHeader(Names.SEC_WEBSOCKET_PROTOCOL, protocol);
|
if (expectedSubprotocol != null && !expectedSubprotocol.equals("")) {
|
||||||
|
request.addHeader(Names.SEC_WEBSOCKET_PROTOCOL, expectedSubprotocol);
|
||||||
}
|
}
|
||||||
|
|
||||||
request.addHeader(Names.SEC_WEBSOCKET_VERSION, "13");
|
request.addHeader(Names.SEC_WEBSOCKET_VERSION, "13");
|
||||||
|
|
||||||
if (customHeaders != null) {
|
if (customHeaders != null) {
|
||||||
@ -221,6 +221,9 @@ public class WebSocketClientHandshaker13 extends WebSocketClientHandshaker {
|
|||||||
expectedChallengeResponseString));
|
expectedChallengeResponseString));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String subprotocol = response.getHeader(Names.SEC_WEBSOCKET_PROTOCOL);
|
||||||
|
setActualSubprotocol(subprotocol);
|
||||||
|
|
||||||
channel.getPipeline().replace(HttpResponseDecoder.class, "ws-decoder",
|
channel.getPipeline().replace(HttpResponseDecoder.class, "ws-decoder",
|
||||||
new WebSocket13FrameDecoder(false, allowExtensions, this.getMaxFramePayloadLength()));
|
new WebSocket13FrameDecoder(false, allowExtensions, this.getMaxFramePayloadLength()));
|
||||||
|
|
||||||
|
@ -37,8 +37,11 @@ public abstract class WebSocketServerHandshaker {
|
|||||||
|
|
||||||
private final long maxFramePayloadLength;
|
private final long maxFramePayloadLength;
|
||||||
|
|
||||||
|
private String selectedSubprotocol = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link ChannelFutureListener} which will call {@link Channels#fireExceptionCaught(org.jboss.netty.channel.ChannelHandlerContext, Throwable)}
|
* {@link ChannelFutureListener} which will call
|
||||||
|
* {@link Channels#fireExceptionCaught(org.jboss.netty.channel.ChannelHandlerContext, Throwable)}
|
||||||
* if the {@link ChannelFuture} was not successful.
|
* if the {@link ChannelFuture} was not successful.
|
||||||
*/
|
*/
|
||||||
public static final ChannelFutureListener HANDSHAKE_LISTENER = new ChannelFutureListener() {
|
public static final ChannelFutureListener HANDSHAKE_LISTENER = new ChannelFutureListener() {
|
||||||
@ -55,10 +58,12 @@ public abstract class WebSocketServerHandshaker {
|
|||||||
* @param version
|
* @param version
|
||||||
* the protocol version
|
* the protocol version
|
||||||
* @param webSocketUrl
|
* @param webSocketUrl
|
||||||
* URL for web socket communications. e.g "ws://myhost.com/mypath". Subsequent web socket frames will be
|
* URL for web socket communications. e.g
|
||||||
|
* "ws://myhost.com/mypath". Subsequent web socket frames will be
|
||||||
* sent to this URL.
|
* sent to this URL.
|
||||||
* @param subprotocols
|
* @param subprotocols
|
||||||
* CSV of supported protocols. Null if sub protocols not supported.
|
* CSV of supported protocols. Null if sub protocols not
|
||||||
|
* supported.
|
||||||
*/
|
*/
|
||||||
protected WebSocketServerHandshaker(WebSocketVersion version, String webSocketUrl, String subprotocols) {
|
protected WebSocketServerHandshaker(WebSocketVersion version, String webSocketUrl, String subprotocols) {
|
||||||
this(version, webSocketUrl, subprotocols, Long.MAX_VALUE);
|
this(version, webSocketUrl, subprotocols, Long.MAX_VALUE);
|
||||||
@ -70,10 +75,12 @@ public abstract class WebSocketServerHandshaker {
|
|||||||
* @param version
|
* @param version
|
||||||
* the protocol version
|
* the protocol version
|
||||||
* @param webSocketUrl
|
* @param webSocketUrl
|
||||||
* URL for web socket communications. e.g "ws://myhost.com/mypath". Subsequent web socket frames will be
|
* URL for web socket communications. e.g
|
||||||
|
* "ws://myhost.com/mypath". Subsequent web socket frames will be
|
||||||
* sent to this URL.
|
* sent to this URL.
|
||||||
* @param subprotocols
|
* @param subprotocols
|
||||||
* CSV of supported protocols. Null if sub protocols not supported.
|
* CSV of supported protocols. Null if sub protocols not
|
||||||
|
* supported.
|
||||||
* @param maxFramePayloadLength
|
* @param maxFramePayloadLength
|
||||||
* Maximum length of a frame's payload
|
* Maximum length of a frame's payload
|
||||||
*/
|
*/
|
||||||
@ -93,7 +100,6 @@ public abstract class WebSocketServerHandshaker {
|
|||||||
this.maxFramePayloadLength = maxFramePayloadLength;
|
this.maxFramePayloadLength = maxFramePayloadLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the URL of the web socket
|
* Returns the URL of the web socket
|
||||||
*/
|
*/
|
||||||
@ -106,7 +112,7 @@ public abstract class WebSocketServerHandshaker {
|
|||||||
*/
|
*/
|
||||||
public Set<String> getSubprotocols() {
|
public Set<String> getSubprotocols() {
|
||||||
Set<String> ret = new LinkedHashSet<String>();
|
Set<String> ret = new LinkedHashSet<String>();
|
||||||
for (String p: this.subprotocols) {
|
for (String p : this.subprotocols) {
|
||||||
ret.add(p);
|
ret.add(p);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
@ -158,11 +164,11 @@ public abstract class WebSocketServerHandshaker {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
String[] requesteSubprotocolArray = requestedSubprotocols.split(",");
|
String[] requestedSubprotocolArray = requestedSubprotocols.split(",");
|
||||||
for (String p: requesteSubprotocolArray) {
|
for (String p : requestedSubprotocolArray) {
|
||||||
String requestedSubprotocol = p.trim();
|
String requestedSubprotocol = p.trim();
|
||||||
|
|
||||||
for (String supportedSubprotocol: subprotocols) {
|
for (String supportedSubprotocol : subprotocols) {
|
||||||
if (requestedSubprotocol.equals(supportedSubprotocol)) {
|
if (requestedSubprotocol.equals(supportedSubprotocol)) {
|
||||||
return requestedSubprotocol;
|
return requestedSubprotocol;
|
||||||
}
|
}
|
||||||
@ -172,4 +178,19 @@ public abstract class WebSocketServerHandshaker {
|
|||||||
// No match found
|
// No match found
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the selected subprotocol. Null if no subprotocol has been selected.
|
||||||
|
* <p>
|
||||||
|
* This is only available AFTER <tt>handshake()</tt> has been called.
|
||||||
|
* </p>
|
||||||
|
*/
|
||||||
|
public String getSelectedSubprotocol() {
|
||||||
|
return selectedSubprotocol;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setSelectedSubprotocol(String value) {
|
||||||
|
selectedSubprotocol = value;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -151,9 +151,15 @@ public class WebSocketServerHandshaker00 extends WebSocketServerHandshaker {
|
|||||||
// New handshake method with a challenge:
|
// New handshake method with a challenge:
|
||||||
res.addHeader(SEC_WEBSOCKET_ORIGIN, req.getHeader(ORIGIN));
|
res.addHeader(SEC_WEBSOCKET_ORIGIN, req.getHeader(ORIGIN));
|
||||||
res.addHeader(SEC_WEBSOCKET_LOCATION, getWebSocketUrl());
|
res.addHeader(SEC_WEBSOCKET_LOCATION, getWebSocketUrl());
|
||||||
String protocol = req.getHeader(SEC_WEBSOCKET_PROTOCOL);
|
String subprotocols = req.getHeader(Names.SEC_WEBSOCKET_PROTOCOL);
|
||||||
if (protocol != null) {
|
if (subprotocols != null) {
|
||||||
res.addHeader(SEC_WEBSOCKET_PROTOCOL, selectSubprotocol(protocol));
|
String selectedSubprotocol = selectSubprotocol(subprotocols);
|
||||||
|
if (selectedSubprotocol == null) {
|
||||||
|
throw new WebSocketHandshakeException("Requested subprotocol(s) not supported: " + subprotocols);
|
||||||
|
} else {
|
||||||
|
res.addHeader(Names.SEC_WEBSOCKET_PROTOCOL, selectedSubprotocol);
|
||||||
|
this.setSelectedSubprotocol(selectedSubprotocol);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate the answer of the challenge.
|
// Calculate the answer of the challenge.
|
||||||
|
@ -156,9 +156,15 @@ public class WebSocketServerHandshaker08 extends WebSocketServerHandshaker {
|
|||||||
res.addHeader(Names.UPGRADE, WEBSOCKET.toLowerCase());
|
res.addHeader(Names.UPGRADE, WEBSOCKET.toLowerCase());
|
||||||
res.addHeader(Names.CONNECTION, Names.UPGRADE);
|
res.addHeader(Names.CONNECTION, Names.UPGRADE);
|
||||||
res.addHeader(Names.SEC_WEBSOCKET_ACCEPT, accept);
|
res.addHeader(Names.SEC_WEBSOCKET_ACCEPT, accept);
|
||||||
String protocol = req.getHeader(Names.SEC_WEBSOCKET_PROTOCOL);
|
String subprotocols = req.getHeader(Names.SEC_WEBSOCKET_PROTOCOL);
|
||||||
if (protocol != null) {
|
if (subprotocols != null) {
|
||||||
res.addHeader(Names.SEC_WEBSOCKET_PROTOCOL, selectSubprotocol(protocol));
|
String selectedSubprotocol = selectSubprotocol(subprotocols);
|
||||||
|
if (selectedSubprotocol == null) {
|
||||||
|
throw new WebSocketHandshakeException("Requested subprotocol(s) not supported: " + subprotocols);
|
||||||
|
} else {
|
||||||
|
res.addHeader(Names.SEC_WEBSOCKET_PROTOCOL, selectedSubprotocol);
|
||||||
|
this.setSelectedSubprotocol(selectedSubprotocol);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ChannelFuture future = channel.write(res);
|
ChannelFuture future = channel.write(res);
|
||||||
|
@ -39,10 +39,11 @@ import org.jboss.netty.util.CharsetUtil;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
* Performs server side opening and closing handshakes for <a href="http://tools.ietf.org/html/rfc6455 ">RFC 6455</a>
|
* Performs server side opening and closing handshakes for <a
|
||||||
* (originally web socket specification version <a
|
* href="http://tools.ietf.org/html/rfc6455 ">RFC 6455</a> (originally web
|
||||||
* href="http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-17" >draft-ietf-hybi-thewebsocketprotocol-
|
* socket specification version <a
|
||||||
* 17</a>).
|
* href="http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-17"
|
||||||
|
* >draft-ietf-hybi-thewebsocketprotocol- 17</a>).
|
||||||
* </p>
|
* </p>
|
||||||
*/
|
*/
|
||||||
public class WebSocketServerHandshaker13 extends WebSocketServerHandshaker {
|
public class WebSocketServerHandshaker13 extends WebSocketServerHandshaker {
|
||||||
@ -57,12 +58,14 @@ public class WebSocketServerHandshaker13 extends WebSocketServerHandshaker {
|
|||||||
* Constructor using defaults
|
* Constructor using defaults
|
||||||
*
|
*
|
||||||
* @param webSocketURL
|
* @param webSocketURL
|
||||||
* URL for web socket communications. e.g "ws://myhost.com/mypath". Subsequent web socket frames will be
|
* URL for web socket communications. e.g
|
||||||
|
* "ws://myhost.com/mypath". Subsequent web socket frames will be
|
||||||
* sent to this URL.
|
* sent to this URL.
|
||||||
* @param subprotocols
|
* @param subprotocols
|
||||||
* CSV of supported protocols
|
* CSV of supported protocols
|
||||||
* @param allowExtensions
|
* @param allowExtensions
|
||||||
* Allow extensions to be used in the reserved bits of the web socket frame
|
* Allow extensions to be used in the reserved bits of the web
|
||||||
|
* socket frame
|
||||||
*/
|
*/
|
||||||
public WebSocketServerHandshaker13(String webSocketURL, String subprotocols, boolean allowExtensions) {
|
public WebSocketServerHandshaker13(String webSocketURL, String subprotocols, boolean allowExtensions) {
|
||||||
this(webSocketURL, subprotocols, allowExtensions, Long.MAX_VALUE);
|
this(webSocketURL, subprotocols, allowExtensions, Long.MAX_VALUE);
|
||||||
@ -72,15 +75,18 @@ public class WebSocketServerHandshaker13 extends WebSocketServerHandshaker {
|
|||||||
* Constructor specifying the destination web socket location
|
* Constructor specifying the destination web socket location
|
||||||
*
|
*
|
||||||
* @param webSocketURL
|
* @param webSocketURL
|
||||||
* URL for web socket communications. e.g "ws://myhost.com/mypath". Subsequent web socket frames will be
|
* URL for web socket communications. e.g
|
||||||
|
* "ws://myhost.com/mypath". Subsequent web socket frames will be
|
||||||
* sent to this URL.
|
* sent to this URL.
|
||||||
* @param subprotocols
|
* @param subprotocols
|
||||||
* CSV of supported protocols
|
* CSV of supported protocols
|
||||||
* @param allowExtensions
|
* @param allowExtensions
|
||||||
* Allow extensions to be used in the reserved bits of the web socket frame
|
* Allow extensions to be used in the reserved bits of the web
|
||||||
|
* socket frame
|
||||||
* @param maxFramePayloadLength
|
* @param maxFramePayloadLength
|
||||||
* Maximum allowable frame payload length. Setting this value to your application's requirement may
|
* Maximum allowable frame payload length. Setting this value to
|
||||||
* reduce denial of service attacks using long data frames.
|
* your application's requirement may reduce denial of service
|
||||||
|
* attacks using long data frames.
|
||||||
*/
|
*/
|
||||||
public WebSocketServerHandshaker13(String webSocketURL, String subprotocols, boolean allowExtensions,
|
public WebSocketServerHandshaker13(String webSocketURL, String subprotocols, boolean allowExtensions,
|
||||||
long maxFramePayloadLength) {
|
long maxFramePayloadLength) {
|
||||||
@ -88,12 +94,11 @@ public class WebSocketServerHandshaker13 extends WebSocketServerHandshaker {
|
|||||||
this.allowExtensions = allowExtensions;
|
this.allowExtensions = allowExtensions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
* Handle the web socket handshake for the web socket specification <a href=
|
* Handle the web socket handshake for the web socket specification <a href=
|
||||||
* "http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-17">HyBi versions 13-17</a>. Versions 13-17
|
* "http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-17">HyBi
|
||||||
* share the same wire protocol.
|
* versions 13-17</a>. Versions 13-17 share the same wire protocol.
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
@ -158,9 +163,15 @@ public class WebSocketServerHandshaker13 extends WebSocketServerHandshaker {
|
|||||||
res.addHeader(Names.UPGRADE, WEBSOCKET.toLowerCase());
|
res.addHeader(Names.UPGRADE, WEBSOCKET.toLowerCase());
|
||||||
res.addHeader(Names.CONNECTION, Names.UPGRADE);
|
res.addHeader(Names.CONNECTION, Names.UPGRADE);
|
||||||
res.addHeader(Names.SEC_WEBSOCKET_ACCEPT, accept);
|
res.addHeader(Names.SEC_WEBSOCKET_ACCEPT, accept);
|
||||||
String protocol = req.getHeader(Names.SEC_WEBSOCKET_PROTOCOL);
|
String subprotocols = req.getHeader(Names.SEC_WEBSOCKET_PROTOCOL);
|
||||||
if (protocol != null) {
|
if (subprotocols != null) {
|
||||||
res.addHeader(Names.SEC_WEBSOCKET_PROTOCOL, selectSubprotocol(protocol));
|
String selectedSubprotocol = selectSubprotocol(subprotocols);
|
||||||
|
if (selectedSubprotocol == null) {
|
||||||
|
throw new WebSocketHandshakeException("Requested subprotocol(s) not supported: " + subprotocols);
|
||||||
|
} else {
|
||||||
|
res.addHeader(Names.SEC_WEBSOCKET_PROTOCOL, selectedSubprotocol);
|
||||||
|
this.setSelectedSubprotocol(selectedSubprotocol);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ChannelFuture future = channel.write(res);
|
ChannelFuture future = channel.write(res);
|
||||||
|
Loading…
Reference in New Issue
Block a user