Merge pull request #321 from veebs/WsSubprotocol
Fixed websocket bug where subprotocol not sent by client (master)
This commit is contained in:
commit
ddd2f22fcc
@ -35,7 +35,7 @@ public abstract class WebSocketClientHandshaker {
|
||||
|
||||
private final String expectedSubprotocol;
|
||||
|
||||
private String actualSubprotocol;
|
||||
private String actualSubprotocol = null;
|
||||
|
||||
protected final Map<String, String> customHeaders;
|
||||
|
||||
@ -50,7 +50,7 @@ public abstract class WebSocketClientHandshaker {
|
||||
* @param version
|
||||
* Version of web socket specification to use to connect to the server
|
||||
* @param subprotocol
|
||||
* Sub protocol request sent to the server.
|
||||
* CSV of requested subprotocol(s) sent to the server.
|
||||
* @param customHeaders
|
||||
* Map of custom headers to add to the client request
|
||||
*/
|
||||
@ -78,7 +78,7 @@ public abstract class WebSocketClientHandshaker {
|
||||
Map<String, String> customHeaders, long maxFramePayloadLength) {
|
||||
this.webSocketUrl = webSocketUrl;
|
||||
this.version = version;
|
||||
expectedSubprotocol = subprotocol;
|
||||
this.expectedSubprotocol = subprotocol;
|
||||
this.customHeaders = customHeaders;
|
||||
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() {
|
||||
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() {
|
||||
return actualSubprotocol;
|
||||
|
@ -169,10 +169,12 @@ public class WebSocketClientHandshaker00 extends WebSocketClientHandshaker {
|
||||
|
||||
request.addHeader(Names.SEC_WEBSOCKET_KEY1, key1);
|
||||
request.addHeader(Names.SEC_WEBSOCKET_KEY2, key2);
|
||||
if (getExpectedSubprotocol() != null && !getExpectedSubprotocol().equals("")) {
|
||||
request.addHeader(Names.SEC_WEBSOCKET_PROTOCOL, getExpectedSubprotocol());
|
||||
String expectedSubprotocol = this.getExpectedSubprotocol();
|
||||
if (expectedSubprotocol != null && !expectedSubprotocol.equals("")) {
|
||||
request.addHeader(Names.SEC_WEBSOCKET_PROTOCOL, expectedSubprotocol);
|
||||
}
|
||||
|
||||
|
||||
if (customHeaders != null) {
|
||||
for (String header : customHeaders.keySet()) {
|
||||
request.addHeader(header, customHeaders.get(header));
|
||||
@ -235,8 +237,8 @@ public class WebSocketClientHandshaker00 extends WebSocketClientHandshaker {
|
||||
throw new WebSocketHandshakeException("Invalid challenge");
|
||||
}
|
||||
|
||||
String protocol = response.getHeader(Names.SEC_WEBSOCKET_PROTOCOL);
|
||||
setActualSubprotocol(protocol);
|
||||
String subprotocol = response.getHeader(Names.SEC_WEBSOCKET_PROTOCOL);
|
||||
setActualSubprotocol(subprotocol);
|
||||
|
||||
channel.getPipeline().replace(HttpResponseDecoder.class, "ws-decoder",
|
||||
new WebSocket00FrameDecoder(this.getMaxFramePayloadLength()));
|
||||
|
@ -49,8 +49,6 @@ public class WebSocketClientHandshaker08 extends WebSocketClientHandshaker {
|
||||
|
||||
private String expectedChallengeResponseString;
|
||||
|
||||
private static final String protocol = null;
|
||||
|
||||
private final boolean allowExtensions;
|
||||
|
||||
/**
|
||||
@ -157,9 +155,11 @@ public class WebSocketClientHandshaker08 extends WebSocketClientHandshaker {
|
||||
// See https://github.com/netty/netty/issues/264
|
||||
request.addHeader(Names.SEC_WEBSOCKET_ORIGIN, originValue);
|
||||
|
||||
if (protocol != null && !protocol.equals("")) {
|
||||
request.addHeader(Names.SEC_WEBSOCKET_PROTOCOL, protocol);
|
||||
String expectedSubprotocol = this.getExpectedSubprotocol();
|
||||
if (expectedSubprotocol != null && !expectedSubprotocol.equals("")) {
|
||||
request.addHeader(Names.SEC_WEBSOCKET_PROTOCOL, expectedSubprotocol);
|
||||
}
|
||||
|
||||
request.addHeader(Names.SEC_WEBSOCKET_VERSION, "8");
|
||||
|
||||
if (customHeaders != null) {
|
||||
@ -224,6 +224,9 @@ public class WebSocketClientHandshaker08 extends WebSocketClientHandshaker {
|
||||
expectedChallengeResponseString));
|
||||
}
|
||||
|
||||
String subprotocol = response.getHeader(Names.SEC_WEBSOCKET_PROTOCOL);
|
||||
setActualSubprotocol(subprotocol);
|
||||
|
||||
channel.getPipeline().replace(HttpResponseDecoder.class, "ws-decoder",
|
||||
new WebSocket08FrameDecoder(false, allowExtensions, this.getMaxFramePayloadLength()));
|
||||
|
||||
|
@ -49,8 +49,6 @@ public class WebSocketClientHandshaker13 extends WebSocketClientHandshaker {
|
||||
|
||||
private String expectedChallengeResponseString;
|
||||
|
||||
private static final String protocol = null;
|
||||
|
||||
private final boolean allowExtensions;
|
||||
|
||||
/**
|
||||
@ -154,9 +152,11 @@ public class WebSocketClientHandshaker13 extends WebSocketClientHandshaker {
|
||||
}
|
||||
request.addHeader(Names.ORIGIN, originValue);
|
||||
|
||||
if (protocol != null && !protocol.equals("")) {
|
||||
request.addHeader(Names.SEC_WEBSOCKET_PROTOCOL, protocol);
|
||||
String expectedSubprotocol = this.getExpectedSubprotocol();
|
||||
if (expectedSubprotocol != null && !expectedSubprotocol.equals("")) {
|
||||
request.addHeader(Names.SEC_WEBSOCKET_PROTOCOL, expectedSubprotocol);
|
||||
}
|
||||
|
||||
request.addHeader(Names.SEC_WEBSOCKET_VERSION, "13");
|
||||
|
||||
if (customHeaders != null) {
|
||||
@ -221,6 +221,9 @@ public class WebSocketClientHandshaker13 extends WebSocketClientHandshaker {
|
||||
expectedChallengeResponseString));
|
||||
}
|
||||
|
||||
String subprotocol = response.getHeader(Names.SEC_WEBSOCKET_PROTOCOL);
|
||||
setActualSubprotocol(subprotocol);
|
||||
|
||||
channel.getPipeline().replace(HttpResponseDecoder.class, "ws-decoder",
|
||||
new WebSocket13FrameDecoder(false, allowExtensions, this.getMaxFramePayloadLength()));
|
||||
|
||||
|
@ -35,6 +35,8 @@ public abstract class WebSocketServerHandshaker {
|
||||
|
||||
private final long maxFramePayloadLength;
|
||||
|
||||
private String selectedSubprotocol = null;
|
||||
|
||||
/**
|
||||
* Constructor using default values
|
||||
*
|
||||
@ -143,8 +145,8 @@ public abstract class WebSocketServerHandshaker {
|
||||
return null;
|
||||
}
|
||||
|
||||
String[] requesteSubprotocolArray = requestedSubprotocols.split(",");
|
||||
for (String p : requesteSubprotocolArray) {
|
||||
String[] requestedSubprotocolArray = requestedSubprotocols.split(",");
|
||||
for (String p : requestedSubprotocolArray) {
|
||||
String requestedSubprotocol = p.trim();
|
||||
|
||||
for (String supportedSubprotocol : subprotocols) {
|
||||
@ -157,4 +159,19 @@ public abstract class WebSocketServerHandshaker {
|
||||
// No match found
|
||||
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:
|
||||
res.addHeader(SEC_WEBSOCKET_ORIGIN, req.getHeader(ORIGIN));
|
||||
res.addHeader(SEC_WEBSOCKET_LOCATION, getWebSocketUrl());
|
||||
String protocol = req.getHeader(SEC_WEBSOCKET_PROTOCOL);
|
||||
if (protocol != null) {
|
||||
res.addHeader(SEC_WEBSOCKET_PROTOCOL, selectSubprotocol(protocol));
|
||||
String subprotocols = req.getHeader(Names.SEC_WEBSOCKET_PROTOCOL);
|
||||
if (subprotocols != null) {
|
||||
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.
|
||||
|
@ -148,10 +148,17 @@ public class WebSocketServerHandshaker08 extends WebSocketServerHandshaker {
|
||||
res.addHeader(Names.UPGRADE, WEBSOCKET.toLowerCase());
|
||||
res.addHeader(Names.CONNECTION, Names.UPGRADE);
|
||||
res.addHeader(Names.SEC_WEBSOCKET_ACCEPT, accept);
|
||||
String protocol = req.getHeader(Names.SEC_WEBSOCKET_PROTOCOL);
|
||||
if (protocol != null) {
|
||||
res.addHeader(Names.SEC_WEBSOCKET_PROTOCOL, selectSubprotocol(protocol));
|
||||
String subprotocols = req.getHeader(Names.SEC_WEBSOCKET_PROTOCOL);
|
||||
if (subprotocols != null) {
|
||||
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);
|
||||
|
||||
|
@ -149,10 +149,17 @@ public class WebSocketServerHandshaker13 extends WebSocketServerHandshaker {
|
||||
res.addHeader(Names.UPGRADE, WEBSOCKET.toLowerCase());
|
||||
res.addHeader(Names.CONNECTION, Names.UPGRADE);
|
||||
res.addHeader(Names.SEC_WEBSOCKET_ACCEPT, accept);
|
||||
String protocol = req.getHeader(Names.SEC_WEBSOCKET_PROTOCOL);
|
||||
if (protocol != null) {
|
||||
res.addHeader(Names.SEC_WEBSOCKET_PROTOCOL, selectSubprotocol(protocol));
|
||||
String subprotocols = req.getHeader(Names.SEC_WEBSOCKET_PROTOCOL);
|
||||
if (subprotocols != null) {
|
||||
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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user