Fixed bug where subprotocol not sent by client

Conflicts:

	codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketClientHandshaker.java
	codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketClientHandshaker08.java
	codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketClientHandshaker13.java
	codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketServerHandshaker.java
This commit is contained in:
vibul 2012-05-12 21:05:15 +10:00 committed by Trustin Lee
parent 67ec4429cc
commit 4fc089829d
8 changed files with 75 additions and 25 deletions

View File

@ -98,14 +98,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;

View File

@ -152,10 +152,12 @@ public class WebSocketClientHandshaker00 extends WebSocketClientHandshaker {
request.addHeader(Names.ORIGIN, originValue); request.addHeader(Names.ORIGIN, originValue);
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) {
for (String header : customHeaders.keySet()) { for (String header : customHeaders.keySet()) {
request.addHeader(header, customHeaders.get(header)); request.addHeader(header, customHeaders.get(header));
@ -218,8 +220,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.pipeline().replace( channel.pipeline().replace(
HttpResponseDecoder.class, "ws-decoder", HttpResponseDecoder.class, "ws-decoder",

View File

@ -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;
/** /**
@ -134,9 +132,11 @@ public class WebSocketClientHandshaker08 extends WebSocketClientHandshaker {
} }
request.addHeader(Names.SEC_WEBSOCKET_ORIGIN, originValue); request.addHeader(Names.SEC_WEBSOCKET_ORIGIN, originValue);
if (protocol != null && !protocol.equals("")) { String expectedSubprotocol = 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, "8"); request.addHeader(Names.SEC_WEBSOCKET_VERSION, "8");
if (customHeaders != null) { if (customHeaders != null) {
@ -197,6 +197,9 @@ public class WebSocketClientHandshaker08 extends WebSocketClientHandshaker {
expectedChallengeResponseString)); expectedChallengeResponseString));
} }
String subprotocol = response.getHeader(Names.SEC_WEBSOCKET_PROTOCOL);
setActualSubprotocol(subprotocol);
channel.pipeline().replace(HttpResponseDecoder.class, "ws-decoder", channel.pipeline().replace(HttpResponseDecoder.class, "ws-decoder",
new WebSocket08FrameDecoder(false, allowExtensions, getMaxFramePayloadLength())); new WebSocket08FrameDecoder(false, allowExtensions, getMaxFramePayloadLength()));

View File

@ -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;
/** /**
@ -134,9 +132,11 @@ public class WebSocketClientHandshaker13 extends WebSocketClientHandshaker {
} }
request.addHeader(Names.SEC_WEBSOCKET_ORIGIN, originValue); request.addHeader(Names.SEC_WEBSOCKET_ORIGIN, originValue);
if (protocol != null && !protocol.equals("")) { String expectedSubprotocol = 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) {
@ -197,6 +197,9 @@ public class WebSocketClientHandshaker13 extends WebSocketClientHandshaker {
expectedChallengeResponseString)); expectedChallengeResponseString));
} }
String subprotocol = response.getHeader(Names.SEC_WEBSOCKET_PROTOCOL);
setActualSubprotocol(subprotocol);
channel.pipeline().replace(HttpResponseDecoder.class, "ws-decoder", channel.pipeline().replace(HttpResponseDecoder.class, "ws-decoder",
new WebSocket13FrameDecoder(false, allowExtensions, getMaxFramePayloadLength())); new WebSocket13FrameDecoder(false, allowExtensions, getMaxFramePayloadLength()));

View File

@ -35,6 +35,8 @@ public abstract class WebSocketServerHandshaker {
private final int maxFramePayloadLength; private final int maxFramePayloadLength;
private String selectedSubprotocol = null;
/** /**
* Constructor specifying the destination web socket location * Constructor specifying the destination web socket location
* *
@ -91,7 +93,11 @@ public abstract class WebSocketServerHandshaker {
} }
/** /**
<<<<<<< HEAD
* Returns the max length for any frame's payload. * Returns the max length for any frame's payload.
=======
* Returns the max length for any frame's payload
>>>>>>> abd10d9... Fixed bug where subprotocol not sent by client
*/ */
public int getMaxFramePayloadLength() { public int getMaxFramePayloadLength() {
return maxFramePayloadLength; return maxFramePayloadLength;
@ -129,8 +135,8 @@ 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) {
@ -143,4 +149,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;
}
} }

View File

@ -137,9 +137,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.

View File

@ -131,11 +131,18 @@ 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);
// Upgrade the connection and send the handshake response. // Upgrade the connection and send the handshake response.

View File

@ -132,11 +132,18 @@ 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);
// Upgrade the connection and send the handshake response. // Upgrade the connection and send the handshake response.