diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketServerProtocolHandler.java b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketServerProtocolHandler.java index 1b302800f3..dc48516687 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketServerProtocolHandler.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketServerProtocolHandler.java @@ -26,6 +26,7 @@ import io.netty.channel.ChannelPipeline; import io.netty.handler.codec.http.DefaultFullHttpResponse; import io.netty.handler.codec.http.FullHttpRequest; import io.netty.handler.codec.http.FullHttpResponse; +import io.netty.handler.codec.http.HttpHeaders; import io.netty.handler.codec.http.HttpResponseStatus; import io.netty.util.AttributeKey; @@ -46,8 +47,9 @@ import static io.netty.handler.codec.http.HttpVersion.*; * to the io.netty.example.http.websocketx.server.WebSocketServer example. * * To know once a handshake was done you can intercept the - * {@link ChannelInboundHandler#userEventTriggered(ChannelHandlerContext, Object)} and check if the event was of type - * {@link ServerHandshakeStateEvent#HANDSHAKE_COMPLETE}. + * {@link ChannelInboundHandler#userEventTriggered(ChannelHandlerContext, Object)} and check if the event was instance + * of {@link HandshakeComplete}, the event will contain extra information about the handshake such as the request and + * selected subprotocol. */ public class WebSocketServerProtocolHandler extends WebSocketProtocolHandler { @@ -56,11 +58,42 @@ public class WebSocketServerProtocolHandler extends WebSocketProtocolHandler { */ public enum ServerHandshakeStateEvent { /** - * The Handshake was complete succesful and so the channel was upgraded to websockets + * The Handshake was completed successfully and the channel was upgraded to websockets. + * + * @deprecated in favor of {@link HandshakeComplete} class, + * it provides extra information about the handshake */ + @Deprecated HANDSHAKE_COMPLETE } + /** + * The Handshake was completed successfully and the channel was upgraded to websockets. + */ + public static final class HandshakeComplete { + private final String requestUri; + private final HttpHeaders requestHeaders; + private final String selectedSubprotocol; + + HandshakeComplete(String requestUri, HttpHeaders requestHeaders, String selectedSubprotocol) { + this.requestUri = requestUri; + this.requestHeaders = requestHeaders; + this.selectedSubprotocol = selectedSubprotocol; + } + + public String requestUri() { + return requestUri; + } + + public HttpHeaders requestHeaders() { + return requestHeaders; + } + + public String selectedSubprotocol() { + return selectedSubprotocol; + } + } + private static final AttributeKey HANDSHAKER_ATTR_KEY = AttributeKey.valueOf(WebSocketServerHandshaker.class, "HANDSHAKER"); diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketServerProtocolHandshakeHandler.java b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketServerProtocolHandshakeHandler.java index b1544fb23d..e63a715db1 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketServerProtocolHandshakeHandler.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketServerProtocolHandshakeHandler.java @@ -54,7 +54,7 @@ class WebSocketServerProtocolHandshakeHandler extends ChannelInboundHandlerAdapt @Override public void channelRead(final ChannelHandlerContext ctx, Object msg) throws Exception { - FullHttpRequest req = (FullHttpRequest) msg; + final FullHttpRequest req = (FullHttpRequest) msg; if (!websocketPath.equals(req.uri())) { ctx.fireChannelRead(msg); return; @@ -80,8 +80,12 @@ class WebSocketServerProtocolHandshakeHandler extends ChannelInboundHandlerAdapt if (!future.isSuccess()) { ctx.fireExceptionCaught(future.cause()); } else { + // Kept for compatibility ctx.fireUserEventTriggered( WebSocketServerProtocolHandler.ServerHandshakeStateEvent.HANDSHAKE_COMPLETE); + ctx.fireUserEventTriggered( + new WebSocketServerProtocolHandler.HandshakeComplete( + req.uri(), req.headers(), handshaker.selectedSubprotocol())); } } }); diff --git a/codec-http/src/test/java/io/netty/handler/codec/http/websocketx/WebSocketHandshakeHandOverTest.java b/codec-http/src/test/java/io/netty/handler/codec/http/websocketx/WebSocketHandshakeHandOverTest.java index 9d8fc1a42e..22f1d57b18 100644 --- a/codec-http/src/test/java/io/netty/handler/codec/http/websocketx/WebSocketHandshakeHandOverTest.java +++ b/codec-http/src/test/java/io/netty/handler/codec/http/websocketx/WebSocketHandshakeHandOverTest.java @@ -36,12 +36,14 @@ import static org.junit.Assert.*; public class WebSocketHandshakeHandOverTest { private boolean serverReceivedHandshake; + private WebSocketServerProtocolHandler.HandshakeComplete serverHandshakeComplete; private boolean clientReceivedHandshake; private boolean clientReceivedMessage; @Before public void setUp() { serverReceivedHandshake = false; + serverHandshakeComplete = null; clientReceivedHandshake = false; clientReceivedMessage = false; } @@ -55,6 +57,8 @@ public class WebSocketHandshakeHandOverTest { serverReceivedHandshake = true; // immediatly send a message to the client on connect ctx.writeAndFlush(new TextWebSocketFrame("abc")); + } else if (evt instanceof WebSocketServerProtocolHandler.HandshakeComplete) { + serverHandshakeComplete = (WebSocketServerProtocolHandler.HandshakeComplete) evt; } } @Override @@ -80,6 +84,10 @@ public class WebSocketHandshakeHandOverTest { // Transfer the handshake from the client to the server transferAllDataWithMerge(clientChannel, serverChannel); assertTrue(serverReceivedHandshake); + assertNotNull(serverHandshakeComplete); + assertEquals("/test", serverHandshakeComplete.requestUri()); + assertEquals(8, serverHandshakeComplete.requestHeaders().size()); + assertEquals("test-proto-2", serverHandshakeComplete.selectedSubprotocol()); // Transfer the handshake response and the websocket message to the client transferAllDataWithMerge(serverChannel, clientChannel); @@ -124,7 +132,7 @@ public class WebSocketHandshakeHandOverTest { new HttpClientCodec(), new HttpObjectAggregator(8192), new WebSocketClientProtocolHandler(new URI("ws://localhost:1234/test"), - WebSocketVersion.V13, null, + WebSocketVersion.V13, "test-proto-2", false, null, 65536), handler); } @@ -133,7 +141,7 @@ public class WebSocketHandshakeHandOverTest { return new EmbeddedChannel( new HttpServerCodec(), new HttpObjectAggregator(8192), - new WebSocketServerProtocolHandler("/test", null, false), + new WebSocketServerProtocolHandler("/test", "test-proto-1, test-proto-2", false), handler); } }