diff --git a/src/main/java/io/netty/example/http/websocketx/autobahn/WebSocketServer.java b/src/main/java/io/netty/example/http/websocketx/autobahn/WebSocketServer.java index 70fb04948e..cf7a98cc2b 100644 --- a/src/main/java/io/netty/example/http/websocketx/autobahn/WebSocketServer.java +++ b/src/main/java/io/netty/example/http/websocketx/autobahn/WebSocketServer.java @@ -29,24 +29,24 @@ import io.netty.channel.socket.nio.NioServerSocketChannelFactory; * suite */ public class WebSocketServer { - public static void main(String[] args) { - ConsoleHandler ch = new ConsoleHandler(); - ch.setLevel(Level.FINE); - Logger.getLogger("").addHandler(ch); - Logger.getLogger("").setLevel(Level.FINE); + public static void main(String[] args) { + ConsoleHandler ch = new ConsoleHandler(); + ch.setLevel(Level.FINE); + Logger.getLogger("").addHandler(ch); + Logger.getLogger("").setLevel(Level.FINE); - // Configure the server. - ServerBootstrap bootstrap = new ServerBootstrap(new NioServerSocketChannelFactory( - Executors.newCachedThreadPool(), Executors.newCachedThreadPool())); + // Configure the server. + ServerBootstrap bootstrap = new ServerBootstrap(new NioServerSocketChannelFactory( + Executors.newCachedThreadPool(), Executors.newCachedThreadPool())); - // bootstrap.setOption("child.tcpNoDelay", true); + // bootstrap.setOption("child.tcpNoDelay", true); - // Set up the event pipeline factory. - bootstrap.setPipelineFactory(new WebSocketServerPipelineFactory()); + // Set up the event pipeline factory. + bootstrap.setPipelineFactory(new WebSocketServerPipelineFactory()); - // Bind and start to accept incoming connections. - bootstrap.bind(new InetSocketAddress(9000)); + // Bind and start to accept incoming connections. + bootstrap.bind(new InetSocketAddress(9000)); - System.out.println("Web Socket Server started on localhost:9000."); - } + System.out.println("Web Socket Server started on localhost:9000."); + } } diff --git a/src/main/java/io/netty/example/http/websocketx/autobahn/WebSocketServerHandler.java b/src/main/java/io/netty/example/http/websocketx/autobahn/WebSocketServerHandler.java index f6d62eca58..fe7cc225f3 100644 --- a/src/main/java/io/netty/example/http/websocketx/autobahn/WebSocketServerHandler.java +++ b/src/main/java/io/netty/example/http/websocketx/autobahn/WebSocketServerHandler.java @@ -48,86 +48,86 @@ import io.netty.util.CharsetUtil; * Handles handshakes and messages */ public class WebSocketServerHandler extends SimpleChannelUpstreamHandler { - private static final InternalLogger logger = InternalLoggerFactory.getInstance(WebSocketServerHandler.class); + private static final InternalLogger logger = InternalLoggerFactory.getInstance(WebSocketServerHandler.class); - private WebSocketServerHandshaker handshaker = null; + private WebSocketServerHandshaker handshaker = null; - @Override - public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception { - Object msg = e.getMessage(); - if (msg instanceof HttpRequest) { - handleHttpRequest(ctx, (HttpRequest) msg); - } else if (msg instanceof WebSocketFrame) { - handleWebSocketFrame(ctx, (WebSocketFrame) msg); - } - } + @Override + public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception { + Object msg = e.getMessage(); + if (msg instanceof HttpRequest) { + handleHttpRequest(ctx, (HttpRequest) msg); + } else if (msg instanceof WebSocketFrame) { + handleWebSocketFrame(ctx, (WebSocketFrame) msg); + } + } - private void handleHttpRequest(ChannelHandlerContext ctx, HttpRequest req) throws Exception { - // Allow only GET methods. - if (req.getMethod() != GET) { - sendHttpResponse(ctx, req, new DefaultHttpResponse(HTTP_1_1, FORBIDDEN)); - return; - } + private void handleHttpRequest(ChannelHandlerContext ctx, HttpRequest req) throws Exception { + // Allow only GET methods. + if (req.getMethod() != GET) { + sendHttpResponse(ctx, req, new DefaultHttpResponse(HTTP_1_1, FORBIDDEN)); + return; + } - // Handshake - WebSocketServerHandshakerFactory wsFactory = new WebSocketServerHandshakerFactory( - this.getWebSocketLocation(req), null, false); - this.handshaker = wsFactory.newHandshaker(req); - if (this.handshaker == null) { - wsFactory.sendUnsupportedWebSocketVersionResponse(ctx.getChannel()); - } else { - this.handshaker.performOpeningHandshake(ctx.getChannel(), req); - } - } + // Handshake + WebSocketServerHandshakerFactory wsFactory = new WebSocketServerHandshakerFactory( + this.getWebSocketLocation(req), null, false); + this.handshaker = wsFactory.newHandshaker(req); + if (this.handshaker == null) { + wsFactory.sendUnsupportedWebSocketVersionResponse(ctx.getChannel()); + } else { + this.handshaker.performOpeningHandshake(ctx.getChannel(), req); + } + } - private void handleWebSocketFrame(ChannelHandlerContext ctx, WebSocketFrame frame) { - logger.debug(String - .format("Channel %s received %s", ctx.getChannel().getId(), frame.getClass().getSimpleName())); + private void handleWebSocketFrame(ChannelHandlerContext ctx, WebSocketFrame frame) { + logger.debug(String + .format("Channel %s received %s", ctx.getChannel().getId(), frame.getClass().getSimpleName())); - if (frame instanceof CloseWebSocketFrame) { - this.handshaker.performClosingHandshake(ctx.getChannel(), (CloseWebSocketFrame) frame); - } else if (frame instanceof PingWebSocketFrame) { - ctx.getChannel().write( - new PongWebSocketFrame(frame.isFinalFragment(), frame.getRsv(), frame.getBinaryData())); - } else if (frame instanceof TextWebSocketFrame) { - // String text = ((TextWebSocketFrame) frame).getText(); - ctx.getChannel().write( - new TextWebSocketFrame(frame.isFinalFragment(), frame.getRsv(), frame.getBinaryData())); - } else if (frame instanceof BinaryWebSocketFrame) { - ctx.getChannel().write( - new BinaryWebSocketFrame(frame.isFinalFragment(), frame.getRsv(), frame.getBinaryData())); - } else if (frame instanceof ContinuationWebSocketFrame) { - ctx.getChannel().write( - new ContinuationWebSocketFrame(frame.isFinalFragment(), frame.getRsv(), frame.getBinaryData())); - } else if (frame instanceof PongWebSocketFrame) { - // Ignore - } else { - throw new UnsupportedOperationException(String.format("%s frame types not supported", frame.getClass() - .getName())); - } - } + if (frame instanceof CloseWebSocketFrame) { + this.handshaker.performClosingHandshake(ctx.getChannel(), (CloseWebSocketFrame) frame); + } else if (frame instanceof PingWebSocketFrame) { + ctx.getChannel().write( + new PongWebSocketFrame(frame.isFinalFragment(), frame.getRsv(), frame.getBinaryData())); + } else if (frame instanceof TextWebSocketFrame) { + // String text = ((TextWebSocketFrame) frame).getText(); + ctx.getChannel().write( + new TextWebSocketFrame(frame.isFinalFragment(), frame.getRsv(), frame.getBinaryData())); + } else if (frame instanceof BinaryWebSocketFrame) { + ctx.getChannel().write( + new BinaryWebSocketFrame(frame.isFinalFragment(), frame.getRsv(), frame.getBinaryData())); + } else if (frame instanceof ContinuationWebSocketFrame) { + ctx.getChannel().write( + new ContinuationWebSocketFrame(frame.isFinalFragment(), frame.getRsv(), frame.getBinaryData())); + } else if (frame instanceof PongWebSocketFrame) { + // Ignore + } else { + throw new UnsupportedOperationException(String.format("%s frame types not supported", frame.getClass() + .getName())); + } + } - private void sendHttpResponse(ChannelHandlerContext ctx, HttpRequest req, HttpResponse res) { - // Generate an error page if response status code is not OK (200). - if (res.getStatus().getCode() != 200) { - res.setContent(ChannelBuffers.copiedBuffer(res.getStatus().toString(), CharsetUtil.UTF_8)); - setContentLength(res, res.getContent().readableBytes()); - } + private void sendHttpResponse(ChannelHandlerContext ctx, HttpRequest req, HttpResponse res) { + // Generate an error page if response status code is not OK (200). + if (res.getStatus().getCode() != 200) { + res.setContent(ChannelBuffers.copiedBuffer(res.getStatus().toString(), CharsetUtil.UTF_8)); + setContentLength(res, res.getContent().readableBytes()); + } - // Send the response and close the connection if necessary. - ChannelFuture f = ctx.getChannel().write(res); - if (!isKeepAlive(req) || res.getStatus().getCode() != 200) { - f.addListener(ChannelFutureListener.CLOSE); - } - } + // Send the response and close the connection if necessary. + ChannelFuture f = ctx.getChannel().write(res); + if (!isKeepAlive(req) || res.getStatus().getCode() != 200) { + f.addListener(ChannelFutureListener.CLOSE); + } + } - @Override - public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception { - e.getCause().printStackTrace(); - e.getChannel().close(); - } + @Override + public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception { + e.getCause().printStackTrace(); + e.getChannel().close(); + } - private String getWebSocketLocation(HttpRequest req) { - return "ws://" + req.getHeader(HttpHeaders.Names.HOST); - } + private String getWebSocketLocation(HttpRequest req) { + return "ws://" + req.getHeader(HttpHeaders.Names.HOST); + } } diff --git a/src/main/java/io/netty/example/http/websocketx/autobahn/WebSocketServerPipelineFactory.java b/src/main/java/io/netty/example/http/websocketx/autobahn/WebSocketServerPipelineFactory.java index ff2ffa6ebf..469f832bc6 100644 --- a/src/main/java/io/netty/example/http/websocketx/autobahn/WebSocketServerPipelineFactory.java +++ b/src/main/java/io/netty/example/http/websocketx/autobahn/WebSocketServerPipelineFactory.java @@ -26,14 +26,14 @@ import io.netty.handler.codec.http.HttpResponseEncoder; /** */ public class WebSocketServerPipelineFactory implements ChannelPipelineFactory { - @Override - public ChannelPipeline getPipeline() throws Exception { - // Create a default pipeline implementation. - ChannelPipeline pipeline = pipeline(); - pipeline.addLast("decoder", new HttpRequestDecoder()); - pipeline.addLast("aggregator", new HttpChunkAggregator(65536)); - pipeline.addLast("encoder", new HttpResponseEncoder()); - pipeline.addLast("handler", new WebSocketServerHandler()); - return pipeline; - } + @Override + public ChannelPipeline getPipeline() throws Exception { + // Create a default pipeline implementation. + ChannelPipeline pipeline = pipeline(); + pipeline.addLast("decoder", new HttpRequestDecoder()); + pipeline.addLast("aggregator", new HttpChunkAggregator(65536)); + pipeline.addLast("encoder", new HttpResponseEncoder()); + pipeline.addLast("handler", new WebSocketServerHandler()); + return pipeline; + } } diff --git a/src/main/java/io/netty/example/http/websocketx/autobahn/package-info.java b/src/main/java/io/netty/example/http/websocketx/autobahn/package-info.java index fbc2c4306c..09b3632b4e 100644 --- a/src/main/java/io/netty/example/http/websocketx/autobahn/package-info.java +++ b/src/main/java/io/netty/example/http/websocketx/autobahn/package-info.java @@ -47,11 +47,13 @@ * } * * - *

10. Run the test python fuzzing_client.py. Note that the actual test case python code is + *

10. Run WebSocketServer in this package + * + *

11. Run the test python fuzzing_client.py. Note that the actual test case python code is * located in /usr/local/lib/python2.6/dist-packages/autobahn-0.4.3-py2.6.egg/autobahn/cases * and not in the checked out git repository. * - *

11. See the results in reports/servers/index.html + *

12. See the results in reports/servers/index.html */ package io.netty.example.http.websocketx.autobahn; diff --git a/src/main/java/io/netty/example/http/websocketx/client/App.java b/src/main/java/io/netty/example/http/websocketx/client/App.java index d65f0d0c95..8ff1817491 100644 --- a/src/main/java/io/netty/example/http/websocketx/client/App.java +++ b/src/main/java/io/netty/example/http/websocketx/client/App.java @@ -35,98 +35,98 @@ import io.netty.handler.codec.http.websocketx.WebSocketVersion; */ public class App { - public static void main(String[] args) throws Exception { - ConsoleHandler ch = new ConsoleHandler(); - ch.setLevel(Level.FINE); - Logger.getLogger("").addHandler(ch); - Logger.getLogger("").setLevel(Level.FINE); + public static void main(String[] args) throws Exception { + ConsoleHandler ch = new ConsoleHandler(); + ch.setLevel(Level.FINE); + Logger.getLogger("").addHandler(ch); + Logger.getLogger("").setLevel(Level.FINE); - runClient(); - System.exit(0); - } + runClient(); + System.exit(0); + } - /** - * Send and receive some messages using a web socket client - * - * @throws Exception - */ - public static void runClient() throws Exception { + /** + * Send and receive some messages using a web socket client + * + * @throws Exception + */ + public static void runClient() throws Exception { - MyCallbackHandler callbackHandler = new MyCallbackHandler(); - WebSocketClientFactory factory = new WebSocketClientFactory(); + MyCallbackHandler callbackHandler = new MyCallbackHandler(); + WebSocketClientFactory factory = new WebSocketClientFactory(); - // Connect with RFC 6455. You can change it to V10 or V00. - // If you change it to V00, ping is not supported and remember to change HttpResponseDecoder to - // WebSocketHttpResponseDecoder in the pipeline. - WebSocketClient client = factory.newClient(new URI("ws://localhost:8080/websocket"), WebSocketVersion.V13, - callbackHandler, null); + // Connect with RFC 6455. You can change it to V10 or V00. + // If you change it to V00, ping is not supported and remember to change HttpResponseDecoder to + // WebSocketHttpResponseDecoder in the pipeline. + WebSocketClient client = factory.newClient(new URI("ws://localhost:8080/websocket"), WebSocketVersion.V13, + callbackHandler, null); - // Connect - System.out.println("WebSocket Client connecting"); - client.connect().awaitUninterruptibly(); - Thread.sleep(200); + // Connect + System.out.println("WebSocket Client connecting"); + client.connect().awaitUninterruptibly(); + Thread.sleep(200); - // Send 10 messages and wait for responses - System.out.println("WebSocket Client sending message"); - for (int i = 0; i < 10; i++) { - client.send(new TextWebSocketFrame("Message #" + i)); - } - Thread.sleep(1000); + // Send 10 messages and wait for responses + System.out.println("WebSocket Client sending message"); + for (int i = 0; i < 10; i++) { + client.send(new TextWebSocketFrame("Message #" + i)); + } + Thread.sleep(1000); - // Ping - only supported for V10 and up. - System.out.println("WebSocket Client sending ping"); - client.send(new PingWebSocketFrame(ChannelBuffers.copiedBuffer(new byte[] { 1, 2, 3, 4, 5, 6 }))); - Thread.sleep(1000); + // Ping - only supported for V10 and up. + System.out.println("WebSocket Client sending ping"); + client.send(new PingWebSocketFrame(ChannelBuffers.copiedBuffer(new byte[] { 1, 2, 3, 4, 5, 6 }))); + Thread.sleep(1000); - // Close - System.out.println("WebSocket Client sending close"); - client.send(new CloseWebSocketFrame()); - Thread.sleep(1000); + // Close + System.out.println("WebSocket Client sending close"); + client.send(new CloseWebSocketFrame()); + Thread.sleep(1000); - // Disconnect - client.disconnect(); - } + // Disconnect + client.disconnect(); + } - /** - * Our web socket callback handler for this app - */ - public static class MyCallbackHandler implements WebSocketCallback { - public boolean connected = false; - public ArrayList messagesReceived = new ArrayList(); + /** + * Our web socket callback handler for this app + */ + public static class MyCallbackHandler implements WebSocketCallback { + public boolean connected = false; + public ArrayList messagesReceived = new ArrayList(); - public MyCallbackHandler() { - } + public MyCallbackHandler() { + } - @Override - public void onConnect(WebSocketClient client) { - System.out.println("WebSocket Client connected!"); - connected = true; - } + @Override + public void onConnect(WebSocketClient client) { + System.out.println("WebSocket Client connected!"); + connected = true; + } - @Override - public void onDisconnect(WebSocketClient client) { - System.out.println("WebSocket Client disconnected!"); - connected = false; - } + @Override + public void onDisconnect(WebSocketClient client) { + System.out.println("WebSocket Client disconnected!"); + connected = false; + } - @Override - public void onMessage(WebSocketClient client, WebSocketFrame frame) { - if (frame instanceof TextWebSocketFrame) { - TextWebSocketFrame textFrame = (TextWebSocketFrame) frame; - System.out.println("WebSocket Client received message:" + textFrame.getText()); - messagesReceived.add(textFrame.getText()); - } else if (frame instanceof PongWebSocketFrame) { - System.out.println("WebSocket Client received pong"); - } else if (frame instanceof CloseWebSocketFrame) { - System.out.println("WebSocket Client received closing"); - } - } + @Override + public void onMessage(WebSocketClient client, WebSocketFrame frame) { + if (frame instanceof TextWebSocketFrame) { + TextWebSocketFrame textFrame = (TextWebSocketFrame) frame; + System.out.println("WebSocket Client received message:" + textFrame.getText()); + messagesReceived.add(textFrame.getText()); + } else if (frame instanceof PongWebSocketFrame) { + System.out.println("WebSocket Client received pong"); + } else if (frame instanceof CloseWebSocketFrame) { + System.out.println("WebSocket Client received closing"); + } + } - @Override - public void onError(Throwable t) { - System.out.println("WebSocket Client error " + t.toString()); - } + @Override + public void onError(Throwable t) { + System.out.println("WebSocket Client error " + t.toString()); + } - } + } } diff --git a/src/main/java/io/netty/example/http/websocketx/client/WebSocketCallback.java b/src/main/java/io/netty/example/http/websocketx/client/WebSocketCallback.java index 6052bd564c..ed64532ce0 100644 --- a/src/main/java/io/netty/example/http/websocketx/client/WebSocketCallback.java +++ b/src/main/java/io/netty/example/http/websocketx/client/WebSocketCallback.java @@ -31,37 +31,37 @@ import io.netty.handler.codec.http.websocketx.WebSocketFrame; */ public interface WebSocketCallback { - /** - * Called when the client is connected to the server - * - * @param client - * Current client used to connect - */ - void onConnect(WebSocketClient client); + /** + * Called when the client is connected to the server + * + * @param client + * Current client used to connect + */ + void onConnect(WebSocketClient client); - /** - * Called when the client got disconnected from the server. - * - * @param client - * Current client that was disconnected - */ - void onDisconnect(WebSocketClient client); + /** + * Called when the client got disconnected from the server. + * + * @param client + * Current client that was disconnected + */ + void onDisconnect(WebSocketClient client); - /** - * Called when a message arrives from the server. - * - * @param client - * Current client connected - * @param frame - * Data received from server - */ - void onMessage(WebSocketClient client, WebSocketFrame frame); + /** + * Called when a message arrives from the server. + * + * @param client + * Current client connected + * @param frame + * Data received from server + */ + void onMessage(WebSocketClient client, WebSocketFrame frame); - /** - * Called when an unhandled errors occurs. - * - * @param t - * The causing error - */ - void onError(Throwable t); + /** + * Called when an unhandled errors occurs. + * + * @param t + * The causing error + */ + void onError(Throwable t); } diff --git a/src/main/java/io/netty/example/http/websocketx/client/WebSocketClient.java b/src/main/java/io/netty/example/http/websocketx/client/WebSocketClient.java index 727b31ccea..24064bb56b 100644 --- a/src/main/java/io/netty/example/http/websocketx/client/WebSocketClient.java +++ b/src/main/java/io/netty/example/http/websocketx/client/WebSocketClient.java @@ -29,26 +29,26 @@ import io.netty.handler.codec.http.websocketx.WebSocketFrame; */ public interface WebSocketClient { - /** - * Connect to server Host and port is setup by the factory. - * - * @return Connect future. Fires when connected. - */ - ChannelFuture connect(); + /** + * Connect to server Host and port is setup by the factory. + * + * @return Connect future. Fires when connected. + */ + ChannelFuture connect(); - /** - * Disconnect from the server - * - * @return Disconnect future. Fires when disconnected. - */ - ChannelFuture disconnect(); + /** + * Disconnect from the server + * + * @return Disconnect future. Fires when disconnected. + */ + ChannelFuture disconnect(); - /** - * Send data to server - * - * @param frame - * Data for sending - * @return Write future. Will fire when the data is sent. - */ - ChannelFuture send(WebSocketFrame frame); + /** + * Send data to server + * + * @param frame + * Data for sending + * @return Write future. Will fire when the data is sent. + */ + ChannelFuture send(WebSocketFrame frame); } diff --git a/src/main/java/io/netty/example/http/websocketx/client/WebSocketClientFactory.java b/src/main/java/io/netty/example/http/websocketx/client/WebSocketClientFactory.java index aa2216b9ac..396dcb6829 100644 --- a/src/main/java/io/netty/example/http/websocketx/client/WebSocketClientFactory.java +++ b/src/main/java/io/netty/example/http/websocketx/client/WebSocketClientFactory.java @@ -43,50 +43,50 @@ import java.util.concurrent.Executors; */ public class WebSocketClientFactory { - private final NioClientSocketChannelFactory socketChannelFactory = new NioClientSocketChannelFactory( - Executors.newCachedThreadPool(), Executors.newCachedThreadPool()); + private final NioClientSocketChannelFactory socketChannelFactory = new NioClientSocketChannelFactory( + Executors.newCachedThreadPool(), Executors.newCachedThreadPool()); - /** - * Create a new WebSocket client. - * - * @param url - * URL to connect to. - * @param version - * Web Socket version to support - * @param callback - * Callback interface to receive events - * @param customHeaders - * custom HTTP headers to pass during the handshake - * @return A WebSocket client. Call {@link WebSocketClient#connect()} to connect. - */ - public WebSocketClient newClient(final URI url, final WebSocketVersion version, final WebSocketCallback callback, - Map customHeaders) { - ClientBootstrap bootstrap = new ClientBootstrap(socketChannelFactory); + /** + * Create a new WebSocket client. + * + * @param url + * URL to connect to. + * @param version + * Web Socket version to support + * @param callback + * Callback interface to receive events + * @param customHeaders + * custom HTTP headers to pass during the handshake + * @return A WebSocket client. Call {@link WebSocketClient#connect()} to connect. + */ + public WebSocketClient newClient(final URI url, final WebSocketVersion version, final WebSocketCallback callback, + Map customHeaders) { + ClientBootstrap bootstrap = new ClientBootstrap(socketChannelFactory); - String protocol = url.getScheme(); - if (!protocol.equals("ws") && !protocol.equals("wss")) { - throw new IllegalArgumentException("Unsupported protocol: " + protocol); - } + String protocol = url.getScheme(); + if (!protocol.equals("ws") && !protocol.equals("wss")) { + throw new IllegalArgumentException("Unsupported protocol: " + protocol); + } - final WebSocketClientHandler clientHandler = new WebSocketClientHandler(bootstrap, url, version, callback, - customHeaders); + final WebSocketClientHandler clientHandler = new WebSocketClientHandler(bootstrap, url, version, callback, + customHeaders); - bootstrap.setPipelineFactory(new ChannelPipelineFactory() { + bootstrap.setPipelineFactory(new ChannelPipelineFactory() { - @Override - public ChannelPipeline getPipeline() throws Exception { - ChannelPipeline pipeline = Channels.pipeline(); + @Override + public ChannelPipeline getPipeline() throws Exception { + ChannelPipeline pipeline = Channels.pipeline(); - // If you wish to support HyBi V00, you need to use WebSocketHttpResponseDecoder instead for - // HttpResponseDecoder. - pipeline.addLast("decoder", new HttpResponseDecoder()); + // If you wish to support HyBi V00, you need to use WebSocketHttpResponseDecoder instead for + // HttpResponseDecoder. + pipeline.addLast("decoder", new HttpResponseDecoder()); - pipeline.addLast("encoder", new HttpRequestEncoder()); - pipeline.addLast("ws-handler", clientHandler); - return pipeline; - } - }); + pipeline.addLast("encoder", new HttpRequestEncoder()); + pipeline.addLast("ws-handler", clientHandler); + return pipeline; + } + }); - return clientHandler; - } + return clientHandler; + } } diff --git a/src/main/java/io/netty/example/http/websocketx/client/WebSocketClientHandler.java b/src/main/java/io/netty/example/http/websocketx/client/WebSocketClientHandler.java index 034bfae6e7..8790813ee6 100644 --- a/src/main/java/io/netty/example/http/websocketx/client/WebSocketClientHandler.java +++ b/src/main/java/io/netty/example/http/websocketx/client/WebSocketClientHandler.java @@ -49,81 +49,81 @@ import io.netty.util.CharsetUtil; */ public class WebSocketClientHandler extends SimpleChannelUpstreamHandler implements WebSocketClient { - private final ClientBootstrap bootstrap; - private URI url; - private final WebSocketCallback callback; - private Channel channel; - private WebSocketClientHandshaker handshaker = null; - private final WebSocketVersion version; - private Map customHeaders = null; + private final ClientBootstrap bootstrap; + private URI url; + private final WebSocketCallback callback; + private Channel channel; + private WebSocketClientHandshaker handshaker = null; + private final WebSocketVersion version; + private Map customHeaders = null; - public WebSocketClientHandler(ClientBootstrap bootstrap, URI url, WebSocketVersion version, - WebSocketCallback callback, Map customHeaders) { - this.bootstrap = bootstrap; - this.url = url; - this.version = version; - this.callback = callback; - this.customHeaders = customHeaders; - } + public WebSocketClientHandler(ClientBootstrap bootstrap, URI url, WebSocketVersion version, + WebSocketCallback callback, Map customHeaders) { + this.bootstrap = bootstrap; + this.url = url; + this.version = version; + this.callback = callback; + this.customHeaders = customHeaders; + } - @Override - public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception { - channel = e.getChannel(); - this.handshaker = new WebSocketClientHandshakerFactory() - .newHandshaker(url, version, null, false, customHeaders); - handshaker.performOpeningHandshake(channel); - } + @Override + public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception { + channel = e.getChannel(); + this.handshaker = new WebSocketClientHandshakerFactory() + .newHandshaker(url, version, null, false, customHeaders); + handshaker.performOpeningHandshake(channel); + } - @Override - public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception { - callback.onDisconnect(this); - } + @Override + public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception { + callback.onDisconnect(this); + } - @Override - public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception { - if (!handshaker.isOpeningHandshakeCompleted()) { - handshaker.performClosingHandshake(ctx.getChannel(), (HttpResponse) e.getMessage()); - callback.onConnect(this); - return; - } + @Override + public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception { + if (!handshaker.isOpeningHandshakeCompleted()) { + handshaker.performClosingHandshake(ctx.getChannel(), (HttpResponse) e.getMessage()); + callback.onConnect(this); + return; + } - if (e.getMessage() instanceof HttpResponse) { - HttpResponse response = (HttpResponse) e.getMessage(); - throw new WebSocketException("Unexpected HttpResponse (status=" + response.getStatus() + ", content=" - + response.getContent().toString(CharsetUtil.UTF_8) + ")"); - } + if (e.getMessage() instanceof HttpResponse) { + HttpResponse response = (HttpResponse) e.getMessage(); + throw new WebSocketException("Unexpected HttpResponse (status=" + response.getStatus() + ", content=" + + response.getContent().toString(CharsetUtil.UTF_8) + ")"); + } - WebSocketFrame frame = (WebSocketFrame) e.getMessage(); - callback.onMessage(this, frame); - } + WebSocketFrame frame = (WebSocketFrame) e.getMessage(); + callback.onMessage(this, frame); + } - @Override - public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception { - final Throwable t = e.getCause(); - callback.onError(t); - e.getChannel().close(); - } + @Override + public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception { + final Throwable t = e.getCause(); + callback.onError(t); + e.getChannel().close(); + } - @Override - public ChannelFuture connect() { - return bootstrap.connect(new InetSocketAddress(url.getHost(), url.getPort())); - } + @Override + public ChannelFuture connect() { + return bootstrap.connect(new InetSocketAddress(url.getHost(), url.getPort())); + } - @Override - public ChannelFuture disconnect() { - return channel.close(); - } + @Override + public ChannelFuture disconnect() { + return channel.close(); + } - @Override - public ChannelFuture send(WebSocketFrame frame) { - return channel.write(frame); - } + @Override + public ChannelFuture send(WebSocketFrame frame) { + return channel.write(frame); + } - public URI getUrl() { - return url; - } + public URI getUrl() { + return url; + } - public void setUrl(URI url) { - this.url = url; - } + public void setUrl(URI url) { + this.url = url; + } } diff --git a/src/main/java/io/netty/example/http/websocketx/client/WebSocketException.java b/src/main/java/io/netty/example/http/websocketx/client/WebSocketException.java index 1477b4d700..ed227a7925 100644 --- a/src/main/java/io/netty/example/http/websocketx/client/WebSocketException.java +++ b/src/main/java/io/netty/example/http/websocketx/client/WebSocketException.java @@ -30,15 +30,15 @@ import java.io.IOException; */ public class WebSocketException extends IOException { - /** + /** */ - private static final long serialVersionUID = 1L; + private static final long serialVersionUID = 1L; - public WebSocketException(String s) { - super(s); - } + public WebSocketException(String s) { + super(s); + } - public WebSocketException(String s, Throwable throwable) { - super(s, throwable); - } + public WebSocketException(String s, Throwable throwable) { + super(s, throwable); + } } \ No newline at end of file diff --git a/src/main/java/io/netty/example/http/websocketx/client/WebSocketHttpResponseDecoder.java b/src/main/java/io/netty/example/http/websocketx/client/WebSocketHttpResponseDecoder.java index 3d7de0337d..850054c429 100644 --- a/src/main/java/io/netty/example/http/websocketx/client/WebSocketHttpResponseDecoder.java +++ b/src/main/java/io/netty/example/http/websocketx/client/WebSocketHttpResponseDecoder.java @@ -25,27 +25,27 @@ import io.netty.handler.codec.http.HttpResponseDecoder; */ public class WebSocketHttpResponseDecoder extends HttpResponseDecoder { - @Override - protected boolean isContentAlwaysEmpty(HttpMessage msg) { - if (msg instanceof HttpResponse) { - HttpResponse res = (HttpResponse) msg; - int code = res.getStatus().getCode(); + @Override + protected boolean isContentAlwaysEmpty(HttpMessage msg) { + if (msg instanceof HttpResponse) { + HttpResponse res = (HttpResponse) msg; + int code = res.getStatus().getCode(); - // FIX force reading of protocol upgrade challenge data into the content buffer - if (code == 101) { - return false; - } + // FIX force reading of protocol upgrade challenge data into the content buffer + if (code == 101) { + return false; + } - if (code < 200) { - return true; - } - switch (code) { - case 204: - case 205: - case 304: - return true; - } - } - return false; - } + if (code < 200) { + return true; + } + switch (code) { + case 204: + case 205: + case 304: + return true; + } + } + return false; + } } diff --git a/src/main/java/io/netty/example/http/websocketx/server/WebSocketServer.java b/src/main/java/io/netty/example/http/websocketx/server/WebSocketServer.java index fba0f97305..3580fd68db 100644 --- a/src/main/java/io/netty/example/http/websocketx/server/WebSocketServer.java +++ b/src/main/java/io/netty/example/http/websocketx/server/WebSocketServer.java @@ -36,33 +36,30 @@ import io.netty.channel.socket.nio.NioServerSocketChannelFactory; * *

*/ public class WebSocketServer { - public static void main(String[] args) { - ConsoleHandler ch = new ConsoleHandler(); - ch.setLevel(Level.FINE); - Logger.getLogger("").addHandler(ch); - Logger.getLogger("").setLevel(Level.FINE); + public static void main(String[] args) { + ConsoleHandler ch = new ConsoleHandler(); + ch.setLevel(Level.FINE); + Logger.getLogger("").addHandler(ch); + Logger.getLogger("").setLevel(Level.FINE); - // Configure the server. - ServerBootstrap bootstrap = new ServerBootstrap(new NioServerSocketChannelFactory( - Executors.newCachedThreadPool(), Executors.newCachedThreadPool())); + // Configure the server. + ServerBootstrap bootstrap = new ServerBootstrap(new NioServerSocketChannelFactory( + Executors.newCachedThreadPool(), Executors.newCachedThreadPool())); - // Set up the event pipeline factory. - bootstrap.setPipelineFactory(new WebSocketServerPipelineFactory()); + // Set up the event pipeline factory. + bootstrap.setPipelineFactory(new WebSocketServerPipelineFactory()); - // Bind and start to accept incoming connections. - bootstrap.bind(new InetSocketAddress(8080)); + // Bind and start to accept incoming connections. + bootstrap.bind(new InetSocketAddress(8080)); - System.out - .println("Web Socket Server started on 8080. Open your browser and navigate to http://localhost:8080/"); - } + System.out + .println("Web Socket Server started on 8080. Open your browser and navigate to http://localhost:8080/"); + } } diff --git a/src/main/java/io/netty/example/http/websocketx/server/WebSocketServerHandler.java b/src/main/java/io/netty/example/http/websocketx/server/WebSocketServerHandler.java index 702e15b8e6..7319dbaa8a 100644 --- a/src/main/java/io/netty/example/http/websocketx/server/WebSocketServerHandler.java +++ b/src/main/java/io/netty/example/http/websocketx/server/WebSocketServerHandler.java @@ -48,99 +48,99 @@ import io.netty.util.CharsetUtil; * Handles handshakes and messages */ public class WebSocketServerHandler extends SimpleChannelUpstreamHandler { - private static final InternalLogger logger = InternalLoggerFactory.getInstance(WebSocketServerHandler.class); + private static final InternalLogger logger = InternalLoggerFactory.getInstance(WebSocketServerHandler.class); - private static final String WEBSOCKET_PATH = "/websocket"; + private static final String WEBSOCKET_PATH = "/websocket"; - private WebSocketServerHandshaker handshaker = null; + private WebSocketServerHandshaker handshaker = null; - @Override - public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception { - Object msg = e.getMessage(); - if (msg instanceof HttpRequest) { - handleHttpRequest(ctx, (HttpRequest) msg); - } else if (msg instanceof WebSocketFrame) { - handleWebSocketFrame(ctx, (WebSocketFrame) msg); - } - } + @Override + public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception { + Object msg = e.getMessage(); + if (msg instanceof HttpRequest) { + handleHttpRequest(ctx, (HttpRequest) msg); + } else if (msg instanceof WebSocketFrame) { + handleWebSocketFrame(ctx, (WebSocketFrame) msg); + } + } - private void handleHttpRequest(ChannelHandlerContext ctx, HttpRequest req) throws Exception { - // Allow only GET methods. - if (req.getMethod() != GET) { - sendHttpResponse(ctx, req, new DefaultHttpResponse(HTTP_1_1, FORBIDDEN)); - return; - } + private void handleHttpRequest(ChannelHandlerContext ctx, HttpRequest req) throws Exception { + // Allow only GET methods. + if (req.getMethod() != GET) { + sendHttpResponse(ctx, req, new DefaultHttpResponse(HTTP_1_1, FORBIDDEN)); + return; + } - // Send the demo page and favicon.ico - if (req.getUri().equals("/")) { - HttpResponse res = new DefaultHttpResponse(HTTP_1_1, OK); + // Send the demo page and favicon.ico + if (req.getUri().equals("/")) { + HttpResponse res = new DefaultHttpResponse(HTTP_1_1, OK); - ChannelBuffer content = WebSocketServerIndexPage.getContent(getWebSocketLocation(req)); + ChannelBuffer content = WebSocketServerIndexPage.getContent(getWebSocketLocation(req)); - res.setHeader(CONTENT_TYPE, "text/html; charset=UTF-8"); - setContentLength(res, content.readableBytes()); + res.setHeader(CONTENT_TYPE, "text/html; charset=UTF-8"); + setContentLength(res, content.readableBytes()); - res.setContent(content); - sendHttpResponse(ctx, req, res); - return; - } else if (req.getUri().equals("/favicon.ico")) { - HttpResponse res = new DefaultHttpResponse(HTTP_1_1, NOT_FOUND); - sendHttpResponse(ctx, req, res); - return; - } + res.setContent(content); + sendHttpResponse(ctx, req, res); + return; + } else if (req.getUri().equals("/favicon.ico")) { + HttpResponse res = new DefaultHttpResponse(HTTP_1_1, NOT_FOUND); + sendHttpResponse(ctx, req, res); + return; + } - // Handshake - WebSocketServerHandshakerFactory wsFactory = new WebSocketServerHandshakerFactory( - this.getWebSocketLocation(req), null, false); - this.handshaker = wsFactory.newHandshaker(req); - if (this.handshaker == null) { - wsFactory.sendUnsupportedWebSocketVersionResponse(ctx.getChannel()); - } else { - this.handshaker.performOpeningHandshake(ctx.getChannel(), req); - } - } + // Handshake + WebSocketServerHandshakerFactory wsFactory = new WebSocketServerHandshakerFactory( + this.getWebSocketLocation(req), null, false); + this.handshaker = wsFactory.newHandshaker(req); + if (this.handshaker == null) { + wsFactory.sendUnsupportedWebSocketVersionResponse(ctx.getChannel()); + } else { + this.handshaker.performOpeningHandshake(ctx.getChannel(), req); + } + } - private void handleWebSocketFrame(ChannelHandlerContext ctx, WebSocketFrame frame) { + private void handleWebSocketFrame(ChannelHandlerContext ctx, WebSocketFrame frame) { - // Check for closing frame - if (frame instanceof CloseWebSocketFrame) { - this.handshaker.performClosingHandshake(ctx.getChannel(), (CloseWebSocketFrame) frame); - return; - } else if (frame instanceof PingWebSocketFrame) { - ctx.getChannel().write(new PongWebSocketFrame(frame.getBinaryData())); - return; - } else if (!(frame instanceof TextWebSocketFrame)) { - throw new UnsupportedOperationException(String.format("%s frame types not supported", frame.getClass() - .getName())); - } + // Check for closing frame + if (frame instanceof CloseWebSocketFrame) { + this.handshaker.performClosingHandshake(ctx.getChannel(), (CloseWebSocketFrame) frame); + return; + } else if (frame instanceof PingWebSocketFrame) { + ctx.getChannel().write(new PongWebSocketFrame(frame.getBinaryData())); + return; + } else if (!(frame instanceof TextWebSocketFrame)) { + throw new UnsupportedOperationException(String.format("%s frame types not supported", frame.getClass() + .getName())); + } - // Send the uppercase string back. - String request = ((TextWebSocketFrame) frame).getText(); - logger.debug(String.format("Channel %s received %s", ctx.getChannel().getId(), request)); - ctx.getChannel().write(new TextWebSocketFrame(request.toUpperCase())); - } + // Send the uppercase string back. + String request = ((TextWebSocketFrame) frame).getText(); + logger.debug(String.format("Channel %s received %s", ctx.getChannel().getId(), request)); + ctx.getChannel().write(new TextWebSocketFrame(request.toUpperCase())); + } - private void sendHttpResponse(ChannelHandlerContext ctx, HttpRequest req, HttpResponse res) { - // Generate an error page if response status code is not OK (200). - if (res.getStatus().getCode() != 200) { - res.setContent(ChannelBuffers.copiedBuffer(res.getStatus().toString(), CharsetUtil.UTF_8)); - setContentLength(res, res.getContent().readableBytes()); - } + private void sendHttpResponse(ChannelHandlerContext ctx, HttpRequest req, HttpResponse res) { + // Generate an error page if response status code is not OK (200). + if (res.getStatus().getCode() != 200) { + res.setContent(ChannelBuffers.copiedBuffer(res.getStatus().toString(), CharsetUtil.UTF_8)); + setContentLength(res, res.getContent().readableBytes()); + } - // Send the response and close the connection if necessary. - ChannelFuture f = ctx.getChannel().write(res); - if (!isKeepAlive(req) || res.getStatus().getCode() != 200) { - f.addListener(ChannelFutureListener.CLOSE); - } - } + // Send the response and close the connection if necessary. + ChannelFuture f = ctx.getChannel().write(res); + if (!isKeepAlive(req) || res.getStatus().getCode() != 200) { + f.addListener(ChannelFutureListener.CLOSE); + } + } - @Override - public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception { - e.getCause().printStackTrace(); - e.getChannel().close(); - } + @Override + public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception { + e.getCause().printStackTrace(); + e.getChannel().close(); + } - private String getWebSocketLocation(HttpRequest req) { - return "ws://" + req.getHeader(HttpHeaders.Names.HOST) + WEBSOCKET_PATH; - } + private String getWebSocketLocation(HttpRequest req) { + return "ws://" + req.getHeader(HttpHeaders.Names.HOST) + WEBSOCKET_PATH; + } } diff --git a/src/main/java/io/netty/example/http/websocketx/server/WebSocketServerIndexPage.java b/src/main/java/io/netty/example/http/websocketx/server/WebSocketServerIndexPage.java index f79c02ec25..aea46fbb16 100644 --- a/src/main/java/io/netty/example/http/websocketx/server/WebSocketServerIndexPage.java +++ b/src/main/java/io/netty/example/http/websocketx/server/WebSocketServerIndexPage.java @@ -24,69 +24,69 @@ import io.netty.util.CharsetUtil; */ public class WebSocketServerIndexPage { - private static final String NEWLINE = "\r\n"; + private static final String NEWLINE = "\r\n"; - public static ChannelBuffer getContent(String webSocketLocation) { - return ChannelBuffers - .copiedBuffer( - "Web Socket Test" - + NEWLINE - + "" - + NEWLINE - + "" - + NEWLINE - + "
" - + NEWLINE - + "" - + "" - + NEWLINE + "

Output

" + NEWLINE - + "" - + NEWLINE + "
" + NEWLINE + "" + NEWLINE + "" + NEWLINE, - CharsetUtil.US_ASCII); - } + public static ChannelBuffer getContent(String webSocketLocation) { + return ChannelBuffers + .copiedBuffer( + "Web Socket Test" + + NEWLINE + + "" + + NEWLINE + + "" + + NEWLINE + + "
" + + NEWLINE + + "" + + "" + + NEWLINE + "

Output

" + NEWLINE + + "" + + NEWLINE + "
" + NEWLINE + "" + NEWLINE + "" + NEWLINE, + CharsetUtil.US_ASCII); + } } diff --git a/src/main/java/io/netty/example/http/websocketx/server/WebSocketServerPipelineFactory.java b/src/main/java/io/netty/example/http/websocketx/server/WebSocketServerPipelineFactory.java index 1232bda3fb..21c31d41a9 100644 --- a/src/main/java/io/netty/example/http/websocketx/server/WebSocketServerPipelineFactory.java +++ b/src/main/java/io/netty/example/http/websocketx/server/WebSocketServerPipelineFactory.java @@ -26,14 +26,14 @@ import io.netty.handler.codec.http.HttpResponseEncoder; /** */ public class WebSocketServerPipelineFactory implements ChannelPipelineFactory { - @Override - public ChannelPipeline getPipeline() throws Exception { - // Create a default pipeline implementation. - ChannelPipeline pipeline = pipeline(); - pipeline.addLast("decoder", new HttpRequestDecoder()); - pipeline.addLast("aggregator", new HttpChunkAggregator(65536)); - pipeline.addLast("encoder", new HttpResponseEncoder()); - pipeline.addLast("handler", new WebSocketServerHandler()); - return pipeline; - } + @Override + public ChannelPipeline getPipeline() throws Exception { + // Create a default pipeline implementation. + ChannelPipeline pipeline = pipeline(); + pipeline.addLast("decoder", new HttpRequestDecoder()); + pipeline.addLast("aggregator", new HttpChunkAggregator(65536)); + pipeline.addLast("encoder", new HttpResponseEncoder()); + pipeline.addLast("handler", new WebSocketServerHandler()); + return pipeline; + } } diff --git a/src/main/java/io/netty/example/http/websocketx/sslserver/WebSocketSslServer.java b/src/main/java/io/netty/example/http/websocketx/sslserver/WebSocketSslServer.java index f2a2714aa9..c491b43235 100644 --- a/src/main/java/io/netty/example/http/websocketx/sslserver/WebSocketSslServer.java +++ b/src/main/java/io/netty/example/http/websocketx/sslserver/WebSocketSslServer.java @@ -36,45 +36,42 @@ import io.netty.channel.socket.nio.NioServerSocketChannelFactory; * * */ public class WebSocketSslServer { - public static void main(String[] args) { - ConsoleHandler ch = new ConsoleHandler(); - ch.setLevel(Level.FINE); - Logger.getLogger("").addHandler(ch); - Logger.getLogger("").setLevel(Level.FINE); + public static void main(String[] args) { + ConsoleHandler ch = new ConsoleHandler(); + ch.setLevel(Level.FINE); + Logger.getLogger("").addHandler(ch); + Logger.getLogger("").setLevel(Level.FINE); - String keyStoreFilePath = System.getProperty("keystore.file.path"); - if (keyStoreFilePath == null || keyStoreFilePath.isEmpty()) { - System.out.println("ERROR: System property keystore.file.path not set. Exiting now!"); - System.exit(1); - } + String keyStoreFilePath = System.getProperty("keystore.file.path"); + if (keyStoreFilePath == null || keyStoreFilePath.isEmpty()) { + System.out.println("ERROR: System property keystore.file.path not set. Exiting now!"); + System.exit(1); + } - String keyStoreFilePassword = System.getProperty("keystore.file.password"); - if (keyStoreFilePassword == null || keyStoreFilePassword.isEmpty()) { - System.out.println("ERROR: System property keystore.file.password not set. Exiting now!"); - System.exit(1); - } + String keyStoreFilePassword = System.getProperty("keystore.file.password"); + if (keyStoreFilePassword == null || keyStoreFilePassword.isEmpty()) { + System.out.println("ERROR: System property keystore.file.password not set. Exiting now!"); + System.exit(1); + } - // Configure the server. - ServerBootstrap bootstrap = new ServerBootstrap(new NioServerSocketChannelFactory( - Executors.newCachedThreadPool(), Executors.newCachedThreadPool())); + // Configure the server. + ServerBootstrap bootstrap = new ServerBootstrap(new NioServerSocketChannelFactory( + Executors.newCachedThreadPool(), Executors.newCachedThreadPool())); - // Set up the event pipeline factory. - bootstrap.setPipelineFactory(new WebSocketSslServerPipelineFactory()); + // Set up the event pipeline factory. + bootstrap.setPipelineFactory(new WebSocketSslServerPipelineFactory()); - // Bind and start to accept incoming connections. - bootstrap.bind(new InetSocketAddress(8081)); + // Bind and start to accept incoming connections. + bootstrap.bind(new InetSocketAddress(8081)); - System.out - .println("Web Socket Server started on 8081. Open your browser and navigate to https://localhost:8081/"); - } + System.out + .println("Web Socket Server started on 8081. Open your browser and navigate to https://localhost:8081/"); + } } diff --git a/src/main/java/io/netty/example/http/websocketx/sslserver/WebSocketSslServerHandler.java b/src/main/java/io/netty/example/http/websocketx/sslserver/WebSocketSslServerHandler.java index 8274fa6354..c5dc57e373 100644 --- a/src/main/java/io/netty/example/http/websocketx/sslserver/WebSocketSslServerHandler.java +++ b/src/main/java/io/netty/example/http/websocketx/sslserver/WebSocketSslServerHandler.java @@ -48,99 +48,99 @@ import io.netty.util.CharsetUtil; * Handles handshakes and messages */ public class WebSocketSslServerHandler extends SimpleChannelUpstreamHandler { - private static final InternalLogger logger = InternalLoggerFactory.getInstance(WebSocketSslServerHandler.class); + private static final InternalLogger logger = InternalLoggerFactory.getInstance(WebSocketSslServerHandler.class); - private static final String WEBSOCKET_PATH = "/websocket"; + private static final String WEBSOCKET_PATH = "/websocket"; - private WebSocketServerHandshaker handshaker = null; + private WebSocketServerHandshaker handshaker = null; - @Override - public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception { - Object msg = e.getMessage(); - if (msg instanceof HttpRequest) { - handleHttpRequest(ctx, (HttpRequest) msg); - } else if (msg instanceof WebSocketFrame) { - handleWebSocketFrame(ctx, (WebSocketFrame) msg); - } - } + @Override + public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception { + Object msg = e.getMessage(); + if (msg instanceof HttpRequest) { + handleHttpRequest(ctx, (HttpRequest) msg); + } else if (msg instanceof WebSocketFrame) { + handleWebSocketFrame(ctx, (WebSocketFrame) msg); + } + } - private void handleHttpRequest(ChannelHandlerContext ctx, HttpRequest req) throws Exception { - // Allow only GET methods. - if (req.getMethod() != GET) { - sendHttpResponse(ctx, req, new DefaultHttpResponse(HTTP_1_1, FORBIDDEN)); - return; - } + private void handleHttpRequest(ChannelHandlerContext ctx, HttpRequest req) throws Exception { + // Allow only GET methods. + if (req.getMethod() != GET) { + sendHttpResponse(ctx, req, new DefaultHttpResponse(HTTP_1_1, FORBIDDEN)); + return; + } - // Send the demo page and favicon.ico - if (req.getUri().equals("/")) { - HttpResponse res = new DefaultHttpResponse(HTTP_1_1, OK); + // Send the demo page and favicon.ico + if (req.getUri().equals("/")) { + HttpResponse res = new DefaultHttpResponse(HTTP_1_1, OK); - ChannelBuffer content = WebSocketSslServerIndexPage.getContent(getWebSocketLocation(req)); + ChannelBuffer content = WebSocketSslServerIndexPage.getContent(getWebSocketLocation(req)); - res.setHeader(CONTENT_TYPE, "text/html; charset=UTF-8"); - setContentLength(res, content.readableBytes()); + res.setHeader(CONTENT_TYPE, "text/html; charset=UTF-8"); + setContentLength(res, content.readableBytes()); - res.setContent(content); - sendHttpResponse(ctx, req, res); - return; - } else if (req.getUri().equals("/favicon.ico")) { - HttpResponse res = new DefaultHttpResponse(HTTP_1_1, NOT_FOUND); - sendHttpResponse(ctx, req, res); - return; - } + res.setContent(content); + sendHttpResponse(ctx, req, res); + return; + } else if (req.getUri().equals("/favicon.ico")) { + HttpResponse res = new DefaultHttpResponse(HTTP_1_1, NOT_FOUND); + sendHttpResponse(ctx, req, res); + return; + } - // Handshake - WebSocketServerHandshakerFactory wsFactory = new WebSocketServerHandshakerFactory( - this.getWebSocketLocation(req), null, false); - this.handshaker = wsFactory.newHandshaker(req); - if (this.handshaker == null) { - wsFactory.sendUnsupportedWebSocketVersionResponse(ctx.getChannel()); - } else { - this.handshaker.performOpeningHandshake(ctx.getChannel(), req); - } - } + // Handshake + WebSocketServerHandshakerFactory wsFactory = new WebSocketServerHandshakerFactory( + this.getWebSocketLocation(req), null, false); + this.handshaker = wsFactory.newHandshaker(req); + if (this.handshaker == null) { + wsFactory.sendUnsupportedWebSocketVersionResponse(ctx.getChannel()); + } else { + this.handshaker.performOpeningHandshake(ctx.getChannel(), req); + } + } - private void handleWebSocketFrame(ChannelHandlerContext ctx, WebSocketFrame frame) { + private void handleWebSocketFrame(ChannelHandlerContext ctx, WebSocketFrame frame) { - // Check for closing frame - if (frame instanceof CloseWebSocketFrame) { - this.handshaker.performClosingHandshake(ctx.getChannel(), (CloseWebSocketFrame) frame); - return; - } else if (frame instanceof PingWebSocketFrame) { - ctx.getChannel().write(new PongWebSocketFrame(frame.getBinaryData())); - return; - } else if (!(frame instanceof TextWebSocketFrame)) { - throw new UnsupportedOperationException(String.format("%s frame types not supported", frame.getClass() - .getName())); - } + // Check for closing frame + if (frame instanceof CloseWebSocketFrame) { + this.handshaker.performClosingHandshake(ctx.getChannel(), (CloseWebSocketFrame) frame); + return; + } else if (frame instanceof PingWebSocketFrame) { + ctx.getChannel().write(new PongWebSocketFrame(frame.getBinaryData())); + return; + } else if (!(frame instanceof TextWebSocketFrame)) { + throw new UnsupportedOperationException(String.format("%s frame types not supported", frame.getClass() + .getName())); + } - // Send the uppercase string back. - String request = ((TextWebSocketFrame) frame).getText(); - logger.debug(String.format("Channel %s received %s", ctx.getChannel().getId(), request)); - ctx.getChannel().write(new TextWebSocketFrame(request.toUpperCase())); - } + // Send the uppercase string back. + String request = ((TextWebSocketFrame) frame).getText(); + logger.debug(String.format("Channel %s received %s", ctx.getChannel().getId(), request)); + ctx.getChannel().write(new TextWebSocketFrame(request.toUpperCase())); + } - private void sendHttpResponse(ChannelHandlerContext ctx, HttpRequest req, HttpResponse res) { - // Generate an error page if response status code is not OK (200). - if (res.getStatus().getCode() != 200) { - res.setContent(ChannelBuffers.copiedBuffer(res.getStatus().toString(), CharsetUtil.UTF_8)); - setContentLength(res, res.getContent().readableBytes()); - } + private void sendHttpResponse(ChannelHandlerContext ctx, HttpRequest req, HttpResponse res) { + // Generate an error page if response status code is not OK (200). + if (res.getStatus().getCode() != 200) { + res.setContent(ChannelBuffers.copiedBuffer(res.getStatus().toString(), CharsetUtil.UTF_8)); + setContentLength(res, res.getContent().readableBytes()); + } - // Send the response and close the connection if necessary. - ChannelFuture f = ctx.getChannel().write(res); - if (!isKeepAlive(req) || res.getStatus().getCode() != 200) { - f.addListener(ChannelFutureListener.CLOSE); - } - } + // Send the response and close the connection if necessary. + ChannelFuture f = ctx.getChannel().write(res); + if (!isKeepAlive(req) || res.getStatus().getCode() != 200) { + f.addListener(ChannelFutureListener.CLOSE); + } + } - @Override - public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception { - e.getCause().printStackTrace(); - e.getChannel().close(); - } + @Override + public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception { + e.getCause().printStackTrace(); + e.getChannel().close(); + } - private String getWebSocketLocation(HttpRequest req) { - return "wss://" + req.getHeader(HttpHeaders.Names.HOST) + WEBSOCKET_PATH; - } + private String getWebSocketLocation(HttpRequest req) { + return "wss://" + req.getHeader(HttpHeaders.Names.HOST) + WEBSOCKET_PATH; + } } diff --git a/src/main/java/io/netty/example/http/websocketx/sslserver/WebSocketSslServerIndexPage.java b/src/main/java/io/netty/example/http/websocketx/sslserver/WebSocketSslServerIndexPage.java index 41cc15aafe..a06353bb89 100644 --- a/src/main/java/io/netty/example/http/websocketx/sslserver/WebSocketSslServerIndexPage.java +++ b/src/main/java/io/netty/example/http/websocketx/sslserver/WebSocketSslServerIndexPage.java @@ -24,69 +24,69 @@ import io.netty.util.CharsetUtil; */ public class WebSocketSslServerIndexPage { - private static final String NEWLINE = "\r\n"; + private static final String NEWLINE = "\r\n"; - public static ChannelBuffer getContent(String webSocketLocation) { - return ChannelBuffers - .copiedBuffer( - "Web Socket Test" - + NEWLINE - + "" - + NEWLINE - + "" - + NEWLINE - + "
" - + NEWLINE - + "" - + "" - + NEWLINE + "

Output

" + NEWLINE - + "" - + NEWLINE + "
" + NEWLINE + "" + NEWLINE + "" + NEWLINE, - CharsetUtil.US_ASCII); - } + public static ChannelBuffer getContent(String webSocketLocation) { + return ChannelBuffers + .copiedBuffer( + "Web Socket Test" + + NEWLINE + + "" + + NEWLINE + + "" + + NEWLINE + + "
" + + NEWLINE + + "" + + "" + + NEWLINE + "

Output

" + NEWLINE + + "" + + NEWLINE + "
" + NEWLINE + "" + NEWLINE + "" + NEWLINE, + CharsetUtil.US_ASCII); + } } diff --git a/src/main/java/io/netty/example/http/websocketx/sslserver/WebSocketSslServerPipelineFactory.java b/src/main/java/io/netty/example/http/websocketx/sslserver/WebSocketSslServerPipelineFactory.java index 11fa4082cd..6393738eab 100644 --- a/src/main/java/io/netty/example/http/websocketx/sslserver/WebSocketSslServerPipelineFactory.java +++ b/src/main/java/io/netty/example/http/websocketx/sslserver/WebSocketSslServerPipelineFactory.java @@ -29,19 +29,19 @@ import io.netty.handler.ssl.SslHandler; /** */ public class WebSocketSslServerPipelineFactory implements ChannelPipelineFactory { - @Override - public ChannelPipeline getPipeline() throws Exception { - // Create a default pipeline implementation. - ChannelPipeline pipeline = pipeline(); + @Override + public ChannelPipeline getPipeline() throws Exception { + // Create a default pipeline implementation. + ChannelPipeline pipeline = pipeline(); - SSLEngine engine = WebSocketSslServerSslContext.getInstance().getServerContext().createSSLEngine(); - engine.setUseClientMode(false); - pipeline.addLast("ssl", new SslHandler(engine)); + SSLEngine engine = WebSocketSslServerSslContext.getInstance().getServerContext().createSSLEngine(); + engine.setUseClientMode(false); + pipeline.addLast("ssl", new SslHandler(engine)); - pipeline.addLast("decoder", new HttpRequestDecoder()); - pipeline.addLast("aggregator", new HttpChunkAggregator(65536)); - pipeline.addLast("encoder", new HttpResponseEncoder()); - pipeline.addLast("handler", new WebSocketSslServerHandler()); - return pipeline; - } + pipeline.addLast("decoder", new HttpRequestDecoder()); + pipeline.addLast("aggregator", new HttpChunkAggregator(65536)); + pipeline.addLast("encoder", new HttpResponseEncoder()); + pipeline.addLast("handler", new WebSocketSslServerHandler()); + return pipeline; + } } diff --git a/src/main/java/io/netty/example/http/websocketx/sslserver/WebSocketSslServerSslContext.java b/src/main/java/io/netty/example/http/websocketx/sslserver/WebSocketSslServerSslContext.java index 3ea4ff7ac4..b189d0de22 100644 --- a/src/main/java/io/netty/example/http/websocketx/sslserver/WebSocketSslServerSslContext.java +++ b/src/main/java/io/netty/example/http/websocketx/sslserver/WebSocketSslServerSslContext.java @@ -30,73 +30,73 @@ import io.netty.logging.InternalLoggerFactory; */ public class WebSocketSslServerSslContext { - private static final InternalLogger logger = InternalLoggerFactory.getInstance(WebSocketSslServerSslContext.class); - private static final String PROTOCOL = "TLS"; - private SSLContext _serverContext; + private static final InternalLogger logger = InternalLoggerFactory.getInstance(WebSocketSslServerSslContext.class); + private static final String PROTOCOL = "TLS"; + private SSLContext _serverContext; - /** - * Returns the singleton instance for this class - */ - public static WebSocketSslServerSslContext getInstance() { - return SingletonHolder.INSTANCE; - } + /** + * Returns the singleton instance for this class + */ + public static WebSocketSslServerSslContext getInstance() { + return SingletonHolder.INSTANCE; + } - /** - * SingletonHolder is loaded on the first execution of Singleton.getInstance() or the first access to - * SingletonHolder.INSTANCE, not before. - * - * See http://en.wikipedia.org/wiki/Singleton_pattern - */ - private static class SingletonHolder { + /** + * SingletonHolder is loaded on the first execution of Singleton.getInstance() or the first access to + * SingletonHolder.INSTANCE, not before. + * + * See http://en.wikipedia.org/wiki/Singleton_pattern + */ + private static class SingletonHolder { - public static final WebSocketSslServerSslContext INSTANCE = new WebSocketSslServerSslContext(); - } + public static final WebSocketSslServerSslContext INSTANCE = new WebSocketSslServerSslContext(); + } - /** - * Constructor for singleton - */ - private WebSocketSslServerSslContext() { - try { - // Key store (Server side certificate) - String algorithm = Security.getProperty("ssl.KeyManagerFactory.algorithm"); - if (algorithm == null) { - algorithm = "SunX509"; - } + /** + * Constructor for singleton + */ + private WebSocketSslServerSslContext() { + try { + // Key store (Server side certificate) + String algorithm = Security.getProperty("ssl.KeyManagerFactory.algorithm"); + if (algorithm == null) { + algorithm = "SunX509"; + } - SSLContext serverContext = null; - try { - String keyStoreFilePath = System.getProperty("keystore.file.path"); - String keyStoreFilePassword = System.getProperty("keystore.file.password"); + SSLContext serverContext = null; + try { + String keyStoreFilePath = System.getProperty("keystore.file.path"); + String keyStoreFilePassword = System.getProperty("keystore.file.password"); - KeyStore ks = KeyStore.getInstance("JKS"); - FileInputStream fin = new FileInputStream(keyStoreFilePath); - ks.load(fin, keyStoreFilePassword.toCharArray()); + KeyStore ks = KeyStore.getInstance("JKS"); + FileInputStream fin = new FileInputStream(keyStoreFilePath); + ks.load(fin, keyStoreFilePassword.toCharArray()); - // Set up key manager factory to use our key store - // Assume key password is the same as the key store file - // password - KeyManagerFactory kmf = KeyManagerFactory.getInstance(algorithm); - kmf.init(ks, keyStoreFilePassword.toCharArray()); + // Set up key manager factory to use our key store + // Assume key password is the same as the key store file + // password + KeyManagerFactory kmf = KeyManagerFactory.getInstance(algorithm); + kmf.init(ks, keyStoreFilePassword.toCharArray()); - // Initialise the SSLContext to work with our key managers. - serverContext = SSLContext.getInstance(PROTOCOL); - serverContext.init(kmf.getKeyManagers(), null, null); - } catch (Exception e) { - throw new Error("Failed to initialize the server-side SSLContext", e); - } - _serverContext = serverContext; - } catch (Exception ex) { - logger.error("Error initializing SslContextManager. " + ex.getMessage(), ex); - System.exit(1); + // Initialise the SSLContext to work with our key managers. + serverContext = SSLContext.getInstance(PROTOCOL); + serverContext.init(kmf.getKeyManagers(), null, null); + } catch (Exception e) { + throw new Error("Failed to initialize the server-side SSLContext", e); + } + _serverContext = serverContext; + } catch (Exception ex) { + logger.error("Error initializing SslContextManager. " + ex.getMessage(), ex); + System.exit(1); - } - } + } + } - /** - * Returns the server context with server side key store - */ - public SSLContext getServerContext() { - return _serverContext; - } + /** + * Returns the server context with server side key store + */ + public SSLContext getServerContext() { + return _serverContext; + } } diff --git a/src/main/java/io/netty/handler/codec/http/websocketx/BinaryWebSocketFrame.java b/src/main/java/io/netty/handler/codec/http/websocketx/BinaryWebSocketFrame.java index d68df00257..ed9f87dbe0 100644 --- a/src/main/java/io/netty/handler/codec/http/websocketx/BinaryWebSocketFrame.java +++ b/src/main/java/io/netty/handler/codec/http/websocketx/BinaryWebSocketFrame.java @@ -23,42 +23,42 @@ import io.netty.buffer.ChannelBuffers; */ public class BinaryWebSocketFrame extends WebSocketFrame { - /** - * Creates a new empty binary frame. - */ - public BinaryWebSocketFrame() { - this.setBinaryData(ChannelBuffers.EMPTY_BUFFER); - } + /** + * Creates a new empty binary frame. + */ + public BinaryWebSocketFrame() { + this.setBinaryData(ChannelBuffers.EMPTY_BUFFER); + } - /** - * Creates a new binary frame with the specified binary data. The final fragment flag is set to true. - * - * @param binaryData - * the content of the frame. - */ - public BinaryWebSocketFrame(ChannelBuffer binaryData) { - this.setBinaryData(binaryData); - } + /** + * Creates a new binary frame with the specified binary data. The final fragment flag is set to true. + * + * @param binaryData + * the content of the frame. + */ + public BinaryWebSocketFrame(ChannelBuffer binaryData) { + this.setBinaryData(binaryData); + } - /** - * Creates a new binary frame with the specified binary data and the final fragment flag. - * - * @param finalFragment - * flag indicating if this frame is the final fragment - * @param rsv - * reserved bits used for protocol extensions - * @param binaryData - * the content of the frame. - */ - public BinaryWebSocketFrame(boolean finalFragment, int rsv, ChannelBuffer binaryData) { - this.setFinalFragment(finalFragment); - this.setRsv(rsv); - this.setBinaryData(binaryData); - } + /** + * Creates a new binary frame with the specified binary data and the final fragment flag. + * + * @param finalFragment + * flag indicating if this frame is the final fragment + * @param rsv + * reserved bits used for protocol extensions + * @param binaryData + * the content of the frame. + */ + public BinaryWebSocketFrame(boolean finalFragment, int rsv, ChannelBuffer binaryData) { + this.setFinalFragment(finalFragment); + this.setRsv(rsv); + this.setBinaryData(binaryData); + } - @Override - public String toString() { - return getClass().getSimpleName() + "(data: " + getBinaryData() + ')'; - } + @Override + public String toString() { + return getClass().getSimpleName() + "(data: " + getBinaryData() + ')'; + } } diff --git a/src/main/java/io/netty/handler/codec/http/websocketx/CloseWebSocketFrame.java b/src/main/java/io/netty/handler/codec/http/websocketx/CloseWebSocketFrame.java index 4f05c39aa5..67a61f8199 100644 --- a/src/main/java/io/netty/handler/codec/http/websocketx/CloseWebSocketFrame.java +++ b/src/main/java/io/netty/handler/codec/http/websocketx/CloseWebSocketFrame.java @@ -22,28 +22,28 @@ import io.netty.buffer.ChannelBuffers; */ public class CloseWebSocketFrame extends WebSocketFrame { - /** - * Creates a new empty close frame. - */ - public CloseWebSocketFrame() { - this.setBinaryData(ChannelBuffers.EMPTY_BUFFER); - } + /** + * Creates a new empty close frame. + */ + public CloseWebSocketFrame() { + this.setBinaryData(ChannelBuffers.EMPTY_BUFFER); + } - /** - * Creates a new close frame - * - * @param finalFragment - * flag indicating if this frame is the final fragment - * @param rsv - * reserved bits used for protocol extensions - */ - public CloseWebSocketFrame(boolean finalFragment, int rsv) { - this.setFinalFragment(finalFragment); - this.setRsv(rsv); - } + /** + * Creates a new close frame + * + * @param finalFragment + * flag indicating if this frame is the final fragment + * @param rsv + * reserved bits used for protocol extensions + */ + public CloseWebSocketFrame(boolean finalFragment, int rsv) { + this.setFinalFragment(finalFragment); + this.setRsv(rsv); + } - @Override - public String toString() { - return getClass().getSimpleName(); - } + @Override + public String toString() { + return getClass().getSimpleName(); + } } diff --git a/src/main/java/io/netty/handler/codec/http/websocketx/ContinuationWebSocketFrame.java b/src/main/java/io/netty/handler/codec/http/websocketx/ContinuationWebSocketFrame.java index bb9d967211..ca77115803 100644 --- a/src/main/java/io/netty/handler/codec/http/websocketx/ContinuationWebSocketFrame.java +++ b/src/main/java/io/netty/handler/codec/http/websocketx/ContinuationWebSocketFrame.java @@ -25,114 +25,114 @@ import io.netty.util.CharsetUtil; */ public class ContinuationWebSocketFrame extends WebSocketFrame { - private String aggregatedText = null; + private String aggregatedText = null; - /** - * Creates a new empty continuation frame. - */ - public ContinuationWebSocketFrame() { - this.setBinaryData(ChannelBuffers.EMPTY_BUFFER); - } + /** + * Creates a new empty continuation frame. + */ + public ContinuationWebSocketFrame() { + this.setBinaryData(ChannelBuffers.EMPTY_BUFFER); + } - /** - * Creates a new continuation frame with the specified binary data. The final fragment flag is set to true. - * - * @param binaryData - * the content of the frame. - */ - public ContinuationWebSocketFrame(ChannelBuffer binaryData) { - this.setBinaryData(binaryData); - } + /** + * Creates a new continuation frame with the specified binary data. The final fragment flag is set to true. + * + * @param binaryData + * the content of the frame. + */ + public ContinuationWebSocketFrame(ChannelBuffer binaryData) { + this.setBinaryData(binaryData); + } - /** - * Creates a new continuation frame with the specified binary data - * - * @param finalFragment - * flag indicating if this frame is the final fragment - * @param rsv - * reserved bits used for protocol extensions - * @param binaryData - * the content of the frame. - */ - public ContinuationWebSocketFrame(boolean finalFragment, int rsv, ChannelBuffer binaryData) { - this.setFinalFragment(finalFragment); - this.setRsv(rsv); - this.setBinaryData(binaryData); - } + /** + * Creates a new continuation frame with the specified binary data + * + * @param finalFragment + * flag indicating if this frame is the final fragment + * @param rsv + * reserved bits used for protocol extensions + * @param binaryData + * the content of the frame. + */ + public ContinuationWebSocketFrame(boolean finalFragment, int rsv, ChannelBuffer binaryData) { + this.setFinalFragment(finalFragment); + this.setRsv(rsv); + this.setBinaryData(binaryData); + } - /** - * Creates a new continuation frame with the specified binary data - * - * @param finalFragment - * flag indicating if this frame is the final fragment - * @param rsv - * reserved bits used for protocol extensions - * @param binaryData - * the content of the frame. - * @param aggregatedText - * Aggregated text set by decoder on the final continuation frame of a fragmented text message - */ - public ContinuationWebSocketFrame(boolean finalFragment, int rsv, ChannelBuffer binaryData, String aggregatedText) { - this.setFinalFragment(finalFragment); - this.setRsv(rsv); - this.setBinaryData(binaryData); - this.aggregatedText = aggregatedText; - } + /** + * Creates a new continuation frame with the specified binary data + * + * @param finalFragment + * flag indicating if this frame is the final fragment + * @param rsv + * reserved bits used for protocol extensions + * @param binaryData + * the content of the frame. + * @param aggregatedText + * Aggregated text set by decoder on the final continuation frame of a fragmented text message + */ + public ContinuationWebSocketFrame(boolean finalFragment, int rsv, ChannelBuffer binaryData, String aggregatedText) { + this.setFinalFragment(finalFragment); + this.setRsv(rsv); + this.setBinaryData(binaryData); + this.aggregatedText = aggregatedText; + } - /** - * Creates a new continuation frame with the specified text data - * - * @param finalFragment - * flag indicating if this frame is the final fragment - * @param rsv - * reserved bits used for protocol extensions - * @param text - * text content of the frame. - */ - public ContinuationWebSocketFrame(boolean finalFragment, int rsv, String text) { - this.setFinalFragment(finalFragment); - this.setRsv(rsv); - this.setText(text); - } + /** + * Creates a new continuation frame with the specified text data + * + * @param finalFragment + * flag indicating if this frame is the final fragment + * @param rsv + * reserved bits used for protocol extensions + * @param text + * text content of the frame. + */ + public ContinuationWebSocketFrame(boolean finalFragment, int rsv, String text) { + this.setFinalFragment(finalFragment); + this.setRsv(rsv); + this.setText(text); + } - /** - * Returns the text data in this frame - */ - public String getText() { - if (this.getBinaryData() == null) { - return null; - } - return this.getBinaryData().toString(CharsetUtil.UTF_8); - } + /** + * Returns the text data in this frame + */ + public String getText() { + if (this.getBinaryData() == null) { + return null; + } + return this.getBinaryData().toString(CharsetUtil.UTF_8); + } - /** - * Sets the string for this frame - * - * @param text - * text to store - */ - public void setText(String text) { - if (text == null || text.isEmpty()) { - this.setBinaryData(ChannelBuffers.EMPTY_BUFFER); - } else { - this.setBinaryData(ChannelBuffers.copiedBuffer(text, CharsetUtil.UTF_8)); - } - } + /** + * Sets the string for this frame + * + * @param text + * text to store + */ + public void setText(String text) { + if (text == null || text.isEmpty()) { + this.setBinaryData(ChannelBuffers.EMPTY_BUFFER); + } else { + this.setBinaryData(ChannelBuffers.copiedBuffer(text, CharsetUtil.UTF_8)); + } + } - @Override - public String toString() { - return getClass().getSimpleName() + "(data: " + getBinaryData() + ')'; - } + @Override + public String toString() { + return getClass().getSimpleName() + "(data: " + getBinaryData() + ')'; + } - /** - * Aggregated text returned by decoder on the final continuation frame of a fragmented text message - */ - public String getAggregatedText() { - return aggregatedText; - } + /** + * Aggregated text returned by decoder on the final continuation frame of a fragmented text message + */ + public String getAggregatedText() { + return aggregatedText; + } - public void setAggregatedText(String aggregatedText) { - this.aggregatedText = aggregatedText; - } + public void setAggregatedText(String aggregatedText) { + this.aggregatedText = aggregatedText; + } } diff --git a/src/main/java/io/netty/handler/codec/http/websocketx/PingWebSocketFrame.java b/src/main/java/io/netty/handler/codec/http/websocketx/PingWebSocketFrame.java index 90c6e732a8..5815faad97 100644 --- a/src/main/java/io/netty/handler/codec/http/websocketx/PingWebSocketFrame.java +++ b/src/main/java/io/netty/handler/codec/http/websocketx/PingWebSocketFrame.java @@ -23,43 +23,43 @@ import io.netty.buffer.ChannelBuffers; */ public class PingWebSocketFrame extends WebSocketFrame { - /** - * Creates a new empty ping frame. - */ - public PingWebSocketFrame() { - this.setFinalFragment(true); - this.setBinaryData(ChannelBuffers.EMPTY_BUFFER); - } + /** + * Creates a new empty ping frame. + */ + public PingWebSocketFrame() { + this.setFinalFragment(true); + this.setBinaryData(ChannelBuffers.EMPTY_BUFFER); + } - /** - * Creates a new ping frame with the specified binary data. - * - * @param binaryData - * the content of the frame. - */ - public PingWebSocketFrame(ChannelBuffer binaryData) { - this.setBinaryData(binaryData); - } + /** + * Creates a new ping frame with the specified binary data. + * + * @param binaryData + * the content of the frame. + */ + public PingWebSocketFrame(ChannelBuffer binaryData) { + this.setBinaryData(binaryData); + } - /** - * Creates a new ping frame with the specified binary data - * - * @param finalFragment - * flag indicating if this frame is the final fragment - * @param rsv - * reserved bits used for protocol extensions - * @param binaryData - * the content of the frame. - */ - public PingWebSocketFrame(boolean finalFragment, int rsv, ChannelBuffer binaryData) { - this.setFinalFragment(finalFragment); - this.setRsv(rsv); - this.setBinaryData(binaryData); - } + /** + * Creates a new ping frame with the specified binary data + * + * @param finalFragment + * flag indicating if this frame is the final fragment + * @param rsv + * reserved bits used for protocol extensions + * @param binaryData + * the content of the frame. + */ + public PingWebSocketFrame(boolean finalFragment, int rsv, ChannelBuffer binaryData) { + this.setFinalFragment(finalFragment); + this.setRsv(rsv); + this.setBinaryData(binaryData); + } - @Override - public String toString() { - return getClass().getSimpleName() + "(data: " + getBinaryData() + ')'; - } + @Override + public String toString() { + return getClass().getSimpleName() + "(data: " + getBinaryData() + ')'; + } } diff --git a/src/main/java/io/netty/handler/codec/http/websocketx/PongWebSocketFrame.java b/src/main/java/io/netty/handler/codec/http/websocketx/PongWebSocketFrame.java index bc85205414..ee3fd861b4 100644 --- a/src/main/java/io/netty/handler/codec/http/websocketx/PongWebSocketFrame.java +++ b/src/main/java/io/netty/handler/codec/http/websocketx/PongWebSocketFrame.java @@ -23,42 +23,42 @@ import io.netty.buffer.ChannelBuffers; */ public class PongWebSocketFrame extends WebSocketFrame { - /** - * Creates a new empty pong frame. - */ - public PongWebSocketFrame() { - this.setBinaryData(ChannelBuffers.EMPTY_BUFFER); - } + /** + * Creates a new empty pong frame. + */ + public PongWebSocketFrame() { + this.setBinaryData(ChannelBuffers.EMPTY_BUFFER); + } - /** - * Creates a new pong frame with the specified binary data. - * - * @param binaryData - * the content of the frame. - */ - public PongWebSocketFrame(ChannelBuffer binaryData) { - this.setBinaryData(binaryData); - } + /** + * Creates a new pong frame with the specified binary data. + * + * @param binaryData + * the content of the frame. + */ + public PongWebSocketFrame(ChannelBuffer binaryData) { + this.setBinaryData(binaryData); + } - /** - * Creates a new pong frame with the specified binary data - * - * @param finalFragment - * flag indicating if this frame is the final fragment - * @param rsv - * reserved bits used for protocol extensions - * @param binaryData - * the content of the frame. - */ - public PongWebSocketFrame(boolean finalFragment, int rsv, ChannelBuffer binaryData) { - this.setFinalFragment(finalFragment); - this.setRsv(rsv); - this.setBinaryData(binaryData); - } + /** + * Creates a new pong frame with the specified binary data + * + * @param finalFragment + * flag indicating if this frame is the final fragment + * @param rsv + * reserved bits used for protocol extensions + * @param binaryData + * the content of the frame. + */ + public PongWebSocketFrame(boolean finalFragment, int rsv, ChannelBuffer binaryData) { + this.setFinalFragment(finalFragment); + this.setRsv(rsv); + this.setBinaryData(binaryData); + } - @Override - public String toString() { - return getClass().getSimpleName() + "(data: " + getBinaryData() + ')'; - } + @Override + public String toString() { + return getClass().getSimpleName() + "(data: " + getBinaryData() + ')'; + } } diff --git a/src/main/java/io/netty/handler/codec/http/websocketx/TextWebSocketFrame.java b/src/main/java/io/netty/handler/codec/http/websocketx/TextWebSocketFrame.java index 6cb774f921..0087ced4e2 100644 --- a/src/main/java/io/netty/handler/codec/http/websocketx/TextWebSocketFrame.java +++ b/src/main/java/io/netty/handler/codec/http/websocketx/TextWebSocketFrame.java @@ -24,98 +24,98 @@ import io.netty.util.CharsetUtil; */ public class TextWebSocketFrame extends WebSocketFrame { - /** - * Creates a new empty text frame. - */ - public TextWebSocketFrame() { - this.setBinaryData(ChannelBuffers.EMPTY_BUFFER); - } + /** + * Creates a new empty text frame. + */ + public TextWebSocketFrame() { + this.setBinaryData(ChannelBuffers.EMPTY_BUFFER); + } - /** - * Creates a new text frame with the specified text string. The final fragment flag is set to true. - * - * @param text - * String to put in the frame - */ - public TextWebSocketFrame(String text) { - if (text == null || text.isEmpty()) { - this.setBinaryData(ChannelBuffers.EMPTY_BUFFER); - } else { - this.setBinaryData(ChannelBuffers.copiedBuffer(text, CharsetUtil.UTF_8)); - } - } + /** + * Creates a new text frame with the specified text string. The final fragment flag is set to true. + * + * @param text + * String to put in the frame + */ + public TextWebSocketFrame(String text) { + if (text == null || text.isEmpty()) { + this.setBinaryData(ChannelBuffers.EMPTY_BUFFER); + } else { + this.setBinaryData(ChannelBuffers.copiedBuffer(text, CharsetUtil.UTF_8)); + } + } - /** - * Creates a new text frame with the specified binary data. The final fragment flag is set to true. - * - * @param binaryData - * the content of the frame. Must be UTF-8 encoded - */ - public TextWebSocketFrame(ChannelBuffer binaryData) { - this.setBinaryData(binaryData); - } + /** + * Creates a new text frame with the specified binary data. The final fragment flag is set to true. + * + * @param binaryData + * the content of the frame. Must be UTF-8 encoded + */ + public TextWebSocketFrame(ChannelBuffer binaryData) { + this.setBinaryData(binaryData); + } - /** - * Creates a new text frame with the specified text string. The final fragment flag is set to true. - * - * @param finalFragment - * flag indicating if this frame is the final fragment - * @param rsv - * reserved bits used for protocol extensions - * @param text - * String to put in the frame - */ - public TextWebSocketFrame(boolean finalFragment, int rsv, String text) { - this.setFinalFragment(finalFragment); - this.setRsv(rsv); - if (text == null || text.isEmpty()) { - this.setBinaryData(ChannelBuffers.EMPTY_BUFFER); - } else { - this.setBinaryData(ChannelBuffers.copiedBuffer(text, CharsetUtil.UTF_8)); - } - } + /** + * Creates a new text frame with the specified text string. The final fragment flag is set to true. + * + * @param finalFragment + * flag indicating if this frame is the final fragment + * @param rsv + * reserved bits used for protocol extensions + * @param text + * String to put in the frame + */ + public TextWebSocketFrame(boolean finalFragment, int rsv, String text) { + this.setFinalFragment(finalFragment); + this.setRsv(rsv); + if (text == null || text.isEmpty()) { + this.setBinaryData(ChannelBuffers.EMPTY_BUFFER); + } else { + this.setBinaryData(ChannelBuffers.copiedBuffer(text, CharsetUtil.UTF_8)); + } + } - /** - * Creates a new text frame with the specified binary data. The final fragment flag is set to true. - * - * @param finalFragment - * flag indicating if this frame is the final fragment - * @param rsv - * reserved bits used for protocol extensions - * @param binaryData - * the content of the frame. Must be UTF-8 encoded - */ - public TextWebSocketFrame(boolean finalFragment, int rsv, ChannelBuffer binaryData) { - this.setFinalFragment(finalFragment); - this.setRsv(rsv); - this.setBinaryData(binaryData); - } + /** + * Creates a new text frame with the specified binary data. The final fragment flag is set to true. + * + * @param finalFragment + * flag indicating if this frame is the final fragment + * @param rsv + * reserved bits used for protocol extensions + * @param binaryData + * the content of the frame. Must be UTF-8 encoded + */ + public TextWebSocketFrame(boolean finalFragment, int rsv, ChannelBuffer binaryData) { + this.setFinalFragment(finalFragment); + this.setRsv(rsv); + this.setBinaryData(binaryData); + } - /** - * Returns the text data in this frame - */ - public String getText() { - if (this.getBinaryData() == null) { - return null; - } - return this.getBinaryData().toString(CharsetUtil.UTF_8); - } + /** + * Returns the text data in this frame + */ + public String getText() { + if (this.getBinaryData() == null) { + return null; + } + return this.getBinaryData().toString(CharsetUtil.UTF_8); + } - /** - * Sets the string for this frame - * - * @param text - * text to store - */ - public void setText(String text) { - if (text == null) { - throw new NullPointerException("text"); - } - this.setBinaryData(ChannelBuffers.copiedBuffer(text, CharsetUtil.UTF_8)); - } + /** + * Sets the string for this frame + * + * @param text + * text to store + */ + public void setText(String text) { + if (text == null) { + throw new NullPointerException("text"); + } + this.setBinaryData(ChannelBuffers.copiedBuffer(text, CharsetUtil.UTF_8)); + } - @Override - public String toString() { - return getClass().getSimpleName() + "(text: " + getText() + ')'; - } + @Override + public String toString() { + return getClass().getSimpleName() + "(text: " + getText() + ')'; + } } diff --git a/src/main/java/io/netty/handler/codec/http/websocketx/UTF8Exception.java b/src/main/java/io/netty/handler/codec/http/websocketx/UTF8Exception.java index 69a9abea86..9b1eaae803 100644 --- a/src/main/java/io/netty/handler/codec/http/websocketx/UTF8Exception.java +++ b/src/main/java/io/netty/handler/codec/http/websocketx/UTF8Exception.java @@ -23,9 +23,9 @@ package io.netty.handler.codec.http.websocketx; * Invalid UTF8 bytes encountered */ final class UTF8Exception extends RuntimeException { - private static final long serialVersionUID = 1L; + private static final long serialVersionUID = 1L; - UTF8Exception(String reason) { - super(reason); - } + UTF8Exception(String reason) { + super(reason); + } } diff --git a/src/main/java/io/netty/handler/codec/http/websocketx/UTF8Output.java b/src/main/java/io/netty/handler/codec/http/websocketx/UTF8Output.java index ef50d71292..58a2872a39 100644 --- a/src/main/java/io/netty/handler/codec/http/websocketx/UTF8Output.java +++ b/src/main/java/io/netty/handler/codec/http/websocketx/UTF8Output.java @@ -23,59 +23,59 @@ package io.netty.handler.codec.http.websocketx; * Checks UTF8 bytes for validity before converting it into a string */ final class UTF8Output { - private static final int UTF8_ACCEPT = 0; - private static final int UTF8_REJECT = 12; + private static final int UTF8_ACCEPT = 0; + private static final int UTF8_REJECT = 12; - private static final byte[] TYPES = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 10, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 3, 3, 11, - 6, 6, 6, 5, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 }; + private static final byte[] TYPES = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 10, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 3, 3, 11, + 6, 6, 6, 5, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 }; - private static final byte[] STATES = { 0, 12, 24, 36, 60, 96, 84, 12, 12, 12, 48, 72, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 0, 12, 12, 12, 12, 12, 0, 12, 0, 12, 12, 12, 24, 12, 12, 12, 12, 12, 24, 12, 24, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 24, 12, 12, 12, 12, 12, 24, 12, 12, 12, 12, 12, 12, 12, 24, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 36, 12, 36, 12, 12, 12, 36, 12, 12, 12, 12, 12, 36, 12, 36, 12, 12, 12, 36, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12 }; + private static final byte[] STATES = { 0, 12, 24, 36, 60, 96, 84, 12, 12, 12, 48, 72, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 0, 12, 12, 12, 12, 12, 0, 12, 0, 12, 12, 12, 24, 12, 12, 12, 12, 12, 24, 12, 24, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 24, 12, 12, 12, 12, 12, 24, 12, 12, 12, 12, 12, 12, 12, 24, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 36, 12, 36, 12, 12, 12, 36, 12, 12, 12, 12, 12, 36, 12, 36, 12, 12, 12, 36, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12 }; - private int state = UTF8_ACCEPT; - private int codep = 0; + private int state = UTF8_ACCEPT; + private int codep = 0; - private final StringBuilder stringBuilder; + private final StringBuilder stringBuilder; - UTF8Output(byte[] bytes) { - stringBuilder = new StringBuilder(bytes.length); - write(bytes); - } + UTF8Output(byte[] bytes) { + stringBuilder = new StringBuilder(bytes.length); + write(bytes); + } - public void write(byte[] bytes) { - for (byte b : bytes) { - write(b); - } - } + public void write(byte[] bytes) { + for (byte b : bytes) { + write(b); + } + } - public void write(int b) { - byte type = TYPES[b & 0xFF]; + public void write(int b) { + byte type = TYPES[b & 0xFF]; - codep = (state != UTF8_ACCEPT) ? (b & 0x3f) | (codep << 6) : (0xff >> type) & (b); + codep = (state != UTF8_ACCEPT) ? (b & 0x3f) | (codep << 6) : (0xff >> type) & (b); - state = STATES[state + type]; + state = STATES[state + type]; - if (state == UTF8_ACCEPT) { - stringBuilder.append((char) codep); - } else if (state == UTF8_REJECT) { - throw new UTF8Exception("bytes are not UTF-8"); - } - } + if (state == UTF8_ACCEPT) { + stringBuilder.append((char) codep); + } else if (state == UTF8_REJECT) { + throw new UTF8Exception("bytes are not UTF-8"); + } + } - @Override - public String toString() { - if (state != UTF8_ACCEPT) { - throw new UTF8Exception("bytes are not UTF-8"); - } - return stringBuilder.toString(); - } + @Override + public String toString() { + if (state != UTF8_ACCEPT) { + throw new UTF8Exception("bytes are not UTF-8"); + } + return stringBuilder.toString(); + } } diff --git a/src/main/java/io/netty/handler/codec/http/websocketx/WebSocket00FrameDecoder.java b/src/main/java/io/netty/handler/codec/http/websocketx/WebSocket00FrameDecoder.java index 57c79469bf..59f1722289 100644 --- a/src/main/java/io/netty/handler/codec/http/websocketx/WebSocket00FrameDecoder.java +++ b/src/main/java/io/netty/handler/codec/http/websocketx/WebSocket00FrameDecoder.java @@ -33,101 +33,101 @@ import io.netty.handler.codec.replay.VoidEnum; */ public class WebSocket00FrameDecoder extends ReplayingDecoder { - public static final int DEFAULT_MAX_FRAME_SIZE = 16384; + public static final int DEFAULT_MAX_FRAME_SIZE = 16384; - private final int maxFrameSize; - private boolean receivedClosingHandshake; + private final int maxFrameSize; + private boolean receivedClosingHandshake; - public WebSocket00FrameDecoder() { - this(DEFAULT_MAX_FRAME_SIZE); - } + public WebSocket00FrameDecoder() { + this(DEFAULT_MAX_FRAME_SIZE); + } - /** - * Creates a new instance of {@code WebSocketFrameDecoder} with the specified {@code maxFrameSize}. If the client - * sends a frame size larger than {@code maxFrameSize}, the channel will be closed. - * - * @param maxFrameSize - * the maximum frame size to decode - */ - public WebSocket00FrameDecoder(int maxFrameSize) { - this.maxFrameSize = maxFrameSize; - } + /** + * Creates a new instance of {@code WebSocketFrameDecoder} with the specified {@code maxFrameSize}. If the client + * sends a frame size larger than {@code maxFrameSize}, the channel will be closed. + * + * @param maxFrameSize + * the maximum frame size to decode + */ + public WebSocket00FrameDecoder(int maxFrameSize) { + this.maxFrameSize = maxFrameSize; + } - @Override - protected Object decode(ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer, VoidEnum state) - throws Exception { + @Override + protected Object decode(ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer, VoidEnum state) + throws Exception { - // Discard all data received if closing handshake was received before. - if (receivedClosingHandshake) { - buffer.skipBytes(actualReadableBytes()); - return null; - } + // Discard all data received if closing handshake was received before. + if (receivedClosingHandshake) { + buffer.skipBytes(actualReadableBytes()); + return null; + } - // Decode a frame otherwise. - byte type = buffer.readByte(); - if ((type & 0x80) == 0x80) { - // If the MSB on type is set, decode the frame length - return decodeBinaryFrame(type, buffer); - } else { - // Decode a 0xff terminated UTF-8 string - return decodeTextFrame(type, buffer); - } - } + // Decode a frame otherwise. + byte type = buffer.readByte(); + if ((type & 0x80) == 0x80) { + // If the MSB on type is set, decode the frame length + return decodeBinaryFrame(type, buffer); + } else { + // Decode a 0xff terminated UTF-8 string + return decodeTextFrame(type, buffer); + } + } - private WebSocketFrame decodeBinaryFrame(byte type, ChannelBuffer buffer) throws TooLongFrameException { - long frameSize = 0; - int lengthFieldSize = 0; - byte b; - do { - b = buffer.readByte(); - frameSize <<= 7; - frameSize |= b & 0x7f; - if (frameSize > maxFrameSize) { - throw new TooLongFrameException(); - } - lengthFieldSize++; - if (lengthFieldSize > 8) { - // Perhaps a malicious peer? - throw new TooLongFrameException(); - } - } while ((b & 0x80) == 0x80); + private WebSocketFrame decodeBinaryFrame(byte type, ChannelBuffer buffer) throws TooLongFrameException { + long frameSize = 0; + int lengthFieldSize = 0; + byte b; + do { + b = buffer.readByte(); + frameSize <<= 7; + frameSize |= b & 0x7f; + if (frameSize > maxFrameSize) { + throw new TooLongFrameException(); + } + lengthFieldSize++; + if (lengthFieldSize > 8) { + // Perhaps a malicious peer? + throw new TooLongFrameException(); + } + } while ((b & 0x80) == 0x80); - if (type == ((byte) 0xFF) && frameSize == 0) { - receivedClosingHandshake = true; - return new CloseWebSocketFrame(); - } + if (type == ((byte) 0xFF) && frameSize == 0) { + receivedClosingHandshake = true; + return new CloseWebSocketFrame(); + } - return new BinaryWebSocketFrame(buffer.readBytes((int) frameSize)); - } + return new BinaryWebSocketFrame(buffer.readBytes((int) frameSize)); + } - private WebSocketFrame decodeTextFrame(byte type, ChannelBuffer buffer) throws TooLongFrameException { - int ridx = buffer.readerIndex(); - int rbytes = actualReadableBytes(); - int delimPos = buffer.indexOf(ridx, ridx + rbytes, (byte) 0xFF); - if (delimPos == -1) { - // Frame delimiter (0xFF) not found - if (rbytes > maxFrameSize) { - // Frame length exceeded the maximum - throw new TooLongFrameException(); - } else { - // Wait until more data is received - return null; - } - } + private WebSocketFrame decodeTextFrame(byte type, ChannelBuffer buffer) throws TooLongFrameException { + int ridx = buffer.readerIndex(); + int rbytes = actualReadableBytes(); + int delimPos = buffer.indexOf(ridx, ridx + rbytes, (byte) 0xFF); + if (delimPos == -1) { + // Frame delimiter (0xFF) not found + if (rbytes > maxFrameSize) { + // Frame length exceeded the maximum + throw new TooLongFrameException(); + } else { + // Wait until more data is received + return null; + } + } - int frameSize = delimPos - ridx; - if (frameSize > maxFrameSize) { - throw new TooLongFrameException(); - } + int frameSize = delimPos - ridx; + if (frameSize > maxFrameSize) { + throw new TooLongFrameException(); + } - ChannelBuffer binaryData = buffer.readBytes(frameSize); - buffer.skipBytes(1); + ChannelBuffer binaryData = buffer.readBytes(frameSize); + buffer.skipBytes(1); - int ffDelimPos = binaryData.indexOf(binaryData.readerIndex(), binaryData.writerIndex(), (byte) 0xFF); - if (ffDelimPos >= 0) { - throw new IllegalArgumentException("a text frame should not contain 0xFF."); - } + int ffDelimPos = binaryData.indexOf(binaryData.readerIndex(), binaryData.writerIndex(), (byte) 0xFF); + if (ffDelimPos >= 0) { + throw new IllegalArgumentException("a text frame should not contain 0xFF."); + } - return new TextWebSocketFrame(binaryData); - } + return new TextWebSocketFrame(binaryData); + } } diff --git a/src/main/java/io/netty/handler/codec/http/websocketx/WebSocket00FrameEncoder.java b/src/main/java/io/netty/handler/codec/http/websocketx/WebSocket00FrameEncoder.java index fea2c9a8d2..ea0d36feb6 100644 --- a/src/main/java/io/netty/handler/codec/http/websocketx/WebSocket00FrameEncoder.java +++ b/src/main/java/io/netty/handler/codec/http/websocketx/WebSocket00FrameEncoder.java @@ -33,65 +33,65 @@ import io.netty.handler.codec.oneone.OneToOneEncoder; @Sharable public class WebSocket00FrameEncoder extends OneToOneEncoder { - @Override - protected Object encode(ChannelHandlerContext ctx, Channel channel, Object msg) throws Exception { - if (msg instanceof WebSocketFrame) { - WebSocketFrame frame = (WebSocketFrame) msg; - if (frame instanceof TextWebSocketFrame) { - // Text frame - ChannelBuffer data = frame.getBinaryData(); - ChannelBuffer encoded = channel.getConfig().getBufferFactory() - .getBuffer(data.order(), data.readableBytes() + 2); - encoded.writeByte((byte) 0x00); - encoded.writeBytes(data, data.readerIndex(), data.readableBytes()); - encoded.writeByte((byte) 0xFF); - return encoded; - } else if (frame instanceof CloseWebSocketFrame) { - // Close frame - ChannelBuffer data = frame.getBinaryData(); - ChannelBuffer encoded = channel.getConfig().getBufferFactory().getBuffer(data.order(), 2); - encoded.writeByte((byte) 0xFF); - encoded.writeByte((byte) 0x00); - return encoded; - } else { - // Binary frame - ChannelBuffer data = frame.getBinaryData(); - int dataLen = data.readableBytes(); - ChannelBuffer encoded = channel.getConfig().getBufferFactory().getBuffer(data.order(), dataLen + 5); + @Override + protected Object encode(ChannelHandlerContext ctx, Channel channel, Object msg) throws Exception { + if (msg instanceof WebSocketFrame) { + WebSocketFrame frame = (WebSocketFrame) msg; + if (frame instanceof TextWebSocketFrame) { + // Text frame + ChannelBuffer data = frame.getBinaryData(); + ChannelBuffer encoded = channel.getConfig().getBufferFactory() + .getBuffer(data.order(), data.readableBytes() + 2); + encoded.writeByte((byte) 0x00); + encoded.writeBytes(data, data.readerIndex(), data.readableBytes()); + encoded.writeByte((byte) 0xFF); + return encoded; + } else if (frame instanceof CloseWebSocketFrame) { + // Close frame + ChannelBuffer data = frame.getBinaryData(); + ChannelBuffer encoded = channel.getConfig().getBufferFactory().getBuffer(data.order(), 2); + encoded.writeByte((byte) 0xFF); + encoded.writeByte((byte) 0x00); + return encoded; + } else { + // Binary frame + ChannelBuffer data = frame.getBinaryData(); + int dataLen = data.readableBytes(); + ChannelBuffer encoded = channel.getConfig().getBufferFactory().getBuffer(data.order(), dataLen + 5); - // Encode type. - encoded.writeByte((byte) 0x80); + // Encode type. + encoded.writeByte((byte) 0x80); - // Encode length. - int b1 = dataLen >>> 28 & 0x7F; - int b2 = dataLen >>> 14 & 0x7F; - int b3 = dataLen >>> 7 & 0x7F; - int b4 = dataLen & 0x7F; - if (b1 == 0) { - if (b2 == 0) { - if (b3 == 0) { - encoded.writeByte(b4); - } else { - encoded.writeByte(b3 | 0x80); - encoded.writeByte(b4); - } - } else { - encoded.writeByte(b2 | 0x80); - encoded.writeByte(b3 | 0x80); - encoded.writeByte(b4); - } - } else { - encoded.writeByte(b1 | 0x80); - encoded.writeByte(b2 | 0x80); - encoded.writeByte(b3 | 0x80); - encoded.writeByte(b4); - } + // Encode length. + int b1 = dataLen >>> 28 & 0x7F; + int b2 = dataLen >>> 14 & 0x7F; + int b3 = dataLen >>> 7 & 0x7F; + int b4 = dataLen & 0x7F; + if (b1 == 0) { + if (b2 == 0) { + if (b3 == 0) { + encoded.writeByte(b4); + } else { + encoded.writeByte(b3 | 0x80); + encoded.writeByte(b4); + } + } else { + encoded.writeByte(b2 | 0x80); + encoded.writeByte(b3 | 0x80); + encoded.writeByte(b4); + } + } else { + encoded.writeByte(b1 | 0x80); + encoded.writeByte(b2 | 0x80); + encoded.writeByte(b3 | 0x80); + encoded.writeByte(b4); + } - // Encode binary data. - encoded.writeBytes(data, data.readerIndex(), dataLen); - return encoded; - } - } - return msg; - } + // Encode binary data. + encoded.writeBytes(data, data.readerIndex(), dataLen); + return encoded; + } + } + return msg; + } } diff --git a/src/main/java/io/netty/handler/codec/http/websocketx/WebSocket08FrameDecoder.java b/src/main/java/io/netty/handler/codec/http/websocketx/WebSocket08FrameDecoder.java index 07f174b5d8..42bc5f6220 100644 --- a/src/main/java/io/netty/handler/codec/http/websocketx/WebSocket08FrameDecoder.java +++ b/src/main/java/io/netty/handler/codec/http/websocketx/WebSocket08FrameDecoder.java @@ -55,325 +55,325 @@ import io.netty.logging.InternalLoggerFactory; */ public class WebSocket08FrameDecoder extends ReplayingDecoder { - private static final InternalLogger logger = InternalLoggerFactory.getInstance(WebSocket08FrameDecoder.class); + private static final InternalLogger logger = InternalLoggerFactory.getInstance(WebSocket08FrameDecoder.class); - private static final byte OPCODE_CONT = 0x0; - private static final byte OPCODE_TEXT = 0x1; - private static final byte OPCODE_BINARY = 0x2; - private static final byte OPCODE_CLOSE = 0x8; - private static final byte OPCODE_PING = 0x9; - private static final byte OPCODE_PONG = 0xA; + private static final byte OPCODE_CONT = 0x0; + private static final byte OPCODE_TEXT = 0x1; + private static final byte OPCODE_BINARY = 0x2; + private static final byte OPCODE_CLOSE = 0x8; + private static final byte OPCODE_PING = 0x9; + private static final byte OPCODE_PONG = 0xA; - private UTF8Output fragmentedFramesText = null; - private int fragmentedFramesCount = 0; + private UTF8Output fragmentedFramesText = null; + private int fragmentedFramesCount = 0; - private boolean frameFinalFlag; - private int frameRsv; - private int frameOpcode; - private long framePayloadLength; - private ChannelBuffer framePayload = null; - private int framePayloadBytesRead = 0; - private ChannelBuffer maskingKey; + private boolean frameFinalFlag; + private int frameRsv; + private int frameOpcode; + private long framePayloadLength; + private ChannelBuffer framePayload = null; + private int framePayloadBytesRead = 0; + private ChannelBuffer maskingKey; - private boolean allowExtensions = false; - private boolean maskedPayload = false; - private boolean receivedClosingHandshake = false; + private boolean allowExtensions = false; + private boolean maskedPayload = false; + private boolean receivedClosingHandshake = false; - public enum State { - FRAME_START, MASKING_KEY, PAYLOAD, CORRUPT - } + public enum State { + FRAME_START, MASKING_KEY, PAYLOAD, CORRUPT + } - /** - * Constructor - * - * @param maskedPayload - * Web socket servers must set this to true processed incoming masked payload. Client implementations - * must set this to false. - * @param allowExtensions - * Flag to allow reserved extension bits to be used or not - */ - public WebSocket08FrameDecoder(boolean maskedPayload, boolean allowExtensions) { - super(State.FRAME_START); - this.maskedPayload = maskedPayload; - this.allowExtensions = allowExtensions; - } + /** + * Constructor + * + * @param maskedPayload + * Web socket servers must set this to true processed incoming masked payload. Client implementations + * must set this to false. + * @param allowExtensions + * Flag to allow reserved extension bits to be used or not + */ + public WebSocket08FrameDecoder(boolean maskedPayload, boolean allowExtensions) { + super(State.FRAME_START); + this.maskedPayload = maskedPayload; + this.allowExtensions = allowExtensions; + } - @Override - protected Object decode(ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer, State state) - throws Exception { + @Override + protected Object decode(ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer, State state) + throws Exception { - // Discard all data received if closing handshake was received before. - if (receivedClosingHandshake) { - buffer.skipBytes(actualReadableBytes()); - return null; - } + // Discard all data received if closing handshake was received before. + if (receivedClosingHandshake) { + buffer.skipBytes(actualReadableBytes()); + return null; + } - switch (state) { - case FRAME_START: - framePayloadBytesRead = 0; - framePayloadLength = -1; - framePayload = null; + switch (state) { + case FRAME_START: + framePayloadBytesRead = 0; + framePayloadLength = -1; + framePayload = null; - // FIN, RSV, OPCODE - byte b = buffer.readByte(); - frameFinalFlag = (b & 0x80) != 0; - frameRsv = (b & 0x70) >> 4; - frameOpcode = (b & 0x0F); + // FIN, RSV, OPCODE + byte b = buffer.readByte(); + frameFinalFlag = (b & 0x80) != 0; + frameRsv = (b & 0x70) >> 4; + frameOpcode = (b & 0x0F); - if (logger.isDebugEnabled()) { - logger.debug("Decoding WebSocket Frame opCode=" + frameOpcode); - } + if (logger.isDebugEnabled()) { + logger.debug("Decoding WebSocket Frame opCode=" + frameOpcode); + } - // MASK, PAYLOAD LEN 1 - b = buffer.readByte(); - boolean frameMasked = (b & 0x80) != 0; - int framePayloadLen1 = (b & 0x7F); + // MASK, PAYLOAD LEN 1 + b = buffer.readByte(); + boolean frameMasked = (b & 0x80) != 0; + int framePayloadLen1 = (b & 0x7F); - if (frameRsv != 0 && !this.allowExtensions) { - protocolViolation(channel, "RSV != 0 and no extension negotiated, RSV:" + frameRsv); - return null; - } + if (frameRsv != 0 && !this.allowExtensions) { + protocolViolation(channel, "RSV != 0 and no extension negotiated, RSV:" + frameRsv); + return null; + } - if (this.maskedPayload && !frameMasked) { - protocolViolation(channel, "unmasked client to server frame"); - return null; - } - if (frameOpcode > 7) { // control frame (have MSB in opcode set) + if (this.maskedPayload && !frameMasked) { + protocolViolation(channel, "unmasked client to server frame"); + return null; + } + if (frameOpcode > 7) { // control frame (have MSB in opcode set) - // control frames MUST NOT be fragmented - if (!frameFinalFlag) { - protocolViolation(channel, "fragmented control frame"); - return null; - } + // control frames MUST NOT be fragmented + if (!frameFinalFlag) { + protocolViolation(channel, "fragmented control frame"); + return null; + } - // control frames MUST have payload 125 octets or less - if (framePayloadLen1 > 125) { - protocolViolation(channel, "control frame with payload length > 125 octets"); - return null; - } + // control frames MUST have payload 125 octets or less + if (framePayloadLen1 > 125) { + protocolViolation(channel, "control frame with payload length > 125 octets"); + return null; + } - // check for reserved control frame opcodes - if (!(frameOpcode == OPCODE_CLOSE || frameOpcode == OPCODE_PING || frameOpcode == OPCODE_PONG)) { - protocolViolation(channel, "control frame using reserved opcode " + frameOpcode); - return null; - } + // check for reserved control frame opcodes + if (!(frameOpcode == OPCODE_CLOSE || frameOpcode == OPCODE_PING || frameOpcode == OPCODE_PONG)) { + protocolViolation(channel, "control frame using reserved opcode " + frameOpcode); + return null; + } - // close frame : if there is a body, the first two bytes of the - // body MUST be a 2-byte unsigned integer (in network byte - // order) representing a status code - if (frameOpcode == 8 && framePayloadLen1 == 1) { - protocolViolation(channel, "received close control frame with payload len 1"); - return null; - } - } else { // data frame - // check for reserved data frame opcodes - if (!(frameOpcode == OPCODE_CONT || frameOpcode == OPCODE_TEXT || frameOpcode == OPCODE_BINARY)) { - protocolViolation(channel, "data frame using reserved opcode " + frameOpcode); - return null; - } + // close frame : if there is a body, the first two bytes of the + // body MUST be a 2-byte unsigned integer (in network byte + // order) representing a status code + if (frameOpcode == 8 && framePayloadLen1 == 1) { + protocolViolation(channel, "received close control frame with payload len 1"); + return null; + } + } else { // data frame + // check for reserved data frame opcodes + if (!(frameOpcode == OPCODE_CONT || frameOpcode == OPCODE_TEXT || frameOpcode == OPCODE_BINARY)) { + protocolViolation(channel, "data frame using reserved opcode " + frameOpcode); + return null; + } - // check opcode vs message fragmentation state 1/2 - if (fragmentedFramesCount == 0 && frameOpcode == OPCODE_CONT) { - protocolViolation(channel, "received continuation data frame outside fragmented message"); - return null; - } + // check opcode vs message fragmentation state 1/2 + if (fragmentedFramesCount == 0 && frameOpcode == OPCODE_CONT) { + protocolViolation(channel, "received continuation data frame outside fragmented message"); + return null; + } - // check opcode vs message fragmentation state 2/2 - if (fragmentedFramesCount != 0 && frameOpcode != OPCODE_CONT && frameOpcode != OPCODE_PING) { - protocolViolation(channel, "received non-continuation data frame while inside fragmented message"); - return null; - } - } + // check opcode vs message fragmentation state 2/2 + if (fragmentedFramesCount != 0 && frameOpcode != OPCODE_CONT && frameOpcode != OPCODE_PING) { + protocolViolation(channel, "received non-continuation data frame while inside fragmented message"); + return null; + } + } - // Read frame payload length - if (framePayloadLen1 == 126) { - framePayloadLength = buffer.readUnsignedShort(); - if (framePayloadLength < 126) { - protocolViolation(channel, "invalid data frame length (not using minimal length encoding)"); - return null; - } - } else if (framePayloadLen1 == 127) { - framePayloadLength = buffer.readLong(); - // TODO: check if it's bigger than 0x7FFFFFFFFFFFFFFF, Maybe - // just check if it's negative? + // Read frame payload length + if (framePayloadLen1 == 126) { + framePayloadLength = buffer.readUnsignedShort(); + if (framePayloadLength < 126) { + protocolViolation(channel, "invalid data frame length (not using minimal length encoding)"); + return null; + } + } else if (framePayloadLen1 == 127) { + framePayloadLength = buffer.readLong(); + // TODO: check if it's bigger than 0x7FFFFFFFFFFFFFFF, Maybe + // just check if it's negative? - if (framePayloadLength < 65536) { - protocolViolation(channel, "invalid data frame length (not using minimal length encoding)"); - return null; - } - } else { - framePayloadLength = framePayloadLen1; - } + if (framePayloadLength < 65536) { + protocolViolation(channel, "invalid data frame length (not using minimal length encoding)"); + return null; + } + } else { + framePayloadLength = framePayloadLen1; + } - if (logger.isDebugEnabled()) { - logger.debug("Decoding WebSocket Frame length=" + framePayloadLength); - } + if (logger.isDebugEnabled()) { + logger.debug("Decoding WebSocket Frame length=" + framePayloadLength); + } - checkpoint(State.MASKING_KEY); - case MASKING_KEY: - if (this.maskedPayload) { - maskingKey = buffer.readBytes(4); - } - checkpoint(State.PAYLOAD); - case PAYLOAD: - // Sometimes, the payload may not be delivered in 1 nice packet - // We need to accumulate the data until we have it all - int rbytes = actualReadableBytes(); - ChannelBuffer payloadBuffer = null; + checkpoint(State.MASKING_KEY); + case MASKING_KEY: + if (this.maskedPayload) { + maskingKey = buffer.readBytes(4); + } + checkpoint(State.PAYLOAD); + case PAYLOAD: + // Sometimes, the payload may not be delivered in 1 nice packet + // We need to accumulate the data until we have it all + int rbytes = actualReadableBytes(); + ChannelBuffer payloadBuffer = null; - int willHaveReadByteCount = framePayloadBytesRead + rbytes; - // logger.debug("Frame rbytes=" + rbytes + " willHaveReadByteCount=" - // + willHaveReadByteCount + " framePayloadLength=" + - // framePayloadLength); - if (willHaveReadByteCount == framePayloadLength) { - // We have all our content so proceed to process - payloadBuffer = buffer.readBytes(rbytes); - } else if (willHaveReadByteCount < framePayloadLength) { - // We don't have all our content so accumulate payload. - // Returning null means we will get called back - payloadBuffer = buffer.readBytes(rbytes); - if (framePayload == null) { - framePayload = channel.getConfig().getBufferFactory().getBuffer(toFrameLength(framePayloadLength)); - } - framePayload.writeBytes(payloadBuffer); - framePayloadBytesRead = framePayloadBytesRead + rbytes; + int willHaveReadByteCount = framePayloadBytesRead + rbytes; + // logger.debug("Frame rbytes=" + rbytes + " willHaveReadByteCount=" + // + willHaveReadByteCount + " framePayloadLength=" + + // framePayloadLength); + if (willHaveReadByteCount == framePayloadLength) { + // We have all our content so proceed to process + payloadBuffer = buffer.readBytes(rbytes); + } else if (willHaveReadByteCount < framePayloadLength) { + // We don't have all our content so accumulate payload. + // Returning null means we will get called back + payloadBuffer = buffer.readBytes(rbytes); + if (framePayload == null) { + framePayload = channel.getConfig().getBufferFactory().getBuffer(toFrameLength(framePayloadLength)); + } + framePayload.writeBytes(payloadBuffer); + framePayloadBytesRead = framePayloadBytesRead + rbytes; - // Return null to wait for more bytes to arrive - return null; - } else if (willHaveReadByteCount > framePayloadLength) { - // We have more than what we need so read up to the end of frame - // Leave the remainder in the buffer for next frame - payloadBuffer = buffer.readBytes(toFrameLength(framePayloadLength - framePayloadBytesRead)); - } + // Return null to wait for more bytes to arrive + return null; + } else if (willHaveReadByteCount > framePayloadLength) { + // We have more than what we need so read up to the end of frame + // Leave the remainder in the buffer for next frame + payloadBuffer = buffer.readBytes(toFrameLength(framePayloadLength - framePayloadBytesRead)); + } - // Now we have all the data, the next checkpoint must be the next - // frame - checkpoint(State.FRAME_START); + // Now we have all the data, the next checkpoint must be the next + // frame + checkpoint(State.FRAME_START); - // Take the data that we have in this packet - if (framePayload == null) { - framePayload = payloadBuffer; - } else { - framePayload.writeBytes(payloadBuffer); - } + // Take the data that we have in this packet + if (framePayload == null) { + framePayload = payloadBuffer; + } else { + framePayload.writeBytes(payloadBuffer); + } - // Unmask data if needed - if (this.maskedPayload) { - unmask(framePayload); - } + // Unmask data if needed + if (this.maskedPayload) { + unmask(framePayload); + } - // Processing ping/pong/close frames because they cannot be - // fragmented - if (frameOpcode == OPCODE_PING) { - return new PingWebSocketFrame(frameFinalFlag, frameRsv, framePayload); - } else if (frameOpcode == OPCODE_PONG) { - return new PongWebSocketFrame(frameFinalFlag, frameRsv, framePayload); - } else if (frameOpcode == OPCODE_CLOSE) { - this.receivedClosingHandshake = true; - return new CloseWebSocketFrame(frameFinalFlag, frameRsv); - } + // Processing ping/pong/close frames because they cannot be + // fragmented + if (frameOpcode == OPCODE_PING) { + return new PingWebSocketFrame(frameFinalFlag, frameRsv, framePayload); + } else if (frameOpcode == OPCODE_PONG) { + return new PongWebSocketFrame(frameFinalFlag, frameRsv, framePayload); + } else if (frameOpcode == OPCODE_CLOSE) { + this.receivedClosingHandshake = true; + return new CloseWebSocketFrame(frameFinalFlag, frameRsv); + } - // Processing for possible fragmented messages for text and binary - // frames - String aggregatedText = null; - if (frameFinalFlag) { - // Final frame of the sequence. Apparently ping frames are - // allowed in the middle of a fragmented message - if (frameOpcode != OPCODE_PING) { - fragmentedFramesCount = 0; + // Processing for possible fragmented messages for text and binary + // frames + String aggregatedText = null; + if (frameFinalFlag) { + // Final frame of the sequence. Apparently ping frames are + // allowed in the middle of a fragmented message + if (frameOpcode != OPCODE_PING) { + fragmentedFramesCount = 0; - // Check text for UTF8 correctness - if (frameOpcode == OPCODE_TEXT || fragmentedFramesText != null) { - // Check UTF-8 correctness for this payload - checkUTF8String(channel, framePayload.array()); + // Check text for UTF8 correctness + if (frameOpcode == OPCODE_TEXT || fragmentedFramesText != null) { + // Check UTF-8 correctness for this payload + checkUTF8String(channel, framePayload.array()); - // This does a second check to make sure UTF-8 - // correctness for entire text message - aggregatedText = fragmentedFramesText.toString(); + // This does a second check to make sure UTF-8 + // correctness for entire text message + aggregatedText = fragmentedFramesText.toString(); - fragmentedFramesText = null; - } - } - } else { - // Not final frame so we can expect more frames in the - // fragmented sequence - if (fragmentedFramesCount == 0) { - // First text or binary frame for a fragmented set - fragmentedFramesText = null; - if (frameOpcode == OPCODE_TEXT) { - checkUTF8String(channel, framePayload.array()); - } - } else { - // Subsequent frames - only check if init frame is text - if (fragmentedFramesText != null) { - checkUTF8String(channel, framePayload.array()); - } - } + fragmentedFramesText = null; + } + } + } else { + // Not final frame so we can expect more frames in the + // fragmented sequence + if (fragmentedFramesCount == 0) { + // First text or binary frame for a fragmented set + fragmentedFramesText = null; + if (frameOpcode == OPCODE_TEXT) { + checkUTF8String(channel, framePayload.array()); + } + } else { + // Subsequent frames - only check if init frame is text + if (fragmentedFramesText != null) { + checkUTF8String(channel, framePayload.array()); + } + } - // Increment counter - fragmentedFramesCount++; - } + // Increment counter + fragmentedFramesCount++; + } - // Return the frame - if (frameOpcode == OPCODE_TEXT) { - return new TextWebSocketFrame(frameFinalFlag, frameRsv, framePayload); - } else if (frameOpcode == OPCODE_BINARY) { - return new BinaryWebSocketFrame(frameFinalFlag, frameRsv, framePayload); - } else if (frameOpcode == OPCODE_CONT) { - return new ContinuationWebSocketFrame(frameFinalFlag, frameRsv, framePayload, aggregatedText); - } else { - throw new UnsupportedOperationException("Cannot decode web socket frame with opcode: " + frameOpcode); - } - case CORRUPT: - // If we don't keep reading Netty will throw an exception saying - // we can't return null if no bytes read and state not changed. - buffer.readByte(); - return null; - default: - throw new Error("Shouldn't reach here."); - } - } + // Return the frame + if (frameOpcode == OPCODE_TEXT) { + return new TextWebSocketFrame(frameFinalFlag, frameRsv, framePayload); + } else if (frameOpcode == OPCODE_BINARY) { + return new BinaryWebSocketFrame(frameFinalFlag, frameRsv, framePayload); + } else if (frameOpcode == OPCODE_CONT) { + return new ContinuationWebSocketFrame(frameFinalFlag, frameRsv, framePayload, aggregatedText); + } else { + throw new UnsupportedOperationException("Cannot decode web socket frame with opcode: " + frameOpcode); + } + case CORRUPT: + // If we don't keep reading Netty will throw an exception saying + // we can't return null if no bytes read and state not changed. + buffer.readByte(); + return null; + default: + throw new Error("Shouldn't reach here."); + } + } - private void unmask(ChannelBuffer frame) { - byte[] bytes = frame.array(); - for (int i = 0; i < bytes.length; i++) { - frame.setByte(i, frame.getByte(i) ^ maskingKey.getByte(i % 4)); - } - } + private void unmask(ChannelBuffer frame) { + byte[] bytes = frame.array(); + for (int i = 0; i < bytes.length; i++) { + frame.setByte(i, frame.getByte(i) ^ maskingKey.getByte(i % 4)); + } + } - private void protocolViolation(Channel channel, String reason) throws CorruptedFrameException { - checkpoint(State.CORRUPT); - if (channel.isConnected()) { - channel.write(ChannelBuffers.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE); - channel.close().awaitUninterruptibly(); - } - throw new CorruptedFrameException(reason); - } + private void protocolViolation(Channel channel, String reason) throws CorruptedFrameException { + checkpoint(State.CORRUPT); + if (channel.isConnected()) { + channel.write(ChannelBuffers.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE); + channel.close().awaitUninterruptibly(); + } + throw new CorruptedFrameException(reason); + } - private int toFrameLength(long l) throws TooLongFrameException { - if (l > Integer.MAX_VALUE) { - throw new TooLongFrameException("Length:" + l); - } else { - return (int) l; - } - } + private int toFrameLength(long l) throws TooLongFrameException { + if (l > Integer.MAX_VALUE) { + throw new TooLongFrameException("Length:" + l); + } else { + return (int) l; + } + } - private void checkUTF8String(Channel channel, byte[] bytes) throws CorruptedFrameException { - try { - // StringBuilder sb = new StringBuilder("UTF8 " + bytes.length + - // " bytes: "); - // for (byte b : bytes) { - // sb.append(Integer.toHexString(b)).append(" "); - // } - // logger.debug(sb.toString()); + private void checkUTF8String(Channel channel, byte[] bytes) throws CorruptedFrameException { + try { + // StringBuilder sb = new StringBuilder("UTF8 " + bytes.length + + // " bytes: "); + // for (byte b : bytes) { + // sb.append(Integer.toHexString(b)).append(" "); + // } + // logger.debug(sb.toString()); - if (fragmentedFramesText == null) { - fragmentedFramesText = new UTF8Output(bytes); - } else { - fragmentedFramesText.write(bytes); - } - } catch (UTF8Exception ex) { - protocolViolation(channel, "invalid UTF-8 bytes"); - } - } + if (fragmentedFramesText == null) { + fragmentedFramesText = new UTF8Output(bytes); + } else { + fragmentedFramesText.write(bytes); + } + } catch (UTF8Exception ex) { + protocolViolation(channel, "invalid UTF-8 bytes"); + } + } } diff --git a/src/main/java/io/netty/handler/codec/http/websocketx/WebSocket08FrameEncoder.java b/src/main/java/io/netty/handler/codec/http/websocketx/WebSocket08FrameEncoder.java index 91dad9382c..c7318cf6d4 100644 --- a/src/main/java/io/netty/handler/codec/http/websocketx/WebSocket08FrameEncoder.java +++ b/src/main/java/io/netty/handler/codec/http/websocketx/WebSocket08FrameEncoder.java @@ -57,117 +57,117 @@ import io.netty.logging.InternalLoggerFactory; */ public class WebSocket08FrameEncoder extends OneToOneEncoder { - private static final InternalLogger logger = InternalLoggerFactory.getInstance(WebSocket08FrameEncoder.class); + private static final InternalLogger logger = InternalLoggerFactory.getInstance(WebSocket08FrameEncoder.class); - private static final byte OPCODE_CONT = 0x0; - private static final byte OPCODE_TEXT = 0x1; - private static final byte OPCODE_BINARY = 0x2; - private static final byte OPCODE_CLOSE = 0x8; - private static final byte OPCODE_PING = 0x9; - private static final byte OPCODE_PONG = 0xA; + private static final byte OPCODE_CONT = 0x0; + private static final byte OPCODE_TEXT = 0x1; + private static final byte OPCODE_BINARY = 0x2; + private static final byte OPCODE_CLOSE = 0x8; + private static final byte OPCODE_PING = 0x9; + private static final byte OPCODE_PONG = 0xA; - private boolean maskPayload = false; + private boolean maskPayload = false; - /** - * Constructor - * - * @param maskPayload - * Web socket clients must set this to true to mask payload. Server implementations must set this to - * false. - */ - public WebSocket08FrameEncoder(boolean maskPayload) { - this.maskPayload = maskPayload; - } + /** + * Constructor + * + * @param maskPayload + * Web socket clients must set this to true to mask payload. Server implementations must set this to + * false. + */ + public WebSocket08FrameEncoder(boolean maskPayload) { + this.maskPayload = maskPayload; + } - @Override - protected Object encode(ChannelHandlerContext ctx, Channel channel, Object msg) throws Exception { + @Override + protected Object encode(ChannelHandlerContext ctx, Channel channel, Object msg) throws Exception { - byte[] mask = null; + byte[] mask = null; - if (msg instanceof WebSocketFrame) { - WebSocketFrame frame = (WebSocketFrame) msg; - ChannelBuffer data = frame.getBinaryData(); - if (data == null) { - data = ChannelBuffers.EMPTY_BUFFER; - } + if (msg instanceof WebSocketFrame) { + WebSocketFrame frame = (WebSocketFrame) msg; + ChannelBuffer data = frame.getBinaryData(); + if (data == null) { + data = ChannelBuffers.EMPTY_BUFFER; + } - byte opcode; - if (frame instanceof TextWebSocketFrame) { - opcode = OPCODE_TEXT; - } else if (frame instanceof PingWebSocketFrame) { - opcode = OPCODE_PING; - } else if (frame instanceof PongWebSocketFrame) { - opcode = OPCODE_PONG; - } else if (frame instanceof CloseWebSocketFrame) { - opcode = OPCODE_CLOSE; - } else if (frame instanceof BinaryWebSocketFrame) { - opcode = OPCODE_BINARY; - } else if (frame instanceof ContinuationWebSocketFrame) { - opcode = OPCODE_CONT; - } else { - throw new UnsupportedOperationException("Cannot encode frame of type: " + frame.getClass().getName()); - } + byte opcode; + if (frame instanceof TextWebSocketFrame) { + opcode = OPCODE_TEXT; + } else if (frame instanceof PingWebSocketFrame) { + opcode = OPCODE_PING; + } else if (frame instanceof PongWebSocketFrame) { + opcode = OPCODE_PONG; + } else if (frame instanceof CloseWebSocketFrame) { + opcode = OPCODE_CLOSE; + } else if (frame instanceof BinaryWebSocketFrame) { + opcode = OPCODE_BINARY; + } else if (frame instanceof ContinuationWebSocketFrame) { + opcode = OPCODE_CONT; + } else { + throw new UnsupportedOperationException("Cannot encode frame of type: " + frame.getClass().getName()); + } - int length = data.readableBytes(); + int length = data.readableBytes(); - if (logger.isDebugEnabled()) { - logger.debug("Encoding WebSocket Frame opCode=" + opcode + " length=" + length); - } + if (logger.isDebugEnabled()) { + logger.debug("Encoding WebSocket Frame opCode=" + opcode + " length=" + length); + } - int b0 = 0; - if (frame.isFinalFragment()) { - b0 |= (1 << 7); - } - b0 |= (frame.getRsv() % 8) << 4; - b0 |= opcode % 128; + int b0 = 0; + if (frame.isFinalFragment()) { + b0 |= (1 << 7); + } + b0 |= (frame.getRsv() % 8) << 4; + b0 |= opcode % 128; - ChannelBuffer header; - ChannelBuffer body; + ChannelBuffer header; + ChannelBuffer body; - if (opcode == OPCODE_PING && length > 125) { - throw new TooLongFrameException("invalid payload for PING (payload length must be <= 125, was " - + length); - } + if (opcode == OPCODE_PING && length > 125) { + throw new TooLongFrameException("invalid payload for PING (payload length must be <= 125, was " + + length); + } - int maskLength = this.maskPayload ? 4 : 0; - if (length <= 125) { - header = ChannelBuffers.buffer(2 + maskLength); - header.writeByte(b0); - byte b = (byte) (this.maskPayload ? (0x80 | (byte) length) : (byte) length); - header.writeByte(b); - } else if (length <= 0xFFFF) { - header = ChannelBuffers.buffer(4 + maskLength); - header.writeByte(b0); - header.writeByte(this.maskPayload ? (0xFE) : 126); - header.writeByte((length >>> 8) & 0xFF); - header.writeByte((length) & 0xFF); - } else { - header = ChannelBuffers.buffer(10 + maskLength); - header.writeByte(b0); - header.writeByte(this.maskPayload ? (0xFF) : 127); - header.writeLong(length); - } + int maskLength = this.maskPayload ? 4 : 0; + if (length <= 125) { + header = ChannelBuffers.buffer(2 + maskLength); + header.writeByte(b0); + byte b = (byte) (this.maskPayload ? (0x80 | (byte) length) : (byte) length); + header.writeByte(b); + } else if (length <= 0xFFFF) { + header = ChannelBuffers.buffer(4 + maskLength); + header.writeByte(b0); + header.writeByte(this.maskPayload ? (0xFE) : 126); + header.writeByte((length >>> 8) & 0xFF); + header.writeByte((length) & 0xFF); + } else { + header = ChannelBuffers.buffer(10 + maskLength); + header.writeByte(b0); + header.writeByte(this.maskPayload ? (0xFF) : 127); + header.writeLong(length); + } - // Write payload - if (this.maskPayload) { - Integer random = (int) (Math.random() * Integer.MAX_VALUE); - mask = ByteBuffer.allocate(4).putInt(random).array(); - header.writeBytes(mask); + // Write payload + if (this.maskPayload) { + Integer random = (int) (Math.random() * Integer.MAX_VALUE); + mask = ByteBuffer.allocate(4).putInt(random).array(); + header.writeBytes(mask); - body = ChannelBuffers.buffer(length); - int counter = 0; - while (data.readableBytes() > 0) { - byte byteData = data.readByte(); - body.writeByte(byteData ^ mask[+counter++ % 4]); - } - } else { - body = data; - } - return ChannelBuffers.wrappedBuffer(header, body); - } + body = ChannelBuffers.buffer(length); + int counter = 0; + while (data.readableBytes() > 0) { + byte byteData = data.readByte(); + body.writeByte(byteData ^ mask[+counter++ % 4]); + } + } else { + body = data; + } + return ChannelBuffers.wrappedBuffer(header, body); + } - // If not websocket, then just return the message - return msg; - } + // If not websocket, then just return the message + return msg; + } } \ No newline at end of file diff --git a/src/main/java/io/netty/handler/codec/http/websocketx/WebSocket13FrameDecoder.java b/src/main/java/io/netty/handler/codec/http/websocketx/WebSocket13FrameDecoder.java index 435b88fc51..1e2404a832 100644 --- a/src/main/java/io/netty/handler/codec/http/websocketx/WebSocket13FrameDecoder.java +++ b/src/main/java/io/netty/handler/codec/http/websocketx/WebSocket13FrameDecoder.java @@ -43,16 +43,16 @@ package io.netty.handler.codec.http.websocketx; */ public class WebSocket13FrameDecoder extends WebSocket08FrameDecoder { - /** - * Constructor - * - * @param maskedPayload - * Web socket servers must set this to true processed incoming masked payload. Client implementations - * must set this to false. - * @param allowExtensions - * Flag to allow reserved extension bits to be used or not - */ - public WebSocket13FrameDecoder(boolean maskedPayload, boolean allowExtensions) { - super(maskedPayload, allowExtensions); - } + /** + * Constructor + * + * @param maskedPayload + * Web socket servers must set this to true processed incoming masked payload. Client implementations + * must set this to false. + * @param allowExtensions + * Flag to allow reserved extension bits to be used or not + */ + public WebSocket13FrameDecoder(boolean maskedPayload, boolean allowExtensions) { + super(maskedPayload, allowExtensions); + } } diff --git a/src/main/java/io/netty/handler/codec/http/websocketx/WebSocket13FrameEncoder.java b/src/main/java/io/netty/handler/codec/http/websocketx/WebSocket13FrameEncoder.java index 7564eee39b..8218e95482 100644 --- a/src/main/java/io/netty/handler/codec/http/websocketx/WebSocket13FrameEncoder.java +++ b/src/main/java/io/netty/handler/codec/http/websocketx/WebSocket13FrameEncoder.java @@ -45,14 +45,14 @@ package io.netty.handler.codec.http.websocketx; */ public class WebSocket13FrameEncoder extends WebSocket08FrameEncoder { - /** - * Constructor - * - * @param maskPayload - * Web socket clients must set this to true to mask payload. Server implementations must set this to - * false. - */ - public WebSocket13FrameEncoder(boolean maskPayload) { - super(maskPayload); - } + /** + * Constructor + * + * @param maskPayload + * Web socket clients must set this to true to mask payload. Server implementations must set this to + * false. + */ + public WebSocket13FrameEncoder(boolean maskPayload) { + super(maskPayload); + } } diff --git a/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketClientHandshaker.java b/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketClientHandshaker.java index 978d2d172a..4493968db2 100644 --- a/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketClientHandshaker.java +++ b/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketClientHandshaker.java @@ -32,177 +32,177 @@ import io.netty.util.CharsetUtil; */ public abstract class WebSocketClientHandshaker { - private URI webSocketURL; + private URI webSocketURL; - private WebSocketVersion version = WebSocketVersion.UNKNOWN; + private WebSocketVersion version = WebSocketVersion.UNKNOWN; - private boolean openingHandshakeCompleted = false; + private boolean openingHandshakeCompleted = false; - private String subProtocolRequest = null; + private String subProtocolRequest = null; - private String subProtocolResponse = null; + private String subProtocolResponse = null; - protected Map customHeaders = null; + protected Map customHeaders = null; - /** - * - * @param webSocketURL - * @param version - * @param subProtocol - */ - public WebSocketClientHandshaker(URI webSocketURL, WebSocketVersion version, String subProtocol, - Map customHeaders) { - this.webSocketURL = webSocketURL; - this.version = version; - this.subProtocolRequest = subProtocol; - this.customHeaders = customHeaders; - } + /** + * + * @param webSocketURL + * @param version + * @param subProtocol + */ + public WebSocketClientHandshaker(URI webSocketURL, WebSocketVersion version, String subProtocol, + Map customHeaders) { + this.webSocketURL = webSocketURL; + this.version = version; + this.subProtocolRequest = subProtocol; + this.customHeaders = customHeaders; + } - /** - * Returns the URI to the web socket. e.g. "ws://myhost.com/path" - */ - public URI getWebSocketURL() { - return webSocketURL; - } + /** + * Returns the URI to the web socket. e.g. "ws://myhost.com/path" + */ + public URI getWebSocketURL() { + return webSocketURL; + } - protected void setWebSocketURL(URI webSocketURL) { - this.webSocketURL = webSocketURL; - } + protected void setWebSocketURL(URI webSocketURL) { + this.webSocketURL = webSocketURL; + } - /** - * Version of the web socket specification that is being used - */ - public WebSocketVersion getVersion() { - return version; - } + /** + * Version of the web socket specification that is being used + */ + public WebSocketVersion getVersion() { + return version; + } - protected void setVersion(WebSocketVersion version) { - this.version = version; - } + protected void setVersion(WebSocketVersion version) { + this.version = version; + } - /** - * Flag to indicate if the opening handshake is complete - */ - public boolean isOpeningHandshakeCompleted() { - return openingHandshakeCompleted; - } + /** + * Flag to indicate if the opening handshake is complete + */ + public boolean isOpeningHandshakeCompleted() { + return openingHandshakeCompleted; + } - protected void setOpenningHandshakeCompleted(boolean openningHandshakeCompleted) { - this.openingHandshakeCompleted = openningHandshakeCompleted; - } + protected void setOpenningHandshakeCompleted(boolean openningHandshakeCompleted) { + this.openingHandshakeCompleted = openningHandshakeCompleted; + } - /** - * Returns the sub protocol request sent to the server as specified in the constructor - */ - public String getSubProtocolRequest() { - return subProtocolRequest; - } + /** + * Returns the sub protocol request sent to the server as specified in the constructor + */ + public String getSubProtocolRequest() { + return subProtocolRequest; + } - protected void setSubProtocolRequest(String subProtocolRequest) { - this.subProtocolRequest = subProtocolRequest; - } + protected void setSubProtocolRequest(String subProtocolRequest) { + this.subProtocolRequest = subProtocolRequest; + } - /** - * Returns the sub protocol response and sent by the server. Only available after end of handshake. - */ - public String getSubProtocolResponse() { - return subProtocolResponse; - } + /** + * Returns the sub protocol response and sent by the server. Only available after end of handshake. + */ + public String getSubProtocolResponse() { + return subProtocolResponse; + } - protected void setSubProtocolResponse(String subProtocolResponse) { - this.subProtocolResponse = subProtocolResponse; - } + protected void setSubProtocolResponse(String subProtocolResponse) { + this.subProtocolResponse = subProtocolResponse; + } - /** - * Performs the opening handshake - * - * @param channel - * Channel - */ - public abstract void performOpeningHandshake(Channel channel); + /** + * Performs the opening handshake + * + * @param channel + * Channel + */ + public abstract void performOpeningHandshake(Channel channel); - /** - * Performs the closing handshake - * - * @param channel - * Channel - * @param response - * HTTP response containing the closing handshake details - */ - public abstract void performClosingHandshake(Channel channel, HttpResponse response) - throws WebSocketHandshakeException; + /** + * Performs the closing handshake + * + * @param channel + * Channel + * @param response + * HTTP response containing the closing handshake details + */ + public abstract void performClosingHandshake(Channel channel, HttpResponse response) + throws WebSocketHandshakeException; - /** - * Performs an MD5 hash - * - * @param bytes - * Data to hash - * @return Hashed data - */ - protected byte[] md5(byte[] bytes) { - try { - MessageDigest md = MessageDigest.getInstance("MD5"); - return md.digest(bytes); - } catch (NoSuchAlgorithmException e) { - throw new InternalError("MD5 not supported on this platform"); - } - } + /** + * Performs an MD5 hash + * + * @param bytes + * Data to hash + * @return Hashed data + */ + protected byte[] md5(byte[] bytes) { + try { + MessageDigest md = MessageDigest.getInstance("MD5"); + return md.digest(bytes); + } catch (NoSuchAlgorithmException e) { + throw new InternalError("MD5 not supported on this platform"); + } + } - /** - * Performs an SHA-1 hash - * - * @param bytes - * Data to hash - * @return Hashed data - */ - protected byte[] sha1(byte[] bytes) { - try { - MessageDigest md = MessageDigest.getInstance("SHA1"); - return md.digest(bytes); - } catch (NoSuchAlgorithmException e) { - throw new InternalError("SHA-1 not supported on this platform"); - } - } + /** + * Performs an SHA-1 hash + * + * @param bytes + * Data to hash + * @return Hashed data + */ + protected byte[] sha1(byte[] bytes) { + try { + MessageDigest md = MessageDigest.getInstance("SHA1"); + return md.digest(bytes); + } catch (NoSuchAlgorithmException e) { + throw new InternalError("SHA-1 not supported on this platform"); + } + } - /** - * Base 64 encoding - * - * @param bytes - * Bytes to encode - * @return encoded string - */ - protected String base64Encode(byte[] bytes) { - ChannelBuffer hashed = ChannelBuffers.wrappedBuffer(bytes); - return Base64.encode(hashed).toString(CharsetUtil.UTF_8); - } + /** + * Base 64 encoding + * + * @param bytes + * Bytes to encode + * @return encoded string + */ + protected String base64Encode(byte[] bytes) { + ChannelBuffer hashed = ChannelBuffers.wrappedBuffer(bytes); + return Base64.encode(hashed).toString(CharsetUtil.UTF_8); + } - /** - * Creates some random bytes - * - * @param size - * Number of random bytes to create - * @return random bytes - */ - protected byte[] createRandomBytes(int size) { - byte[] bytes = new byte[size]; + /** + * Creates some random bytes + * + * @param size + * Number of random bytes to create + * @return random bytes + */ + protected byte[] createRandomBytes(int size) { + byte[] bytes = new byte[size]; - for (int i = 0; i < size; i++) { - bytes[i] = (byte) createRandomNumber(0, 255); - } + for (int i = 0; i < size; i++) { + bytes[i] = (byte) createRandomNumber(0, 255); + } - return bytes; - } + return bytes; + } - /** - * Generates a random number - * - * @param min - * Minimum value - * @param max - * Maximum value - * @return Random number - */ - protected int createRandomNumber(int min, int max) { - return (int) (Math.random() * max + min); - } + /** + * Generates a random number + * + * @param min + * Minimum value + * @param max + * Maximum value + * @return Random number + */ + protected int createRandomNumber(int min, int max) { + return (int) (Math.random() * max + min); + } } diff --git a/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketClientHandshaker00.java b/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketClientHandshaker00.java index 15995d8135..2fbfbaed54 100644 --- a/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketClientHandshaker00.java +++ b/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketClientHandshaker00.java @@ -45,205 +45,205 @@ import io.netty.handler.codec.http.HttpVersion; */ public class WebSocketClientHandshaker00 extends WebSocketClientHandshaker { - private byte[] expectedChallengeResponseBytes = null; + private byte[] expectedChallengeResponseBytes = null; - /** - * Constructor specifying the destination web socket location and version to initiate - * - * @param webSocketURL - * URL for web socket communications. e.g "ws://myhost.com/mypath". Subsequent web socket frames will be - * sent to this URL. - * @param version - * Version of web socket specification to use to connect to the server - * @param subProtocol - * Sub protocol request sent to the server. - * @param customHeaders - * Map of custom headers to add to the client request - */ - public WebSocketClientHandshaker00(URI webSocketURL, WebSocketVersion version, String subProtocol, - Map customHeaders) { - super(webSocketURL, version, subProtocol, customHeaders); + /** + * Constructor specifying the destination web socket location and version to initiate + * + * @param webSocketURL + * URL for web socket communications. e.g "ws://myhost.com/mypath". Subsequent web socket frames will be + * sent to this URL. + * @param version + * Version of web socket specification to use to connect to the server + * @param subProtocol + * Sub protocol request sent to the server. + * @param customHeaders + * Map of custom headers to add to the client request + */ + public WebSocketClientHandshaker00(URI webSocketURL, WebSocketVersion version, String subProtocol, + Map customHeaders) { + super(webSocketURL, version, subProtocol, customHeaders); - } + } - /** - *

- * Sends the opening request to the server: - *

- * - *
-	 * GET /demo HTTP/1.1
-	 * Upgrade: WebSocket
-	 * Connection: Upgrade
-	 * Host: example.com
-	 * Origin: http://example.com
-	 * Sec-WebSocket-Key1: 4 @1  46546xW%0l 1 5
-	 * Sec-WebSocket-Key2: 12998 5 Y3 1  .P00
-	 * 
-	 * ^n:ds[4U
-	 * 
- * - * @param channel - * Channel into which we can write our request - */ - @Override - public void performOpeningHandshake(Channel channel) { - // Make keys - int spaces1 = createRandomNumber(1, 12); - int spaces2 = createRandomNumber(1, 12); + /** + *

+ * Sends the opening request to the server: + *

+ * + *
+     * GET /demo HTTP/1.1
+     * Upgrade: WebSocket
+     * Connection: Upgrade
+     * Host: example.com
+     * Origin: http://example.com
+     * Sec-WebSocket-Key1: 4 @1  46546xW%0l 1 5
+     * Sec-WebSocket-Key2: 12998 5 Y3 1  .P00
+     * 
+     * ^n:ds[4U
+     * 
+ * + * @param channel + * Channel into which we can write our request + */ + @Override + public void performOpeningHandshake(Channel channel) { + // Make keys + int spaces1 = createRandomNumber(1, 12); + int spaces2 = createRandomNumber(1, 12); - int max1 = Integer.MAX_VALUE / spaces1; - int max2 = Integer.MAX_VALUE / spaces2; + int max1 = Integer.MAX_VALUE / spaces1; + int max2 = Integer.MAX_VALUE / spaces2; - int number1 = createRandomNumber(0, max1); - int number2 = createRandomNumber(0, max2); + int number1 = createRandomNumber(0, max1); + int number2 = createRandomNumber(0, max2); - int product1 = number1 * spaces1; - int product2 = number2 * spaces2; + int product1 = number1 * spaces1; + int product2 = number2 * spaces2; - String key1 = Integer.toString(product1); - String key2 = Integer.toString(product2); + String key1 = Integer.toString(product1); + String key2 = Integer.toString(product2); - key1 = insertRandomCharacters(key1); - key2 = insertRandomCharacters(key2); + key1 = insertRandomCharacters(key1); + key2 = insertRandomCharacters(key2); - key1 = insertSpaces(key1, spaces1); - key2 = insertSpaces(key2, spaces2); + key1 = insertSpaces(key1, spaces1); + key2 = insertSpaces(key2, spaces2); - byte[] key3 = createRandomBytes(8); + byte[] key3 = createRandomBytes(8); - ByteBuffer buffer = ByteBuffer.allocate(4); - buffer.putInt(number1); - byte[] number1Array = buffer.array(); - buffer = ByteBuffer.allocate(4); - buffer.putInt(number2); - byte[] number2Array = buffer.array(); + ByteBuffer buffer = ByteBuffer.allocate(4); + buffer.putInt(number1); + byte[] number1Array = buffer.array(); + buffer = ByteBuffer.allocate(4); + buffer.putInt(number2); + byte[] number2Array = buffer.array(); - byte[] challenge = new byte[16]; - System.arraycopy(number1Array, 0, challenge, 0, 4); - System.arraycopy(number2Array, 0, challenge, 4, 4); - System.arraycopy(key3, 0, challenge, 8, 8); - this.expectedChallengeResponseBytes = md5(challenge); + byte[] challenge = new byte[16]; + System.arraycopy(number1Array, 0, challenge, 0, 4); + System.arraycopy(number2Array, 0, challenge, 4, 4); + System.arraycopy(key3, 0, challenge, 8, 8); + this.expectedChallengeResponseBytes = md5(challenge); - // Get path - URI wsURL = this.getWebSocketURL(); - String path = wsURL.getPath(); - if (wsURL.getQuery() != null && wsURL.getQuery().length() > 0) { - path = wsURL.getPath() + "?" + wsURL.getQuery(); - } + // Get path + URI wsURL = this.getWebSocketURL(); + String path = wsURL.getPath(); + if (wsURL.getQuery() != null && wsURL.getQuery().length() > 0) { + path = wsURL.getPath() + "?" + wsURL.getQuery(); + } - // Format request - HttpRequest request = new DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, path); - request.addHeader(Names.UPGRADE, Values.WEBSOCKET); - request.addHeader(Names.CONNECTION, Values.UPGRADE); - request.addHeader(Names.HOST, wsURL.getHost()); - request.addHeader(Names.ORIGIN, "http://" + wsURL.getHost()); - request.addHeader(Names.SEC_WEBSOCKET_KEY1, key1); - request.addHeader(Names.SEC_WEBSOCKET_KEY2, key2); - if (this.getSubProtocolRequest() != null && !this.getSubProtocolRequest().equals("")) { - request.addHeader(Names.SEC_WEBSOCKET_PROTOCOL, this.getSubProtocolRequest()); - } + // Format request + HttpRequest request = new DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, path); + request.addHeader(Names.UPGRADE, Values.WEBSOCKET); + request.addHeader(Names.CONNECTION, Values.UPGRADE); + request.addHeader(Names.HOST, wsURL.getHost()); + request.addHeader(Names.ORIGIN, "http://" + wsURL.getHost()); + request.addHeader(Names.SEC_WEBSOCKET_KEY1, key1); + request.addHeader(Names.SEC_WEBSOCKET_KEY2, key2); + if (this.getSubProtocolRequest() != null && !this.getSubProtocolRequest().equals("")) { + request.addHeader(Names.SEC_WEBSOCKET_PROTOCOL, this.getSubProtocolRequest()); + } - if (customHeaders != null) { - for (String header : customHeaders.keySet()) { - request.addHeader(header, customHeaders.get(header)); - } - } + if (customHeaders != null) { + for (String header : customHeaders.keySet()) { + request.addHeader(header, customHeaders.get(header)); + } + } - request.setContent(ChannelBuffers.copiedBuffer(key3)); + request.setContent(ChannelBuffers.copiedBuffer(key3)); - channel.write(request); + channel.write(request); - channel.getPipeline().replace(HttpRequestEncoder.class, "ws-encoder", new WebSocket00FrameEncoder()); - } + channel.getPipeline().replace(HttpRequestEncoder.class, "ws-encoder", new WebSocket00FrameEncoder()); + } - /** - *

- * Process server response: - *

- * - *
-	 * HTTP/1.1 101 WebSocket Protocol Handshake
-	 * Upgrade: WebSocket
-	 * Connection: Upgrade
-	 * Sec-WebSocket-Origin: http://example.com
-	 * Sec-WebSocket-Location: ws://example.com/demo
-	 * Sec-WebSocket-Protocol: sample
-	 * 
-	 * 8jKS'y:G*Co,Wxa-
-	 * 
- * - * @param channel - * Channel - * @param response - * HTTP response returned from the server for the request sent by beginOpeningHandshake00(). - * @throws WebSocketHandshakeException - */ - @Override - public void performClosingHandshake(Channel channel, HttpResponse response) throws WebSocketHandshakeException { - final HttpResponseStatus status = new HttpResponseStatus(101, "WebSocket Protocol Handshake"); + /** + *

+ * Process server response: + *

+ * + *
+     * HTTP/1.1 101 WebSocket Protocol Handshake
+     * Upgrade: WebSocket
+     * Connection: Upgrade
+     * Sec-WebSocket-Origin: http://example.com
+     * Sec-WebSocket-Location: ws://example.com/demo
+     * Sec-WebSocket-Protocol: sample
+     * 
+     * 8jKS'y:G*Co,Wxa-
+     * 
+ * + * @param channel + * Channel + * @param response + * HTTP response returned from the server for the request sent by beginOpeningHandshake00(). + * @throws WebSocketHandshakeException + */ + @Override + public void performClosingHandshake(Channel channel, HttpResponse response) throws WebSocketHandshakeException { + final HttpResponseStatus status = new HttpResponseStatus(101, "WebSocket Protocol Handshake"); - if (!response.getStatus().equals(status)) { - throw new WebSocketHandshakeException("Invalid handshake response status: " + response.getStatus()); - } + if (!response.getStatus().equals(status)) { + throw new WebSocketHandshakeException("Invalid handshake response status: " + response.getStatus()); + } - String upgrade = response.getHeader(Names.UPGRADE); - if (upgrade == null || !upgrade.equals(Values.WEBSOCKET)) { - throw new WebSocketHandshakeException("Invalid handshake response upgrade: " - + response.getHeader(Names.UPGRADE)); - } + String upgrade = response.getHeader(Names.UPGRADE); + if (upgrade == null || !upgrade.equals(Values.WEBSOCKET)) { + throw new WebSocketHandshakeException("Invalid handshake response upgrade: " + + response.getHeader(Names.UPGRADE)); + } - String connection = response.getHeader(Names.CONNECTION); - if (connection == null || !connection.equals(Values.UPGRADE)) { - throw new WebSocketHandshakeException("Invalid handshake response connection: " - + response.getHeader(Names.CONNECTION)); - } + String connection = response.getHeader(Names.CONNECTION); + if (connection == null || !connection.equals(Values.UPGRADE)) { + throw new WebSocketHandshakeException("Invalid handshake response connection: " + + response.getHeader(Names.CONNECTION)); + } - byte[] challenge = response.getContent().array(); - if (!Arrays.equals(challenge, expectedChallengeResponseBytes)) { - throw new WebSocketHandshakeException("Invalid challenge"); - } + byte[] challenge = response.getContent().array(); + if (!Arrays.equals(challenge, expectedChallengeResponseBytes)) { + throw new WebSocketHandshakeException("Invalid challenge"); + } - String protocol = response.getHeader(Names.SEC_WEBSOCKET_PROTOCOL); - this.setSubProtocolResponse(protocol); + String protocol = response.getHeader(Names.SEC_WEBSOCKET_PROTOCOL); + this.setSubProtocolResponse(protocol); - channel.getPipeline().replace(HttpResponseDecoder.class, "ws-decoder", new WebSocket00FrameDecoder()); + channel.getPipeline().replace(HttpResponseDecoder.class, "ws-decoder", new WebSocket00FrameDecoder()); - this.setOpenningHandshakeCompleted(true); - } + this.setOpenningHandshakeCompleted(true); + } - private String insertRandomCharacters(String key) { - int count = createRandomNumber(1, 12); + private String insertRandomCharacters(String key) { + int count = createRandomNumber(1, 12); - char[] randomChars = new char[count]; - int randCount = 0; - while (randCount < count) { - int rand = (int) (Math.random() * 0x7e + 0x21); - if (((0x21 < rand) && (rand < 0x2f)) || ((0x3a < rand) && (rand < 0x7e))) { - randomChars[randCount] = (char) rand; - randCount += 1; - } - } + char[] randomChars = new char[count]; + int randCount = 0; + while (randCount < count) { + int rand = (int) (Math.random() * 0x7e + 0x21); + if (((0x21 < rand) && (rand < 0x2f)) || ((0x3a < rand) && (rand < 0x7e))) { + randomChars[randCount] = (char) rand; + randCount += 1; + } + } - for (int i = 0; i < count; i++) { - int split = createRandomNumber(0, key.length()); - String part1 = key.substring(0, split); - String part2 = key.substring(split); - key = part1 + randomChars[i] + part2; - } + for (int i = 0; i < count; i++) { + int split = createRandomNumber(0, key.length()); + String part1 = key.substring(0, split); + String part2 = key.substring(split); + key = part1 + randomChars[i] + part2; + } - return key; - } + return key; + } - private String insertSpaces(String key, int spaces) { - for (int i = 0; i < spaces; i++) { - int split = createRandomNumber(1, key.length() - 1); - String part1 = key.substring(0, split); - String part2 = key.substring(split); - key = part1 + " " + part2; - } + private String insertSpaces(String key, int spaces) { + for (int i = 0; i < spaces; i++) { + int split = createRandomNumber(1, key.length() - 1); + String part1 = key.substring(0, split); + String part2 = key.substring(split); + key = part1 + " " + part2; + } - return key; - } + return key; + } } diff --git a/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketClientHandshaker08.java b/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketClientHandshaker08.java index e857a20ad8..703a2ca789 100644 --- a/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketClientHandshaker08.java +++ b/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketClientHandshaker08.java @@ -42,151 +42,151 @@ import io.netty.util.CharsetUtil; */ public class WebSocketClientHandshaker08 extends WebSocketClientHandshaker { - private static final InternalLogger logger = InternalLoggerFactory.getInstance(WebSocketClientHandshaker08.class); + private static final InternalLogger logger = InternalLoggerFactory.getInstance(WebSocketClientHandshaker08.class); - public static final String MAGIC_GUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; + public static final String MAGIC_GUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; - private String expectedChallengeResponseString = null; + private String expectedChallengeResponseString = null; - private static final String protocol = null; + private static final String protocol = null; - private boolean allowExtensions = false; + private boolean allowExtensions = false; - /** - * Constructor specifying the destination web socket location and version to initiate - * - * @param webSocketURL - * URL for web socket communications. e.g "ws://myhost.com/mypath". Subsequent web socket frames will be - * sent to this URL. - * @param version - * Version of web socket specification to use to connect to the server - * @param subProtocol - * Sub protocol request sent to the server. - * @param allowExtensions - * Allow extensions to be used in the reserved bits of the web socket frame - * @param customHeaders - * Map of custom headers to add to the client request - */ - public WebSocketClientHandshaker08(URI webSocketURL, WebSocketVersion version, String subProtocol, - boolean allowExtensions, Map customHeaders) { - super(webSocketURL, version, subProtocol, customHeaders); - this.allowExtensions = allowExtensions; - } + /** + * Constructor specifying the destination web socket location and version to initiate + * + * @param webSocketURL + * URL for web socket communications. e.g "ws://myhost.com/mypath". Subsequent web socket frames will be + * sent to this URL. + * @param version + * Version of web socket specification to use to connect to the server + * @param subProtocol + * Sub protocol request sent to the server. + * @param allowExtensions + * Allow extensions to be used in the reserved bits of the web socket frame + * @param customHeaders + * Map of custom headers to add to the client request + */ + public WebSocketClientHandshaker08(URI webSocketURL, WebSocketVersion version, String subProtocol, + boolean allowExtensions, Map customHeaders) { + super(webSocketURL, version, subProtocol, customHeaders); + this.allowExtensions = allowExtensions; + } - /** - * /** - *

- * Sends the opening request to the server: - *

- * - *
-	 * GET /chat HTTP/1.1
-	 * Host: server.example.com
-	 * Upgrade: websocket
-	 * Connection: Upgrade
-	 * Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
-	 * Sec-WebSocket-Origin: http://example.com
-	 * Sec-WebSocket-Protocol: chat, superchat
-	 * Sec-WebSocket-Version: 8
-	 * 
- * - * @param channel - * Channel into which we can write our request - */ - @Override - public void performOpeningHandshake(Channel channel) { - // Get path - URI wsURL = this.getWebSocketURL(); - String path = wsURL.getPath(); - if (wsURL.getQuery() != null && wsURL.getQuery().length() > 0) { - path = wsURL.getPath() + "?" + wsURL.getQuery(); - } + /** + * /** + *

+ * Sends the opening request to the server: + *

+ * + *
+     * GET /chat HTTP/1.1
+     * Host: server.example.com
+     * Upgrade: websocket
+     * Connection: Upgrade
+     * Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
+     * Sec-WebSocket-Origin: http://example.com
+     * Sec-WebSocket-Protocol: chat, superchat
+     * Sec-WebSocket-Version: 8
+     * 
+ * + * @param channel + * Channel into which we can write our request + */ + @Override + public void performOpeningHandshake(Channel channel) { + // Get path + URI wsURL = this.getWebSocketURL(); + String path = wsURL.getPath(); + if (wsURL.getQuery() != null && wsURL.getQuery().length() > 0) { + path = wsURL.getPath() + "?" + wsURL.getQuery(); + } - // Get 16 bit nonce and base 64 encode it - byte[] nonce = createRandomBytes(16); - String key = base64Encode(nonce); + // Get 16 bit nonce and base 64 encode it + byte[] nonce = createRandomBytes(16); + String key = base64Encode(nonce); - String acceptSeed = key + MAGIC_GUID; - byte[] sha1 = sha1(acceptSeed.getBytes(CharsetUtil.US_ASCII)); - this.expectedChallengeResponseString = base64Encode(sha1); + String acceptSeed = key + MAGIC_GUID; + byte[] sha1 = sha1(acceptSeed.getBytes(CharsetUtil.US_ASCII)); + this.expectedChallengeResponseString = base64Encode(sha1); - if (logger.isDebugEnabled()) { - logger.debug(String.format("WS Version 08 Client Handshake key: %s. Expected response: %s.", key, - this.expectedChallengeResponseString)); - } + if (logger.isDebugEnabled()) { + logger.debug(String.format("WS Version 08 Client Handshake key: %s. Expected response: %s.", key, + this.expectedChallengeResponseString)); + } - // Format request - HttpRequest request = new DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, path); - request.addHeader(Names.UPGRADE, Values.WEBSOCKET.toLowerCase()); - request.addHeader(Names.CONNECTION, Values.UPGRADE); - request.addHeader(Names.SEC_WEBSOCKET_KEY, key); - request.addHeader(Names.HOST, wsURL.getHost()); - request.addHeader(Names.ORIGIN, "http://" + wsURL.getHost()); - if (protocol != null && !protocol.equals("")) { - request.addHeader(Names.SEC_WEBSOCKET_PROTOCOL, protocol); - } - request.addHeader(Names.SEC_WEBSOCKET_VERSION, "8"); + // Format request + HttpRequest request = new DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, path); + request.addHeader(Names.UPGRADE, Values.WEBSOCKET.toLowerCase()); + request.addHeader(Names.CONNECTION, Values.UPGRADE); + request.addHeader(Names.SEC_WEBSOCKET_KEY, key); + request.addHeader(Names.HOST, wsURL.getHost()); + request.addHeader(Names.ORIGIN, "http://" + wsURL.getHost()); + if (protocol != null && !protocol.equals("")) { + request.addHeader(Names.SEC_WEBSOCKET_PROTOCOL, protocol); + } + request.addHeader(Names.SEC_WEBSOCKET_VERSION, "8"); - if (customHeaders != null) { - for (String header : customHeaders.keySet()) { - request.addHeader(header, customHeaders.get(header)); - } - } + if (customHeaders != null) { + for (String header : customHeaders.keySet()) { + request.addHeader(header, customHeaders.get(header)); + } + } - channel.write(request); + channel.write(request); - channel.getPipeline().replace(HttpRequestEncoder.class, "ws-encoder", new WebSocket08FrameEncoder(true)); - } + channel.getPipeline().replace(HttpRequestEncoder.class, "ws-encoder", new WebSocket08FrameEncoder(true)); + } - /** - *

- * Process server response: - *

- * - *
-	 * HTTP/1.1 101 Switching Protocols
-	 * Upgrade: websocket
-	 * Connection: Upgrade
-	 * Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
-	 * Sec-WebSocket-Protocol: chat
-	 * 
- * - * @param channel - * Channel - * @param response - * HTTP response returned from the server for the request sent by beginOpeningHandshake00(). - * @throws WebSocketHandshakeException - */ - @Override - public void performClosingHandshake(Channel channel, HttpResponse response) throws WebSocketHandshakeException { - final HttpResponseStatus status = new HttpResponseStatus(101, "Switching Protocols"); + /** + *

+ * Process server response: + *

+ * + *
+     * HTTP/1.1 101 Switching Protocols
+     * Upgrade: websocket
+     * Connection: Upgrade
+     * Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
+     * Sec-WebSocket-Protocol: chat
+     * 
+ * + * @param channel + * Channel + * @param response + * HTTP response returned from the server for the request sent by beginOpeningHandshake00(). + * @throws WebSocketHandshakeException + */ + @Override + public void performClosingHandshake(Channel channel, HttpResponse response) throws WebSocketHandshakeException { + final HttpResponseStatus status = new HttpResponseStatus(101, "Switching Protocols"); - if (!response.getStatus().equals(status)) { - throw new WebSocketHandshakeException("Invalid handshake response status: " + response.getStatus()); - } + if (!response.getStatus().equals(status)) { + throw new WebSocketHandshakeException("Invalid handshake response status: " + response.getStatus()); + } - String upgrade = response.getHeader(Names.UPGRADE); - if (upgrade == null || !upgrade.equals(Values.WEBSOCKET.toLowerCase())) { - throw new WebSocketHandshakeException("Invalid handshake response upgrade: " - + response.getHeader(Names.UPGRADE)); - } + String upgrade = response.getHeader(Names.UPGRADE); + if (upgrade == null || !upgrade.equals(Values.WEBSOCKET.toLowerCase())) { + throw new WebSocketHandshakeException("Invalid handshake response upgrade: " + + response.getHeader(Names.UPGRADE)); + } - String connection = response.getHeader(Names.CONNECTION); - if (connection == null || !connection.equals(Values.UPGRADE)) { - throw new WebSocketHandshakeException("Invalid handshake response connection: " - + response.getHeader(Names.CONNECTION)); - } + String connection = response.getHeader(Names.CONNECTION); + if (connection == null || !connection.equals(Values.UPGRADE)) { + throw new WebSocketHandshakeException("Invalid handshake response connection: " + + response.getHeader(Names.CONNECTION)); + } - String accept = response.getHeader(Names.SEC_WEBSOCKET_ACCEPT); - if (accept == null || !accept.equals(this.expectedChallengeResponseString)) { - throw new WebSocketHandshakeException(String.format("Invalid challenge. Actual: %s. Expected: %s", accept, - this.expectedChallengeResponseString)); - } + String accept = response.getHeader(Names.SEC_WEBSOCKET_ACCEPT); + if (accept == null || !accept.equals(this.expectedChallengeResponseString)) { + throw new WebSocketHandshakeException(String.format("Invalid challenge. Actual: %s. Expected: %s", accept, + this.expectedChallengeResponseString)); + } - channel.getPipeline().replace(HttpResponseDecoder.class, "ws-decoder", - new WebSocket08FrameDecoder(false, this.allowExtensions)); + channel.getPipeline().replace(HttpResponseDecoder.class, "ws-decoder", + new WebSocket08FrameDecoder(false, this.allowExtensions)); - this.setOpenningHandshakeCompleted(true); - } + this.setOpenningHandshakeCompleted(true); + } } diff --git a/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketClientHandshaker13.java b/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketClientHandshaker13.java index 1b489cfda8..491636b037 100644 --- a/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketClientHandshaker13.java +++ b/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketClientHandshaker13.java @@ -42,150 +42,150 @@ import io.netty.util.CharsetUtil; */ public class WebSocketClientHandshaker13 extends WebSocketClientHandshaker { - private static final InternalLogger logger = InternalLoggerFactory.getInstance(WebSocketClientHandshaker13.class); + private static final InternalLogger logger = InternalLoggerFactory.getInstance(WebSocketClientHandshaker13.class); - public static final String MAGIC_GUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; + public static final String MAGIC_GUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; - private String expectedChallengeResponseString = null; + private String expectedChallengeResponseString = null; - private static final String protocol = null; + private static final String protocol = null; - private boolean allowExtensions = false; + private boolean allowExtensions = false; - /** - * Constructor specifying the destination web socket location and version to initiate - * - * @param webSocketURL - * URL for web socket communications. e.g "ws://myhost.com/mypath". Subsequent web socket frames will be - * sent to this URL. - * @param version - * Version of web socket specification to use to connect to the server - * @param subProtocol - * Sub protocol request sent to the server. - * @param allowExtensions - * Allow extensions to be used in the reserved bits of the web socket frame - * @param customHeaders - * Map of custom headers to add to the client request - */ - public WebSocketClientHandshaker13(URI webSocketURL, WebSocketVersion version, String subProtocol, - boolean allowExtensions, Map customHeaders) { - super(webSocketURL, version, subProtocol, customHeaders); - this.allowExtensions = allowExtensions; - } + /** + * Constructor specifying the destination web socket location and version to initiate + * + * @param webSocketURL + * URL for web socket communications. e.g "ws://myhost.com/mypath". Subsequent web socket frames will be + * sent to this URL. + * @param version + * Version of web socket specification to use to connect to the server + * @param subProtocol + * Sub protocol request sent to the server. + * @param allowExtensions + * Allow extensions to be used in the reserved bits of the web socket frame + * @param customHeaders + * Map of custom headers to add to the client request + */ + public WebSocketClientHandshaker13(URI webSocketURL, WebSocketVersion version, String subProtocol, + boolean allowExtensions, Map customHeaders) { + super(webSocketURL, version, subProtocol, customHeaders); + this.allowExtensions = allowExtensions; + } - /** - * /** - *

- * Sends the opening request to the server: - *

- * - *
-	 * GET /chat HTTP/1.1
-	 * Host: server.example.com
-	 * Upgrade: websocket
-	 * Connection: Upgrade
-	 * Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
-	 * Sec-WebSocket-Origin: http://example.com
-	 * Sec-WebSocket-Protocol: chat, superchat
-	 * Sec-WebSocket-Version: 13
-	 * 
- * - * @param channel - * Channel into which we can write our request - */ - @Override - public void performOpeningHandshake(Channel channel) { - // Get path - URI wsURL = this.getWebSocketURL(); - String path = wsURL.getPath(); - if (wsURL.getQuery() != null && wsURL.getQuery().length() > 0) { - path = wsURL.getPath() + "?" + wsURL.getQuery(); - } + /** + * /** + *

+ * Sends the opening request to the server: + *

+ * + *
+     * GET /chat HTTP/1.1
+     * Host: server.example.com
+     * Upgrade: websocket
+     * Connection: Upgrade
+     * Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
+     * Sec-WebSocket-Origin: http://example.com
+     * Sec-WebSocket-Protocol: chat, superchat
+     * Sec-WebSocket-Version: 13
+     * 
+ * + * @param channel + * Channel into which we can write our request + */ + @Override + public void performOpeningHandshake(Channel channel) { + // Get path + URI wsURL = this.getWebSocketURL(); + String path = wsURL.getPath(); + if (wsURL.getQuery() != null && wsURL.getQuery().length() > 0) { + path = wsURL.getPath() + "?" + wsURL.getQuery(); + } - // Get 16 bit nonce and base 64 encode it - byte[] nonce = createRandomBytes(16); - String key = base64Encode(nonce); + // Get 16 bit nonce and base 64 encode it + byte[] nonce = createRandomBytes(16); + String key = base64Encode(nonce); - String acceptSeed = key + MAGIC_GUID; - byte[] sha1 = sha1(acceptSeed.getBytes(CharsetUtil.US_ASCII)); - this.expectedChallengeResponseString = base64Encode(sha1); + String acceptSeed = key + MAGIC_GUID; + byte[] sha1 = sha1(acceptSeed.getBytes(CharsetUtil.US_ASCII)); + this.expectedChallengeResponseString = base64Encode(sha1); - if (logger.isDebugEnabled()) { - logger.debug(String.format("WS Version 13 Client Handshake key: %s. Expected response: %s.", key, - this.expectedChallengeResponseString)); - } + if (logger.isDebugEnabled()) { + logger.debug(String.format("WS Version 13 Client Handshake key: %s. Expected response: %s.", key, + this.expectedChallengeResponseString)); + } - // Format request - HttpRequest request = new DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, path); - request.addHeader(Names.UPGRADE, Values.WEBSOCKET.toLowerCase()); - request.addHeader(Names.CONNECTION, Values.UPGRADE); - request.addHeader(Names.SEC_WEBSOCKET_KEY, key); - request.addHeader(Names.HOST, wsURL.getHost()); - request.addHeader(Names.ORIGIN, "http://" + wsURL.getHost()); - if (protocol != null && !protocol.equals("")) { - request.addHeader(Names.SEC_WEBSOCKET_PROTOCOL, protocol); - } - request.addHeader(Names.SEC_WEBSOCKET_VERSION, "13"); + // Format request + HttpRequest request = new DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, path); + request.addHeader(Names.UPGRADE, Values.WEBSOCKET.toLowerCase()); + request.addHeader(Names.CONNECTION, Values.UPGRADE); + request.addHeader(Names.SEC_WEBSOCKET_KEY, key); + request.addHeader(Names.HOST, wsURL.getHost()); + request.addHeader(Names.ORIGIN, "http://" + wsURL.getHost()); + if (protocol != null && !protocol.equals("")) { + request.addHeader(Names.SEC_WEBSOCKET_PROTOCOL, protocol); + } + request.addHeader(Names.SEC_WEBSOCKET_VERSION, "13"); - if (customHeaders != null) { - for (String header : customHeaders.keySet()) { - request.addHeader(header, customHeaders.get(header)); - } - } - channel.write(request); + if (customHeaders != null) { + for (String header : customHeaders.keySet()) { + request.addHeader(header, customHeaders.get(header)); + } + } + channel.write(request); - channel.getPipeline().replace(HttpRequestEncoder.class, "ws-encoder", new WebSocket13FrameEncoder(true)); - } + channel.getPipeline().replace(HttpRequestEncoder.class, "ws-encoder", new WebSocket13FrameEncoder(true)); + } - /** - *

- * Process server response: - *

- * - *
-	 * HTTP/1.1 101 Switching Protocols
-	 * Upgrade: websocket
-	 * Connection: Upgrade
-	 * Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
-	 * Sec-WebSocket-Protocol: chat
-	 * 
- * - * @param channel - * Channel - * @param response - * HTTP response returned from the server for the request sent by beginOpeningHandshake00(). - * @throws WebSocketHandshakeException - */ - @Override - public void performClosingHandshake(Channel channel, HttpResponse response) throws WebSocketHandshakeException { - final HttpResponseStatus status = new HttpResponseStatus(101, "Switching Protocols"); + /** + *

+ * Process server response: + *

+ * + *
+     * HTTP/1.1 101 Switching Protocols
+     * Upgrade: websocket
+     * Connection: Upgrade
+     * Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
+     * Sec-WebSocket-Protocol: chat
+     * 
+ * + * @param channel + * Channel + * @param response + * HTTP response returned from the server for the request sent by beginOpeningHandshake00(). + * @throws WebSocketHandshakeException + */ + @Override + public void performClosingHandshake(Channel channel, HttpResponse response) throws WebSocketHandshakeException { + final HttpResponseStatus status = new HttpResponseStatus(101, "Switching Protocols"); - if (!response.getStatus().equals(status)) { - throw new WebSocketHandshakeException("Invalid handshake response status: " + response.getStatus()); - } + if (!response.getStatus().equals(status)) { + throw new WebSocketHandshakeException("Invalid handshake response status: " + response.getStatus()); + } - String upgrade = response.getHeader(Names.UPGRADE); - if (upgrade == null || !upgrade.equals(Values.WEBSOCKET.toLowerCase())) { - throw new WebSocketHandshakeException("Invalid handshake response upgrade: " - + response.getHeader(Names.UPGRADE)); - } + String upgrade = response.getHeader(Names.UPGRADE); + if (upgrade == null || !upgrade.equals(Values.WEBSOCKET.toLowerCase())) { + throw new WebSocketHandshakeException("Invalid handshake response upgrade: " + + response.getHeader(Names.UPGRADE)); + } - String connection = response.getHeader(Names.CONNECTION); - if (connection == null || !connection.equals(Values.UPGRADE)) { - throw new WebSocketHandshakeException("Invalid handshake response connection: " - + response.getHeader(Names.CONNECTION)); - } + String connection = response.getHeader(Names.CONNECTION); + if (connection == null || !connection.equals(Values.UPGRADE)) { + throw new WebSocketHandshakeException("Invalid handshake response connection: " + + response.getHeader(Names.CONNECTION)); + } - String accept = response.getHeader(Names.SEC_WEBSOCKET_ACCEPT); - if (accept == null || !accept.equals(this.expectedChallengeResponseString)) { - throw new WebSocketHandshakeException(String.format("Invalid challenge. Actual: %s. Expected: %s", accept, - this.expectedChallengeResponseString)); - } + String accept = response.getHeader(Names.SEC_WEBSOCKET_ACCEPT); + if (accept == null || !accept.equals(this.expectedChallengeResponseString)) { + throw new WebSocketHandshakeException(String.format("Invalid challenge. Actual: %s. Expected: %s", accept, + this.expectedChallengeResponseString)); + } - channel.getPipeline().replace(HttpResponseDecoder.class, "ws-decoder", - new WebSocket13FrameDecoder(false, this.allowExtensions)); + channel.getPipeline().replace(HttpResponseDecoder.class, "ws-decoder", + new WebSocket13FrameDecoder(false, this.allowExtensions)); - this.setOpenningHandshakeCompleted(true); - } + this.setOpenningHandshakeCompleted(true); + } } diff --git a/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketClientHandshakerFactory.java b/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketClientHandshakerFactory.java index 05539bc4b0..23fdce8162 100644 --- a/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketClientHandshakerFactory.java +++ b/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketClientHandshakerFactory.java @@ -23,35 +23,35 @@ import java.util.Map; */ public class WebSocketClientHandshakerFactory { - /** - * Instances a new handshaker - * - * @param webSocketURL - * URL for web socket communications. e.g "ws://myhost.com/mypath". Subsequent web socket frames will be - * sent to this URL. - * @param version - * Version of web socket specification to use to connect to the server - * @param subProtocol - * Sub protocol request sent to the server. Null if no sub-protocol support is required. - * @param allowExtensions - * Allow extensions to be used in the reserved bits of the web socket frame - * @param customHeaders - * Custom HTTP headers to send during the handshake - * @throws WebSocketHandshakeException - */ - public WebSocketClientHandshaker newHandshaker(URI webSocketURL, WebSocketVersion version, String subProtocol, - boolean allowExtensions, Map customHeaders) throws WebSocketHandshakeException { - if (version == WebSocketVersion.V13) { - return new WebSocketClientHandshaker13(webSocketURL, version, subProtocol, allowExtensions, customHeaders); - } - if (version == WebSocketVersion.V08) { - return new WebSocketClientHandshaker08(webSocketURL, version, subProtocol, allowExtensions, customHeaders); - } - if (version == WebSocketVersion.V00) { - return new WebSocketClientHandshaker00(webSocketURL, version, subProtocol, customHeaders); - } + /** + * Instances a new handshaker + * + * @param webSocketURL + * URL for web socket communications. e.g "ws://myhost.com/mypath". Subsequent web socket frames will be + * sent to this URL. + * @param version + * Version of web socket specification to use to connect to the server + * @param subProtocol + * Sub protocol request sent to the server. Null if no sub-protocol support is required. + * @param allowExtensions + * Allow extensions to be used in the reserved bits of the web socket frame + * @param customHeaders + * Custom HTTP headers to send during the handshake + * @throws WebSocketHandshakeException + */ + public WebSocketClientHandshaker newHandshaker(URI webSocketURL, WebSocketVersion version, String subProtocol, + boolean allowExtensions, Map customHeaders) throws WebSocketHandshakeException { + if (version == WebSocketVersion.V13) { + return new WebSocketClientHandshaker13(webSocketURL, version, subProtocol, allowExtensions, customHeaders); + } + if (version == WebSocketVersion.V08) { + return new WebSocketClientHandshaker08(webSocketURL, version, subProtocol, allowExtensions, customHeaders); + } + if (version == WebSocketVersion.V00) { + return new WebSocketClientHandshaker00(webSocketURL, version, subProtocol, customHeaders); + } - throw new WebSocketHandshakeException("Protocol version " + version.toString() + " not supported."); + throw new WebSocketHandshakeException("Protocol version " + version.toString() + " not supported."); - } + } } diff --git a/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketFrame.java b/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketFrame.java index 876995ba23..2f237915bd 100644 --- a/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketFrame.java +++ b/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketFrame.java @@ -22,57 +22,57 @@ import io.netty.buffer.ChannelBuffer; */ public abstract class WebSocketFrame { - /** - * Flag to indicate if this frame is the final fragment in a message. The first fragment (frame) may also be the - * final fragment. - */ - private boolean finalFragment = true; + /** + * Flag to indicate if this frame is the final fragment in a message. The first fragment (frame) may also be the + * final fragment. + */ + private boolean finalFragment = true; - /** - * RSV1, RSV2, RSV3 used for extensions - */ - private int rsv = 0; + /** + * RSV1, RSV2, RSV3 used for extensions + */ + private int rsv = 0; - /** - * Contents of this frame - */ - private ChannelBuffer binaryData; + /** + * Contents of this frame + */ + private ChannelBuffer binaryData; - /** - * Returns binary data - */ - public ChannelBuffer getBinaryData() { - return binaryData; - } + /** + * Returns binary data + */ + public ChannelBuffer getBinaryData() { + return binaryData; + } - /** - * Sets the binary data for this frame - */ - public void setBinaryData(ChannelBuffer binaryData) { - this.binaryData = binaryData; - } + /** + * Sets the binary data for this frame + */ + public void setBinaryData(ChannelBuffer binaryData) { + this.binaryData = binaryData; + } - /** - * Flag to indicate if this frame is the final fragment in a message. The first fragment (frame) may also be the - * final fragment. - */ - public boolean isFinalFragment() { - return finalFragment; - } + /** + * Flag to indicate if this frame is the final fragment in a message. The first fragment (frame) may also be the + * final fragment. + */ + public boolean isFinalFragment() { + return finalFragment; + } - public void setFinalFragment(boolean finalFragment) { - this.finalFragment = finalFragment; - } + public void setFinalFragment(boolean finalFragment) { + this.finalFragment = finalFragment; + } - /** - * Bits used for extensions to the standard. - */ - public int getRsv() { - return rsv; - } + /** + * Bits used for extensions to the standard. + */ + public int getRsv() { + return rsv; + } - public void setRsv(int rsv) { - this.rsv = rsv; - } + public void setRsv(int rsv) { + this.rsv = rsv; + } } diff --git a/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketFrameType.java b/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketFrameType.java index 09726c15de..024373adb9 100644 --- a/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketFrameType.java +++ b/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketFrameType.java @@ -19,5 +19,5 @@ package io.netty.handler.codec.http.websocketx; * Type of web socket frames */ public enum WebSocketFrameType { - TEXT, BINARY, PING, PONG, CLOSE, CONTINUATION + TEXT, BINARY, PING, PONG, CLOSE, CONTINUATION } diff --git a/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketHandshakeException.java b/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketHandshakeException.java index f7b0425d2c..815d330fb1 100644 --- a/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketHandshakeException.java +++ b/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketHandshakeException.java @@ -20,13 +20,13 @@ package io.netty.handler.codec.http.websocketx; */ public class WebSocketHandshakeException extends Exception { - private static final long serialVersionUID = 1L; + private static final long serialVersionUID = 1L; - public WebSocketHandshakeException(String s) { - super(s); - } + public WebSocketHandshakeException(String s) { + super(s); + } - public WebSocketHandshakeException(String s, Throwable throwable) { - super(s, throwable); - } + public WebSocketHandshakeException(String s, Throwable throwable) { + super(s, throwable); + } } diff --git a/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketServerHandshaker.java b/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketServerHandshaker.java index 80d66c6038..f88b72020b 100644 --- a/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketServerHandshaker.java +++ b/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketServerHandshaker.java @@ -30,157 +30,157 @@ import io.netty.util.CharsetUtil; */ public abstract class WebSocketServerHandshaker { - private String webSocketURL; + private String webSocketURL; - private String subProtocols; + private String subProtocols; - private String[] subProtocolsArray = null; + private String[] subProtocolsArray = null; - private WebSocketVersion version = WebSocketVersion.UNKNOWN; + private WebSocketVersion version = WebSocketVersion.UNKNOWN; - /** - * Constructor specifying the destination web socket location - * - * @param webSocketURL - * URL for web socket communications. e.g "ws://myhost.com/mypath". Subsequent web socket frames will be - * sent to this URL. - * @param subProtocols - * CSV of supported protocols. Null if sub protocols not supported. - */ - public WebSocketServerHandshaker(String webSocketURL, String subProtocols) { - this.webSocketURL = webSocketURL; - this.subProtocols = subProtocols; + /** + * Constructor specifying the destination web socket location + * + * @param webSocketURL + * URL for web socket communications. e.g "ws://myhost.com/mypath". Subsequent web socket frames will be + * sent to this URL. + * @param subProtocols + * CSV of supported protocols. Null if sub protocols not supported. + */ + public WebSocketServerHandshaker(String webSocketURL, String subProtocols) { + this.webSocketURL = webSocketURL; + this.subProtocols = subProtocols; - if (this.subProtocols != null) { - this.subProtocolsArray = subProtocols.split(","); - for (int i = 0; i < this.subProtocolsArray.length; i++) { - this.subProtocolsArray[i] = this.subProtocolsArray[i].trim(); - } - } - } + if (this.subProtocols != null) { + this.subProtocolsArray = subProtocols.split(","); + for (int i = 0; i < this.subProtocolsArray.length; i++) { + this.subProtocolsArray[i] = this.subProtocolsArray[i].trim(); + } + } + } - /** - * Returns the URL of the web socket - */ - public String getWebSocketURL() { - return webSocketURL; - } + /** + * Returns the URL of the web socket + */ + public String getWebSocketURL() { + return webSocketURL; + } - public void setWebSocketURL(String webSocketURL) { - this.webSocketURL = webSocketURL; - } + public void setWebSocketURL(String webSocketURL) { + this.webSocketURL = webSocketURL; + } - /** - * Returns the CSV of supported sub protocols - */ - public String getSubProtocols() { - return subProtocols; - } + /** + * Returns the CSV of supported sub protocols + */ + public String getSubProtocols() { + return subProtocols; + } - public void setSubProtocols(String subProtocols) { - this.subProtocols = subProtocols; - } + public void setSubProtocols(String subProtocols) { + this.subProtocols = subProtocols; + } - /** - * Returns the version of the specification being supported - */ - public WebSocketVersion getVersion() { - return version; - } + /** + * Returns the version of the specification being supported + */ + public WebSocketVersion getVersion() { + return version; + } - public void setVersion(WebSocketVersion version) { - this.version = version; - } + public void setVersion(WebSocketVersion version) { + this.version = version; + } - /** - * Performs the opening handshake - * - * @param channel - * Channel - * @param req - * HTTP Request - * @throws NoSuchAlgorithmException - */ - public abstract void performOpeningHandshake(Channel channel, HttpRequest req); + /** + * Performs the opening handshake + * + * @param channel + * Channel + * @param req + * HTTP Request + * @throws NoSuchAlgorithmException + */ + public abstract void performOpeningHandshake(Channel channel, HttpRequest req); - /** - * Performs the closing handshake - * - * @param channel - * Channel - * @param frame - * Closing Frame that was received - */ - public abstract void performClosingHandshake(Channel channel, CloseWebSocketFrame frame); + /** + * Performs the closing handshake + * + * @param channel + * Channel + * @param frame + * Closing Frame that was received + */ + public abstract void performClosingHandshake(Channel channel, CloseWebSocketFrame frame); - /** - * Performs an MD5 hash - * - * @param bytes - * Data to hash - * @return Hashed data - */ - protected byte[] md5(byte[] bytes) { - try { - MessageDigest md = MessageDigest.getInstance("MD5"); - return md.digest(bytes); - } catch (NoSuchAlgorithmException e) { - throw new InternalError("MD5 not supported on this platform"); - } - } + /** + * Performs an MD5 hash + * + * @param bytes + * Data to hash + * @return Hashed data + */ + protected byte[] md5(byte[] bytes) { + try { + MessageDigest md = MessageDigest.getInstance("MD5"); + return md.digest(bytes); + } catch (NoSuchAlgorithmException e) { + throw new InternalError("MD5 not supported on this platform"); + } + } - /** - * SHA-1 hashing. Instance this we think it is not thread safe - * - * @param bytes - * byte to hash - * @return hashed - */ - protected byte[] sha1(byte[] bytes) { - try { - MessageDigest md = MessageDigest.getInstance("SHA1"); - return md.digest(bytes); - } catch (NoSuchAlgorithmException e) { - throw new InternalError("SHA-1 not supported on this platform"); - } - } + /** + * SHA-1 hashing. Instance this we think it is not thread safe + * + * @param bytes + * byte to hash + * @return hashed + */ + protected byte[] sha1(byte[] bytes) { + try { + MessageDigest md = MessageDigest.getInstance("SHA1"); + return md.digest(bytes); + } catch (NoSuchAlgorithmException e) { + throw new InternalError("SHA-1 not supported on this platform"); + } + } - /** - * Base 64 encoding - * - * @param bytes - * Bytes to encode - * @return encoded string - */ - protected String base64Encode(byte[] bytes) { - ChannelBuffer hashed = ChannelBuffers.wrappedBuffer(bytes); - return Base64.encode(hashed).toString(CharsetUtil.UTF_8); - } + /** + * Base 64 encoding + * + * @param bytes + * Bytes to encode + * @return encoded string + */ + protected String base64Encode(byte[] bytes) { + ChannelBuffer hashed = ChannelBuffers.wrappedBuffer(bytes); + return Base64.encode(hashed).toString(CharsetUtil.UTF_8); + } - /** - * Selects the first matching supported sub protocol - * - * @param requestedSubProtocol - * CSV of protocols to be supported. e.g. "chat, superchat" - * @return First matching supported sub protocol. Null if not found. - */ - protected String selectSubProtocol(String requestedSubProtocol) { - if (requestedSubProtocol == null || this.subProtocolsArray == null) { - return null; - } + /** + * Selects the first matching supported sub protocol + * + * @param requestedSubProtocol + * CSV of protocols to be supported. e.g. "chat, superchat" + * @return First matching supported sub protocol. Null if not found. + */ + protected String selectSubProtocol(String requestedSubProtocol) { + if (requestedSubProtocol == null || this.subProtocolsArray == null) { + return null; + } - String[] requesteSubProtocolsArray = requestedSubProtocol.split(","); - for (int i = 0; i < requesteSubProtocolsArray.length; i++) { - String requesteSubProtocol = requesteSubProtocolsArray[i].trim(); + String[] requesteSubProtocolsArray = requestedSubProtocol.split(","); + for (int i = 0; i < requesteSubProtocolsArray.length; i++) { + String requesteSubProtocol = requesteSubProtocolsArray[i].trim(); - for (String supportedSubProtocol : this.subProtocolsArray) { - if (requesteSubProtocol.equals(supportedSubProtocol)) { - return requesteSubProtocol; - } - } - } + for (String supportedSubProtocol : this.subProtocolsArray) { + if (requesteSubProtocol.equals(supportedSubProtocol)) { + return requesteSubProtocol; + } + } + } - // No match found - return null; - } + // No match found + return null; + } } diff --git a/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketServerHandshaker00.java b/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketServerHandshaker00.java index 5bdd2c11ec..470736d17a 100644 --- a/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketServerHandshaker00.java +++ b/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketServerHandshaker00.java @@ -58,141 +58,141 @@ import io.netty.logging.InternalLoggerFactory; */ public class WebSocketServerHandshaker00 extends WebSocketServerHandshaker { - private static final InternalLogger logger = InternalLoggerFactory.getInstance(WebSocketServerHandshaker00.class); + private static final InternalLogger logger = InternalLoggerFactory.getInstance(WebSocketServerHandshaker00.class); - /** - * Constructor specifying the destination web socket location - * - * @param webSocketURL - * URL for web socket communications. e.g "ws://myhost.com/mypath". Subsequent web socket frames will be - * sent to this URL. - * @param subProtocols - * CSV of supported protocols - */ - public WebSocketServerHandshaker00(String webSocketURL, String subProtocols) { - super(webSocketURL, subProtocols); - } + /** + * Constructor specifying the destination web socket location + * + * @param webSocketURL + * URL for web socket communications. e.g "ws://myhost.com/mypath". Subsequent web socket frames will be + * sent to this URL. + * @param subProtocols + * CSV of supported protocols + */ + public WebSocketServerHandshaker00(String webSocketURL, String subProtocols) { + super(webSocketURL, subProtocols); + } - /** - *

- * Handle the web socket handshake for the web socket specification HyBi version 0 and lower. This standard - * is really a rehash of hixie-76 and - * hixie-75. - *

- * - *

- * Browser request to the server: - *

- * - *
-	 * GET /demo HTTP/1.1
-	 * Upgrade: WebSocket
-	 * Connection: Upgrade
-	 * Host: example.com
-	 * Origin: http://example.com
-	 * Sec-WebSocket-Key1: 4 @1  46546xW%0l 1 5
-	 * Sec-WebSocket-Key2: 12998 5 Y3 1  .P00
-	 * 
-	 * ^n:ds[4U
-	 * 
- * - *

- * Server response: - *

- * - *
-	 * HTTP/1.1 101 WebSocket Protocol Handshake
-	 * Upgrade: WebSocket
-	 * Connection: Upgrade
-	 * Sec-WebSocket-Origin: http://example.com
-	 * Sec-WebSocket-Location: ws://example.com/demo
-	 * Sec-WebSocket-Protocol: sample
-	 * 
-	 * 8jKS'y:G*Co,Wxa-
-	 * 
- * - * @param channel - * Channel - * @param req - * HTTP request - * @throws NoSuchAlgorithmException - */ - @Override - public void performOpeningHandshake(Channel channel, HttpRequest req) { + /** + *

+ * Handle the web socket handshake for the web socket specification HyBi version 0 and lower. This standard + * is really a rehash of hixie-76 and + * hixie-75. + *

+ * + *

+ * Browser request to the server: + *

+ * + *
+     * GET /demo HTTP/1.1
+     * Upgrade: WebSocket
+     * Connection: Upgrade
+     * Host: example.com
+     * Origin: http://example.com
+     * Sec-WebSocket-Key1: 4 @1  46546xW%0l 1 5
+     * Sec-WebSocket-Key2: 12998 5 Y3 1  .P00
+     * 
+     * ^n:ds[4U
+     * 
+ * + *

+ * Server response: + *

+ * + *
+     * HTTP/1.1 101 WebSocket Protocol Handshake
+     * Upgrade: WebSocket
+     * Connection: Upgrade
+     * Sec-WebSocket-Origin: http://example.com
+     * Sec-WebSocket-Location: ws://example.com/demo
+     * Sec-WebSocket-Protocol: sample
+     * 
+     * 8jKS'y:G*Co,Wxa-
+     * 
+ * + * @param channel + * Channel + * @param req + * HTTP request + * @throws NoSuchAlgorithmException + */ + @Override + public void performOpeningHandshake(Channel channel, HttpRequest req) { - if (logger.isDebugEnabled()) { - logger.debug(String.format("Channel %s WS Version 00 server handshake", channel.getId())); - } - this.setVersion(WebSocketVersion.V00); + if (logger.isDebugEnabled()) { + logger.debug(String.format("Channel %s WS Version 00 server handshake", channel.getId())); + } + this.setVersion(WebSocketVersion.V00); - // Serve the WebSocket handshake request. - if (!Values.UPGRADE.equalsIgnoreCase(req.getHeader(CONNECTION)) - || !WEBSOCKET.equalsIgnoreCase(req.getHeader(Names.UPGRADE))) { - return; - } + // Serve the WebSocket handshake request. + if (!Values.UPGRADE.equalsIgnoreCase(req.getHeader(CONNECTION)) + || !WEBSOCKET.equalsIgnoreCase(req.getHeader(Names.UPGRADE))) { + return; + } - // Hixie 75 does not contain these headers while Hixie 76 does - boolean isHixie76 = req.containsHeader(SEC_WEBSOCKET_KEY1) && req.containsHeader(SEC_WEBSOCKET_KEY2); + // Hixie 75 does not contain these headers while Hixie 76 does + boolean isHixie76 = req.containsHeader(SEC_WEBSOCKET_KEY1) && req.containsHeader(SEC_WEBSOCKET_KEY2); - // Create the WebSocket handshake response. - HttpResponse res = new DefaultHttpResponse(HTTP_1_1, new HttpResponseStatus(101, - isHixie76 ? "WebSocket Protocol Handshake" : "Web Socket Protocol Handshake")); - res.addHeader(Names.UPGRADE, WEBSOCKET); - res.addHeader(CONNECTION, Values.UPGRADE); + // Create the WebSocket handshake response. + HttpResponse res = new DefaultHttpResponse(HTTP_1_1, new HttpResponseStatus(101, + isHixie76 ? "WebSocket Protocol Handshake" : "Web Socket Protocol Handshake")); + res.addHeader(Names.UPGRADE, WEBSOCKET); + res.addHeader(CONNECTION, Values.UPGRADE); - // Fill in the headers and contents depending on handshake method. - if (isHixie76) { - // New handshake method with a challenge: - res.addHeader(SEC_WEBSOCKET_ORIGIN, req.getHeader(ORIGIN)); - res.addHeader(SEC_WEBSOCKET_LOCATION, this.getWebSocketURL()); - String protocol = req.getHeader(SEC_WEBSOCKET_PROTOCOL); - if (protocol != null) { - res.addHeader(SEC_WEBSOCKET_PROTOCOL, selectSubProtocol(protocol)); - } + // Fill in the headers and contents depending on handshake method. + if (isHixie76) { + // New handshake method with a challenge: + res.addHeader(SEC_WEBSOCKET_ORIGIN, req.getHeader(ORIGIN)); + res.addHeader(SEC_WEBSOCKET_LOCATION, this.getWebSocketURL()); + String protocol = req.getHeader(SEC_WEBSOCKET_PROTOCOL); + if (protocol != null) { + res.addHeader(SEC_WEBSOCKET_PROTOCOL, selectSubProtocol(protocol)); + } - // Calculate the answer of the challenge. - String key1 = req.getHeader(SEC_WEBSOCKET_KEY1); - String key2 = req.getHeader(SEC_WEBSOCKET_KEY2); - int a = (int) (Long.parseLong(key1.replaceAll("[^0-9]", "")) / key1.replaceAll("[^ ]", "").length()); - int b = (int) (Long.parseLong(key2.replaceAll("[^0-9]", "")) / key2.replaceAll("[^ ]", "").length()); - long c = req.getContent().readLong(); - ChannelBuffer input = ChannelBuffers.buffer(16); - input.writeInt(a); - input.writeInt(b); - input.writeLong(c); - ChannelBuffer output = ChannelBuffers.wrappedBuffer(this.md5(input.array())); - res.setContent(output); - } else { - // Old Hixie 75 handshake method with no challenge: - res.addHeader(WEBSOCKET_ORIGIN, req.getHeader(ORIGIN)); - res.addHeader(WEBSOCKET_LOCATION, this.getWebSocketURL()); - String protocol = req.getHeader(WEBSOCKET_PROTOCOL); - if (protocol != null) { - res.addHeader(WEBSOCKET_PROTOCOL, selectSubProtocol(protocol)); - } - } + // Calculate the answer of the challenge. + String key1 = req.getHeader(SEC_WEBSOCKET_KEY1); + String key2 = req.getHeader(SEC_WEBSOCKET_KEY2); + int a = (int) (Long.parseLong(key1.replaceAll("[^0-9]", "")) / key1.replaceAll("[^ ]", "").length()); + int b = (int) (Long.parseLong(key2.replaceAll("[^0-9]", "")) / key2.replaceAll("[^ ]", "").length()); + long c = req.getContent().readLong(); + ChannelBuffer input = ChannelBuffers.buffer(16); + input.writeInt(a); + input.writeInt(b); + input.writeLong(c); + ChannelBuffer output = ChannelBuffers.wrappedBuffer(this.md5(input.array())); + res.setContent(output); + } else { + // Old Hixie 75 handshake method with no challenge: + res.addHeader(WEBSOCKET_ORIGIN, req.getHeader(ORIGIN)); + res.addHeader(WEBSOCKET_LOCATION, this.getWebSocketURL()); + String protocol = req.getHeader(WEBSOCKET_PROTOCOL); + if (protocol != null) { + res.addHeader(WEBSOCKET_PROTOCOL, selectSubProtocol(protocol)); + } + } - // Upgrade the connection and send the handshake response. - ChannelPipeline p = channel.getPipeline(); - p.remove(HttpChunkAggregator.class); - p.replace(HttpRequestDecoder.class, "wsdecoder", new WebSocket00FrameDecoder()); + // Upgrade the connection and send the handshake response. + ChannelPipeline p = channel.getPipeline(); + p.remove(HttpChunkAggregator.class); + p.replace(HttpRequestDecoder.class, "wsdecoder", new WebSocket00FrameDecoder()); - channel.write(res); + channel.write(res); - p.replace(HttpResponseEncoder.class, "wsencoder", new WebSocket00FrameEncoder()); - } + p.replace(HttpResponseEncoder.class, "wsencoder", new WebSocket00FrameEncoder()); + } - /** - * Echo back the closing frame - * - * @param channel - * Channel - * @param frame - * Web Socket frame that was received - */ - @Override - public void performClosingHandshake(Channel channel, CloseWebSocketFrame frame) { - channel.write(frame); - } + /** + * Echo back the closing frame + * + * @param channel + * Channel + * @param frame + * Web Socket frame that was received + */ + @Override + public void performClosingHandshake(Channel channel, CloseWebSocketFrame frame) { + channel.write(frame); + } } diff --git a/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketServerHandshaker08.java b/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketServerHandshaker08.java index 196231d817..e26c4812c4 100644 --- a/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketServerHandshaker08.java +++ b/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketServerHandshaker08.java @@ -45,122 +45,122 @@ import io.netty.util.CharsetUtil; */ public class WebSocketServerHandshaker08 extends WebSocketServerHandshaker { - private static final InternalLogger logger = InternalLoggerFactory.getInstance(WebSocketServerHandshaker08.class); + private static final InternalLogger logger = InternalLoggerFactory.getInstance(WebSocketServerHandshaker08.class); - public static final String WEBSOCKET_08_ACCEPT_GUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; + public static final String WEBSOCKET_08_ACCEPT_GUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; - private boolean allowExtensions = false; + private boolean allowExtensions = false; - /** - * Constructor specifying the destination web socket location - * - * @param webSocketURL - * URL for web socket communications. e.g "ws://myhost.com/mypath". Subsequent web socket frames will be - * sent to this URL. - * @param subProtocols - * CSV of supported protocols - * @param allowExtensions - * Allow extensions to be used in the reserved bits of the web socket frame - */ - public WebSocketServerHandshaker08(String webSocketURL, String subProtocols, boolean allowExtensions) { - super(webSocketURL, subProtocols); - this.allowExtensions = allowExtensions; - } + /** + * Constructor specifying the destination web socket location + * + * @param webSocketURL + * URL for web socket communications. e.g "ws://myhost.com/mypath". Subsequent web socket frames will be + * sent to this URL. + * @param subProtocols + * CSV of supported protocols + * @param allowExtensions + * Allow extensions to be used in the reserved bits of the web socket frame + */ + public WebSocketServerHandshaker08(String webSocketURL, String subProtocols, boolean allowExtensions) { + super(webSocketURL, subProtocols); + this.allowExtensions = allowExtensions; + } - /** - *

- * Handle the web socket handshake for the web socket specification HyBi version 8 to 10. Version 8, 9 and - * 10 share the same wire protocol. - *

- * - *

- * Browser request to the server: - *

- * - *
-	 * GET /chat HTTP/1.1
-	 * Host: server.example.com
-	 * Upgrade: websocket
-	 * Connection: Upgrade
-	 * Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
-	 * Sec-WebSocket-Origin: http://example.com
-	 * Sec-WebSocket-Protocol: chat, superchat
-	 * Sec-WebSocket-Version: 8
-	 * 
- * - *

- * Server response: - *

- * - *
-	 * HTTP/1.1 101 Switching Protocols
-	 * Upgrade: websocket
-	 * Connection: Upgrade
-	 * Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
-	 * Sec-WebSocket-Protocol: chat
-	 * 
- * - * @param channel - * Channel - * @param req - * HTTP request - * @throws NoSuchAlgorithmException - */ - @Override - public void performOpeningHandshake(Channel channel, HttpRequest req) { + /** + *

+ * Handle the web socket handshake for the web socket specification HyBi version 8 to 10. Version 8, 9 and + * 10 share the same wire protocol. + *

+ * + *

+ * Browser request to the server: + *

+ * + *
+     * GET /chat HTTP/1.1
+     * Host: server.example.com
+     * Upgrade: websocket
+     * Connection: Upgrade
+     * Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
+     * Sec-WebSocket-Origin: http://example.com
+     * Sec-WebSocket-Protocol: chat, superchat
+     * Sec-WebSocket-Version: 8
+     * 
+ * + *

+ * Server response: + *

+ * + *
+     * HTTP/1.1 101 Switching Protocols
+     * Upgrade: websocket
+     * Connection: Upgrade
+     * Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
+     * Sec-WebSocket-Protocol: chat
+     * 
+ * + * @param channel + * Channel + * @param req + * HTTP request + * @throws NoSuchAlgorithmException + */ + @Override + public void performOpeningHandshake(Channel channel, HttpRequest req) { - if (logger.isDebugEnabled()) { - logger.debug(String.format("Channel %s WS Version 8 server handshake", channel.getId())); - } + if (logger.isDebugEnabled()) { + logger.debug(String.format("Channel %s WS Version 8 server handshake", channel.getId())); + } - HttpResponse res = new DefaultHttpResponse(HTTP_1_1, new HttpResponseStatus(101, "Switching Protocols")); - this.setVersion(WebSocketVersion.V08); + HttpResponse res = new DefaultHttpResponse(HTTP_1_1, new HttpResponseStatus(101, "Switching Protocols")); + this.setVersion(WebSocketVersion.V08); - String key = req.getHeader(Names.SEC_WEBSOCKET_KEY); - if (key == null) { - res.setStatus(HttpResponseStatus.BAD_REQUEST); - return; - } - String acceptSeed = key + WEBSOCKET_08_ACCEPT_GUID; - byte[] sha1 = sha1(acceptSeed.getBytes(CharsetUtil.US_ASCII)); - String accept = base64Encode(sha1); + String key = req.getHeader(Names.SEC_WEBSOCKET_KEY); + if (key == null) { + res.setStatus(HttpResponseStatus.BAD_REQUEST); + return; + } + String acceptSeed = key + WEBSOCKET_08_ACCEPT_GUID; + byte[] sha1 = sha1(acceptSeed.getBytes(CharsetUtil.US_ASCII)); + String accept = base64Encode(sha1); - if (logger.isDebugEnabled()) { - logger.debug(String.format("WS Version 8 Server Handshake key: %s. Response: %s.", key, accept)); - } + if (logger.isDebugEnabled()) { + logger.debug(String.format("WS Version 8 Server Handshake key: %s. Response: %s.", key, accept)); + } - res.setStatus(new HttpResponseStatus(101, "Switching Protocols")); - 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, this.selectSubProtocol(protocol)); - } + res.setStatus(new HttpResponseStatus(101, "Switching Protocols")); + 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, this.selectSubProtocol(protocol)); + } - channel.write(res); + channel.write(res); - // Upgrade the connection and send the handshake response. - ChannelPipeline p = channel.getPipeline(); - p.remove(HttpChunkAggregator.class); - p.replace(HttpRequestDecoder.class, "wsdecoder", new WebSocket08FrameDecoder(true, this.allowExtensions)); - p.replace(HttpResponseEncoder.class, "wsencoder", new WebSocket08FrameEncoder(false)); + // Upgrade the connection and send the handshake response. + ChannelPipeline p = channel.getPipeline(); + p.remove(HttpChunkAggregator.class); + p.replace(HttpRequestDecoder.class, "wsdecoder", new WebSocket08FrameDecoder(true, this.allowExtensions)); + p.replace(HttpResponseEncoder.class, "wsencoder", new WebSocket08FrameEncoder(false)); - } + } - /** - * Echo back the closing frame and close the connection - * - * @param channel - * Channel - * @param frame - * Web Socket frame that was received - */ - @Override - public void performClosingHandshake(Channel channel, CloseWebSocketFrame frame) { - ChannelFuture f = channel.write(frame); - f.addListener(ChannelFutureListener.CLOSE); - } + /** + * Echo back the closing frame and close the connection + * + * @param channel + * Channel + * @param frame + * Web Socket frame that was received + */ + @Override + public void performClosingHandshake(Channel channel, CloseWebSocketFrame frame) { + ChannelFuture f = channel.write(frame); + f.addListener(ChannelFutureListener.CLOSE); + } } diff --git a/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketServerHandshaker13.java b/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketServerHandshaker13.java index 966d4d2934..ea470a3691 100644 --- a/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketServerHandshaker13.java +++ b/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketServerHandshaker13.java @@ -46,122 +46,122 @@ import io.netty.util.CharsetUtil; */ public class WebSocketServerHandshaker13 extends WebSocketServerHandshaker { - private static final InternalLogger logger = InternalLoggerFactory.getInstance(WebSocketServerHandshaker13.class); + private static final InternalLogger logger = InternalLoggerFactory.getInstance(WebSocketServerHandshaker13.class); - public static final String WEBSOCKET_17_ACCEPT_GUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; + public static final String WEBSOCKET_13_ACCEPT_GUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; - private boolean allowExtensions = false; + private boolean allowExtensions = false; - /** - * Constructor specifying the destination web socket location - * - * @param webSocketURL - * URL for web socket communications. e.g "ws://myhost.com/mypath". Subsequent web socket frames will be - * sent to this URL. - * @param subProtocols - * CSV of supported protocols - * @param allowExtensions - * Allow extensions to be used in the reserved bits of the web socket frame - */ - public WebSocketServerHandshaker13(String webSocketURL, String subProtocols, boolean allowExtensions) { - super(webSocketURL, subProtocols); - this.allowExtensions = allowExtensions; - } + /** + * Constructor specifying the destination web socket location + * + * @param webSocketURL + * URL for web socket communications. e.g "ws://myhost.com/mypath". Subsequent web socket frames will be + * sent to this URL. + * @param subProtocols + * CSV of supported protocols + * @param allowExtensions + * Allow extensions to be used in the reserved bits of the web socket frame + */ + public WebSocketServerHandshaker13(String webSocketURL, String subProtocols, boolean allowExtensions) { + super(webSocketURL, subProtocols); + this.allowExtensions = allowExtensions; + } - /** - *

- * Handle the web socket handshake for the web socket specification HyBi versions 13-17. Versions 13-17 - * share the same wire protocol. - *

- * - *

- * Browser request to the server: - *

- * - *
-	 * GET /chat HTTP/1.1
-	 * Host: server.example.com
-	 * Upgrade: websocket
-	 * Connection: Upgrade
-	 * Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
-	 * Sec-WebSocket-Origin: http://example.com
-	 * Sec-WebSocket-Protocol: chat, superchat
-	 * Sec-WebSocket-Version: 13
-	 * 
- * - *

- * Server response: - *

- * - *
-	 * HTTP/1.1 101 Switching Protocols
-	 * Upgrade: websocket
-	 * Connection: Upgrade
-	 * Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
-	 * Sec-WebSocket-Protocol: chat
-	 * 
- * - * @param channel - * Channel - * @param req - * HTTP request - * @throws NoSuchAlgorithmException - */ - @Override - public void performOpeningHandshake(Channel channel, HttpRequest req) { + /** + *

+ * Handle the web socket handshake for the web socket specification HyBi versions 13-17. Versions 13-17 + * share the same wire protocol. + *

+ * + *

+ * Browser request to the server: + *

+ * + *
+     * GET /chat HTTP/1.1
+     * Host: server.example.com
+     * Upgrade: websocket
+     * Connection: Upgrade
+     * Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
+     * Sec-WebSocket-Origin: http://example.com
+     * Sec-WebSocket-Protocol: chat, superchat
+     * Sec-WebSocket-Version: 13
+     * 
+ * + *

+ * Server response: + *

+ * + *
+     * HTTP/1.1 101 Switching Protocols
+     * Upgrade: websocket
+     * Connection: Upgrade
+     * Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
+     * Sec-WebSocket-Protocol: chat
+     * 
+ * + * @param channel + * Channel + * @param req + * HTTP request + * @throws NoSuchAlgorithmException + */ + @Override + public void performOpeningHandshake(Channel channel, HttpRequest req) { - if (logger.isDebugEnabled()) { - logger.debug(String.format("Channel %s WS Version 13 server handshake", channel.getId())); - } + if (logger.isDebugEnabled()) { + logger.debug(String.format("Channel %s WS Version 13 server handshake", channel.getId())); + } - HttpResponse res = new DefaultHttpResponse(HTTP_1_1, new HttpResponseStatus(101, "Switching Protocols")); - this.setVersion(WebSocketVersion.V13); + HttpResponse res = new DefaultHttpResponse(HTTP_1_1, new HttpResponseStatus(101, "Switching Protocols")); + this.setVersion(WebSocketVersion.V13); - String key = req.getHeader(Names.SEC_WEBSOCKET_KEY); - if (key == null) { - res.setStatus(HttpResponseStatus.BAD_REQUEST); - return; - } - String acceptSeed = key + WEBSOCKET_17_ACCEPT_GUID; - byte[] sha1 = sha1(acceptSeed.getBytes(CharsetUtil.US_ASCII)); - String accept = base64Encode(sha1); + String key = req.getHeader(Names.SEC_WEBSOCKET_KEY); + if (key == null) { + res.setStatus(HttpResponseStatus.BAD_REQUEST); + return; + } + String acceptSeed = key + WEBSOCKET_13_ACCEPT_GUID; + byte[] sha1 = sha1(acceptSeed.getBytes(CharsetUtil.US_ASCII)); + String accept = base64Encode(sha1); - if (logger.isDebugEnabled()) { - logger.debug(String.format("WS Version 13 Server Handshake key: %s. Response: %s.", key, accept)); - } + if (logger.isDebugEnabled()) { + logger.debug(String.format("WS Version 13 Server Handshake key: %s. Response: %s.", key, accept)); + } - res.setStatus(new HttpResponseStatus(101, "Switching Protocols")); - 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, this.selectSubProtocol(protocol)); - } + res.setStatus(new HttpResponseStatus(101, "Switching Protocols")); + 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, this.selectSubProtocol(protocol)); + } - channel.write(res); + channel.write(res); - // Upgrade the connection and send the handshake response. - ChannelPipeline p = channel.getPipeline(); - p.remove(HttpChunkAggregator.class); - p.replace(HttpRequestDecoder.class, "wsdecoder", new WebSocket13FrameDecoder(true, this.allowExtensions)); - p.replace(HttpResponseEncoder.class, "wsencoder", new WebSocket13FrameEncoder(false)); + // Upgrade the connection and send the handshake response. + ChannelPipeline p = channel.getPipeline(); + p.remove(HttpChunkAggregator.class); + p.replace(HttpRequestDecoder.class, "wsdecoder", new WebSocket13FrameDecoder(true, this.allowExtensions)); + p.replace(HttpResponseEncoder.class, "wsencoder", new WebSocket13FrameEncoder(false)); - } + } - /** - * Echo back the closing frame and close the connection - * - * @param channel - * Channel - * @param frame - * Web Socket frame that was received - */ - @Override - public void performClosingHandshake(Channel channel, CloseWebSocketFrame frame) { - ChannelFuture f = channel.write(frame); - f.addListener(ChannelFutureListener.CLOSE); - } + /** + * Echo back the closing frame and close the connection + * + * @param channel + * Channel + * @param frame + * Web Socket frame that was received + */ + @Override + public void performClosingHandshake(Channel channel, CloseWebSocketFrame frame) { + ChannelFuture f = channel.write(frame); + f.addListener(ChannelFutureListener.CLOSE); + } } diff --git a/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketServerHandshakerFactory.java b/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketServerHandshakerFactory.java index 2493cdf435..7dc15f72dd 100644 --- a/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketServerHandshakerFactory.java +++ b/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketServerHandshakerFactory.java @@ -24,70 +24,70 @@ import io.netty.handler.codec.http.HttpVersion; import io.netty.handler.codec.http.HttpHeaders.Names; /** - * Instances the appropriate handshake class to use for clients + * Instances the appropriate handshake class to use for servers */ public class WebSocketServerHandshakerFactory { - private final String webSocketURL; + private final String webSocketURL; - private final String subProtocols; + private final String subProtocols; - private boolean allowExtensions = false; + private boolean allowExtensions = false; - /** - * Constructor specifying the destination web socket location - * - * @param webSocketURL - * URL for web socket communications. e.g "ws://myhost.com/mypath". Subsequent web socket frames will be - * sent to this URL. - * @param subProtocols - * CSV of supported protocols. Null if sub protocols not supported. - * @param allowExtensions - * Allow extensions to be used in the reserved bits of the web socket frame - */ - public WebSocketServerHandshakerFactory(String webSocketURL, String subProtocols, boolean allowExtensions) { - this.webSocketURL = webSocketURL; - this.subProtocols = subProtocols; - this.allowExtensions = allowExtensions; - } + /** + * Constructor specifying the destination web socket location + * + * @param webSocketURL + * URL for web socket communications. e.g "ws://myhost.com/mypath". Subsequent web socket frames will be + * sent to this URL. + * @param subProtocols + * CSV of supported protocols. Null if sub protocols not supported. + * @param allowExtensions + * Allow extensions to be used in the reserved bits of the web socket frame + */ + public WebSocketServerHandshakerFactory(String webSocketURL, String subProtocols, boolean allowExtensions) { + this.webSocketURL = webSocketURL; + this.subProtocols = subProtocols; + this.allowExtensions = allowExtensions; + } - /** - * Instances a new handshaker - * - * @return A new WebSocketServerHandshaker for the requested web socket version. Null if web socket version is not - * supported. - */ - public WebSocketServerHandshaker newHandshaker(HttpRequest req) { + /** + * Instances a new handshaker + * + * @return A new WebSocketServerHandshaker for the requested web socket version. Null if web socket version is not + * supported. + */ + public WebSocketServerHandshaker newHandshaker(HttpRequest req) { - String version = req.getHeader(Names.SEC_WEBSOCKET_VERSION); - if (version != null) { - if (version.equals(WebSocketVersion.V13.toHttpHeaderValue())) { - // Version 13 of the wire protocol - RFC 6455 (version 17 of the draft hybi specification). - return new WebSocketServerHandshaker13(webSocketURL, subProtocols, this.allowExtensions); - } else if (version.equals(WebSocketVersion.V08.toHttpHeaderValue())) { - // Version 8 of the wire protocol - version 10 of the draft hybi specification. - return new WebSocketServerHandshaker08(webSocketURL, subProtocols, this.allowExtensions); - } else { - return null; - } - } else { - // Assume version 00 where version header was not specified - return new WebSocketServerHandshaker00(webSocketURL, subProtocols); - } - } + String version = req.getHeader(Names.SEC_WEBSOCKET_VERSION); + if (version != null) { + if (version.equals(WebSocketVersion.V13.toHttpHeaderValue())) { + // Version 13 of the wire protocol - RFC 6455 (version 17 of the draft hybi specification). + return new WebSocketServerHandshaker13(webSocketURL, subProtocols, this.allowExtensions); + } else if (version.equals(WebSocketVersion.V08.toHttpHeaderValue())) { + // Version 8 of the wire protocol - version 10 of the draft hybi specification. + return new WebSocketServerHandshaker08(webSocketURL, subProtocols, this.allowExtensions); + } else { + return null; + } + } else { + // Assume version 00 where version header was not specified + return new WebSocketServerHandshaker00(webSocketURL, subProtocols); + } + } - /** - * Return that we need cannot not support the web socket version - * - * @param channel - * Channel - */ - public void sendUnsupportedWebSocketVersionResponse(Channel channel) { - HttpResponse res = new DefaultHttpResponse(HttpVersion.HTTP_1_1, new HttpResponseStatus(101, - "Switching Protocols")); - res.setStatus(HttpResponseStatus.UPGRADE_REQUIRED); - res.setHeader(Names.SEC_WEBSOCKET_VERSION, WebSocketVersion.V13.toHttpHeaderValue()); - channel.write(res); - } + /** + * Return that we need cannot not support the web socket version + * + * @param channel + * Channel + */ + public void sendUnsupportedWebSocketVersionResponse(Channel channel) { + HttpResponse res = new DefaultHttpResponse(HttpVersion.HTTP_1_1, new HttpResponseStatus(101, + "Switching Protocols")); + res.setStatus(HttpResponseStatus.UPGRADE_REQUIRED); + res.setHeader(Names.SEC_WEBSOCKET_VERSION, WebSocketVersion.V13.toHttpHeaderValue()); + channel.write(res); + } } diff --git a/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketVersion.java b/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketVersion.java index 1a819b950c..3c7e842a3b 100644 --- a/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketVersion.java +++ b/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketVersion.java @@ -25,38 +25,38 @@ package io.netty.handler.codec.http.websocketx; *

*/ public enum WebSocketVersion { - UNKNOWN, + UNKNOWN, - /** - * draft-ietf-hybi-thewebsocketprotocol- 00. - */ - V00, + /** + * draft-ietf-hybi-thewebsocketprotocol- 00. + */ + V00, - /** - * draft-ietf-hybi-thewebsocketprotocol- 10 - */ - V08, + /** + * draft-ietf-hybi-thewebsocketprotocol- 10 + */ + V08, - /** - * RFC 6455. This was originally draft-ietf-hybi-thewebsocketprotocol- - * 17 - */ - V13; + /** + * RFC 6455. This was originally draft-ietf-hybi-thewebsocketprotocol- + * 17 + */ + V13; - /** - * @return Value for HTTP Header 'Sec-WebSocket-Version' - */ - public String toHttpHeaderValue() { - if (this == V00) { - return "0"; - } else if (this == V08) { - return "8"; - } else if (this == V13) { - return "13"; - } - throw new IllegalArgumentException(this.toString() + " cannot be converted to a string."); - } + /** + * @return Value for HTTP Header 'Sec-WebSocket-Version' + */ + public String toHttpHeaderValue() { + if (this == V00) { + return "0"; + } else if (this == V08) { + return "8"; + } else if (this == V13) { + return "13"; + } + throw new IllegalArgumentException(this.toString() + " does not have a HttpHeaderValue."); + } } diff --git a/src/test/java/io/netty/handler/codec/http/websocketx/WebSocketServerHandshaker13Test.java b/src/test/java/io/netty/handler/codec/http/websocketx/WebSocketServerHandshaker13Test.java index 04473624f7..21d5bade2c 100644 --- a/src/test/java/io/netty/handler/codec/http/websocketx/WebSocketServerHandshaker13Test.java +++ b/src/test/java/io/netty/handler/codec/http/websocketx/WebSocketServerHandshaker13Test.java @@ -38,41 +38,41 @@ import org.junit.Test; public class WebSocketServerHandshaker13Test { - private DefaultChannelPipeline createPipeline() { - DefaultChannelPipeline pipeline = new DefaultChannelPipeline(); - pipeline.addLast("chunkAggregator", new HttpChunkAggregator(42)); - pipeline.addLast("requestDecoder", new HttpRequestDecoder()); - pipeline.addLast("responseEncoder", new HttpResponseEncoder()); - return pipeline; - } + private DefaultChannelPipeline createPipeline() { + DefaultChannelPipeline pipeline = new DefaultChannelPipeline(); + pipeline.addLast("chunkAggregator", new HttpChunkAggregator(42)); + pipeline.addLast("requestDecoder", new HttpRequestDecoder()); + pipeline.addLast("responseEncoder", new HttpResponseEncoder()); + return pipeline; + } - @Test - public void testPerformOpeningHandshake() { - Channel channelMock = EasyMock.createMock(Channel.class); + @Test + public void testPerformOpeningHandshake() { + Channel channelMock = EasyMock.createMock(Channel.class); - DefaultChannelPipeline pipeline = createPipeline(); - EasyMock.expect(channelMock.getPipeline()).andReturn(pipeline); + DefaultChannelPipeline pipeline = createPipeline(); + EasyMock.expect(channelMock.getPipeline()).andReturn(pipeline); - // capture the http response in order to verify the headers - Capture res = new Capture(); - EasyMock.expect(channelMock.write(capture(res))).andReturn(new DefaultChannelFuture(channelMock, true)); + // capture the http response in order to verify the headers + Capture res = new Capture(); + EasyMock.expect(channelMock.write(capture(res))).andReturn(new DefaultChannelFuture(channelMock, true)); - replay(channelMock); + replay(channelMock); - HttpRequest req = new DefaultHttpRequest(HTTP_1_1, HttpMethod.GET, "/chat"); - req.setHeader(Names.HOST, "server.example.com"); - req.setHeader(Names.UPGRADE, WEBSOCKET.toLowerCase()); - req.setHeader(Names.CONNECTION, "Upgrade"); - req.setHeader(Names.SEC_WEBSOCKET_KEY, "dGhlIHNhbXBsZSBub25jZQ=="); - req.setHeader(Names.SEC_WEBSOCKET_ORIGIN, "http://example.com"); - req.setHeader(Names.SEC_WEBSOCKET_PROTOCOL, "chat, superchat"); - req.setHeader(Names.SEC_WEBSOCKET_VERSION, "13"); + HttpRequest req = new DefaultHttpRequest(HTTP_1_1, HttpMethod.GET, "/chat"); + req.setHeader(Names.HOST, "server.example.com"); + req.setHeader(Names.UPGRADE, WEBSOCKET.toLowerCase()); + req.setHeader(Names.CONNECTION, "Upgrade"); + req.setHeader(Names.SEC_WEBSOCKET_KEY, "dGhlIHNhbXBsZSBub25jZQ=="); + req.setHeader(Names.SEC_WEBSOCKET_ORIGIN, "http://example.com"); + req.setHeader(Names.SEC_WEBSOCKET_PROTOCOL, "chat, superchat"); + req.setHeader(Names.SEC_WEBSOCKET_VERSION, "13"); - WebSocketServerHandshaker13 handsaker13 = new WebSocketServerHandshaker13("ws://example.com/chat", "chat", - false); - handsaker13.performOpeningHandshake(channelMock, req); + WebSocketServerHandshaker13 handsaker13 = new WebSocketServerHandshaker13("ws://example.com/chat", "chat", + false); + handsaker13.performOpeningHandshake(channelMock, req); - Assert.assertEquals("s3pPLMBiTxaQ9kYGzzhZRbK+xOo=", res.getValue().getHeader(Names.SEC_WEBSOCKET_ACCEPT)); - Assert.assertEquals("chat", res.getValue().getHeader(Names.SEC_WEBSOCKET_PROTOCOL)); - } + Assert.assertEquals("s3pPLMBiTxaQ9kYGzzhZRbK+xOo=", res.getValue().getHeader(Names.SEC_WEBSOCKET_ACCEPT)); + Assert.assertEquals("chat", res.getValue().getHeader(Names.SEC_WEBSOCKET_PROTOCOL)); + } }