@SuppressWarnings("unchecked") @Test public void close() throws Exception { new MockUnit(ChannelHandlerContext.class, WebSocketServerHandshaker.class, Consumer.class) .expect(channel) .expect(close) .expect(unit -> { Attribute<NettyWebSocket> attr = unit.mock(Attribute.class); attr.set(null); Channel ctx = unit.get(Channel.class); expect(ctx.attr(NettyWebSocket.KEY)).andReturn(attr); }) .run(unit -> { new NettyWebSocket( unit.get(ChannelHandlerContext.class), unit.get(WebSocketServerHandshaker.class), unit.get(Consumer.class)).close(1001, "normal"); }); }
@SuppressWarnings("unchecked") @Test public void closeNoAttr() throws Exception { new MockUnit(ChannelHandlerContext.class, WebSocketServerHandshaker.class, Consumer.class) .expect(channel) .expect(close) .expect(unit -> { Channel ctx = unit.get(Channel.class); expect(ctx.attr(NettyWebSocket.KEY)).andReturn(null); }) .run(unit -> { new NettyWebSocket( unit.get(ChannelHandlerContext.class), unit.get(WebSocketServerHandshaker.class), unit.get(Consumer.class)).close(1001, "normal"); }); }
@SuppressWarnings("unchecked") @Test public void resume() throws Exception { new MockUnit(ChannelHandlerContext.class, WebSocketServerHandshaker.class, Consumer.class) .expect(unit -> { ChannelConfig chconf = unit.mock(ChannelConfig.class); expect(chconf.isAutoRead()).andReturn(false); expect(chconf.setAutoRead(true)).andReturn(chconf); Channel ch = unit.mock(Channel.class); expect(ch.config()).andReturn(chconf); ChannelHandlerContext ctx = unit.get(ChannelHandlerContext.class); expect(ctx.channel()).andReturn(ch); }) .run(unit -> { new NettyWebSocket( unit.get(ChannelHandlerContext.class), unit.get(WebSocketServerHandshaker.class), unit.get(Consumer.class)).resume(); }); }
@SuppressWarnings("unchecked") @Test public void resumeIgnored() throws Exception { new MockUnit(ChannelHandlerContext.class, WebSocketServerHandshaker.class, Consumer.class) .expect(unit -> { ChannelConfig chconf = unit.mock(ChannelConfig.class); expect(chconf.isAutoRead()).andReturn(true); Channel ch = unit.mock(Channel.class); expect(ch.config()).andReturn(chconf); ChannelHandlerContext ctx = unit.get(ChannelHandlerContext.class); expect(ctx.channel()).andReturn(ch); }) .run(unit -> { new NettyWebSocket( unit.get(ChannelHandlerContext.class), unit.get(WebSocketServerHandshaker.class), unit.get(Consumer.class)).resume(); }); }
@SuppressWarnings("unchecked") @Test public void pause() throws Exception { new MockUnit(ChannelHandlerContext.class, WebSocketServerHandshaker.class, Consumer.class) .expect(unit -> { ChannelConfig chconf = unit.mock(ChannelConfig.class); expect(chconf.isAutoRead()).andReturn(true); expect(chconf.setAutoRead(false)).andReturn(chconf); Channel ch = unit.mock(Channel.class); expect(ch.config()).andReturn(chconf); ChannelHandlerContext ctx = unit.get(ChannelHandlerContext.class); expect(ctx.channel()).andReturn(ch); }) .run(unit -> { new NettyWebSocket( unit.get(ChannelHandlerContext.class), unit.get(WebSocketServerHandshaker.class), unit.get(Consumer.class)).pause(); }); }
@SuppressWarnings("unchecked") @Test public void pauseIgnored() throws Exception { new MockUnit(ChannelHandlerContext.class, WebSocketServerHandshaker.class, Consumer.class) .expect(unit -> { ChannelConfig chconf = unit.mock(ChannelConfig.class); expect(chconf.isAutoRead()).andReturn(false); Channel ch = unit.mock(Channel.class); expect(ch.config()).andReturn(chconf); ChannelHandlerContext ctx = unit.get(ChannelHandlerContext.class); expect(ctx.channel()).andReturn(ch); }) .run(unit -> { new NettyWebSocket( unit.get(ChannelHandlerContext.class), unit.get(WebSocketServerHandshaker.class), unit.get(Consumer.class)).pause(); }); }
@SuppressWarnings("unchecked") @Test public void terminate() throws Exception { new MockUnit(ChannelHandlerContext.class, WebSocketServerHandshaker.class, Consumer.class, BiConsumer.class) .expect(unit -> { BiConsumer<Integer, Optional<String>> callback = unit.get(BiConsumer.class); callback.accept(1006, Optional.of("Harsh disconnect")); ChannelFuture future = unit.mock(ChannelFuture.class); expect(future.addListener(CLOSE)).andReturn(future); ChannelHandlerContext ctx = unit.get(ChannelHandlerContext.class); expect(ctx.disconnect()).andReturn(future); }) .run(unit -> { NettyWebSocket ws = new NettyWebSocket( unit.get(ChannelHandlerContext.class), unit.get(WebSocketServerHandshaker.class), unit.get(Consumer.class)); ws.onCloseMessage(unit.get(BiConsumer.class)); ws.terminate(); }); }
@SuppressWarnings("unchecked") @Test public void isOpen() throws Exception { new MockUnit(ChannelHandlerContext.class, WebSocketServerHandshaker.class, Consumer.class) .expect(unit -> { Channel ch = unit.mock(Channel.class); expect(ch.isOpen()).andReturn(true); ChannelHandlerContext ctx = unit.get(ChannelHandlerContext.class); expect(ctx.channel()).andReturn(ch); }) .run(unit -> { assertEquals(true, new NettyWebSocket( unit.get(ChannelHandlerContext.class), unit.get(WebSocketServerHandshaker.class), unit.get(Consumer.class)).isOpen()); }); }
@SuppressWarnings("unchecked") @Test public void isNoOpen() throws Exception { new MockUnit(ChannelHandlerContext.class, WebSocketServerHandshaker.class, Consumer.class) .expect(unit -> { Channel ch = unit.mock(Channel.class); expect(ch.isOpen()).andReturn(false); ChannelHandlerContext ctx = unit.get(ChannelHandlerContext.class); expect(ctx.channel()).andReturn(ch); }) .run(unit -> { assertEquals(false, new NettyWebSocket( unit.get(ChannelHandlerContext.class), unit.get(WebSocketServerHandshaker.class), unit.get(Consumer.class)).isOpen()); }); }
@SuppressWarnings("unchecked") @Test public void connect() throws Exception { new MockUnit(ChannelHandlerContext.class, WebSocketServerHandshaker.class, Consumer.class, CountDownLatch.class, Runnable.class) .expect(unit -> { CountDownLatch ready = unit.mockConstructor(CountDownLatch.class, new Class[]{int.class }, 1); ready.countDown(); unit.get(Runnable.class).run(); }) .run(unit -> { NettyWebSocket ws = new NettyWebSocket( unit.get(ChannelHandlerContext.class), unit.get(WebSocketServerHandshaker.class), unit.get(Consumer.class)); ws.onConnect(unit.get(Runnable.class)); ws.connect(); }); }
@SuppressWarnings("unchecked") @Test public void hankshake() throws Exception { new MockUnit(ChannelHandlerContext.class, WebSocketServerHandshaker.class, CountDownLatch.class, Consumer.class) .expect(unit -> { unit.get(Consumer.class).accept(isA(NettyWebSocket.class)); }) .run(unit -> { NettyWebSocket ws = new NettyWebSocket( unit.get(ChannelHandlerContext.class), unit.get(WebSocketServerHandshaker.class), unit.get(Consumer.class)); ws.hankshake(); }); }
@SuppressWarnings("unchecked") @Test public void handleTextFrame() throws Exception { new MockUnit(ChannelHandlerContext.class, WebSocketServerHandshaker.class, Consumer.class, TextWebSocketFrame.class) .expect(unit -> { CountDownLatch ready = unit.mockConstructor(CountDownLatch.class, new Class[]{int.class }, 1); ready.await(); TextWebSocketFrame frame = unit.get(TextWebSocketFrame.class); expect(frame.text()).andReturn("text"); Consumer<String> callback = unit.get(Consumer.class); callback.accept("text"); }) .run(unit -> { NettyWebSocket ws = new NettyWebSocket( unit.get(ChannelHandlerContext.class), unit.get(WebSocketServerHandshaker.class), unit.get(Consumer.class)); ws.onTextMessage(unit.get(Consumer.class)); ws.handle(unit.get(TextWebSocketFrame.class)); }); }
@SuppressWarnings("unchecked") @Test public void handleInterruped() throws Exception { new MockUnit(ChannelHandlerContext.class, WebSocketServerHandshaker.class, Consumer.class, WebSocketFrame.class) .expect(unit -> { CountDownLatch ready = unit.mockConstructor(CountDownLatch.class, new Class[]{int.class }, 1); ready.await(); expectLastCall().andThrow(new InterruptedException("intentional err")); Thread thread = unit.mock(Thread.class); thread.interrupt(); unit.mockStatic(Thread.class); expect(Thread.currentThread()).andReturn(thread); }) .run(unit -> { NettyWebSocket ws = new NettyWebSocket( unit.get(ChannelHandlerContext.class), unit.get(WebSocketServerHandshaker.class), unit.get(Consumer.class)); ws.handle(unit.get(WebSocketFrame.class)); }); }
@SuppressWarnings("unchecked") @Test public void handleException() throws Exception { Throwable cause = new NullPointerException("intentional err"); new MockUnit(ChannelHandlerContext.class, WebSocketServerHandshaker.class, Consumer.class) .expect(unit -> { CountDownLatch ready = unit.mockConstructor(CountDownLatch.class, new Class[]{int.class }, 1); ready.await(); Consumer<Throwable> callback = unit.get(Consumer.class); callback.accept(cause); }) .run(unit -> { NettyWebSocket ws = new NettyWebSocket( unit.get(ChannelHandlerContext.class), unit.get(WebSocketServerHandshaker.class), unit.get(Consumer.class)); ws.onErrorMessage(unit.get(Consumer.class)); ws.handle(cause); }); }
private void handshake(final ChannelHandlerContext ctx, final FullHttpRequest req, final String requestPath) { WebSocketServerHandshakerFactory wsFactory = new WebSocketServerHandshakerFactory(getWebSocketLocation(req), null, true, maxWebSocketFrameSize); WebSocketServerHandshaker handshaker = wsFactory.newHandshaker(req); if (handshaker != null) { handshaker.handshake(ctx.channel(), req).addListener( new ChannelFutureListener() { @Override public void operationComplete(ChannelFuture future) throws Exception { final String sessionId = PipelineUtils.getSessionId(requestPath); if (future.isSuccess()) { ctx.channel().pipeline().addBefore( SocketIOChannelInitializer.SOCKETIO_WEBSOCKET_HANDLER, SocketIOChannelInitializer.WEBSOCKET_FRAME_AGGREGATOR, new WebSocketFrameAggregator(maxWebSocketFrameSize)); connect(ctx, req, sessionId); } else { log.error("Can't handshake: {}", sessionId, future.cause()); } } }); } else { WebSocketServerHandshakerFactory.sendUnsupportedVersionResponse(ctx.channel()); } }
/** * handle WebSocket request,then, the the RPC could happen in WebSocket. * * @param ctx * @param request */ protected void handleWebSocket(final ChannelHandlerContext ctx, FullHttpRequest request) { if (logger.isDebugEnabled()) { logger.debug("handleWebSocket request: uri={}", request.uri()); } // Handshake WebSocketServerHandshakerFactory wsFactory = new WebSocketServerHandshakerFactory(request.uri(), null, true); WebSocketServerHandshaker handshaker = wsFactory.newHandshaker(request); if (handshaker == null) { WebSocketServerHandshakerFactory.sendUnsupportedVersionResponse(ctx.channel()); return; } ChannelFutureListener callback = websocketHandshakeListener(ctx, request); ChannelFuture future = handshaker.handshake(ctx.channel(), request); if (callback != null) { future.addListener(callback); } ChannelPipeline pipe = ctx.pipeline(); if (pipe.get(WebsocketFrameHandler.class) == null) { pipe.addAfter(ctx.name(), "wsFrameHandler", new WebsocketFrameHandler(handshaker)); ChannelHandler handlerAws = pipe.get(AwsProxyProtocolDecoder.class); if (handlerAws != null) { pipe.remove(handlerAws); } pipe.remove(ctx.name());// Remove current Handler } }
@Override protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest req) throws Exception { if (!req.decoderResult().isSuccess()) { sendHttpResponse(ctx, req, new DefaultFullHttpResponse(HTTP_1_1, BAD_REQUEST)); return; } // Allow only GET methods. if (req.method() != GET) { sendHttpResponse(ctx, req, new DefaultFullHttpResponse(HTTP_1_1, FORBIDDEN)); return; } /** * 当且仅当uri为指定path的时候,进行websocket通讯的升级 * */ if (uri.equals(req.uri()) //CONNECTION 字段的值为 UPGRADE, firefox上存在多个值的情况 && req.headers().get(HttpHeaderNames.CONNECTION).contains(HttpHeaderValues.UPGRADE) //UPGRADE 字段的值为 WEBSOCKET && HttpHeaderValues.WEBSOCKET.contentEqualsIgnoreCase(req.headers().get(HttpHeaderNames.UPGRADE)) ) { WebSocketServerHandshakerFactory wsFactory = new WebSocketServerHandshakerFactory( uri, subprotocols, true, 5 * 1024 * 1024); WebSocketServerHandshaker handshaker = wsFactory.newHandshaker(req); if (handshaker == null) { //不支持的协议 WebSocketServerHandshakerFactory.sendUnsupportedVersionResponse(ctx.channel()); } else { //握手结束后补充如下协议 handshaker.handshake(ctx.channel(), req); } return; } //错误的情况 sendHttpResponse(ctx, req, new DefaultFullHttpResponse(HTTP_1_1, NOT_FOUND)); }
public WebSocketClient(@NotNull Channel channel, @NotNull WebSocketServerHandshaker handshaker) { super(channel); this.handshaker = handshaker; }
private void handleWebSocketRequest(@NotNull final ChannelHandlerContext context, @NotNull FullHttpRequest request, @NotNull final QueryStringDecoder uriDecoder) { WebSocketServerHandshakerFactory factory = new WebSocketServerHandshakerFactory("ws://" + request.headers().getAsString(HttpHeaderNames.HOST) + uriDecoder.path(), null, false, NettyUtil.MAX_CONTENT_LENGTH); WebSocketServerHandshaker handshaker = factory.newHandshaker(request); if (handshaker == null) { WebSocketServerHandshakerFactory.sendUnsupportedVersionResponse(context.channel()); return; } if (!context.channel().isOpen()) { return; } final Client client = new WebSocketClient(context.channel(), handshaker); context.attr(ClientManager.CLIENT).set(client); handshaker.handshake(context.channel(), request).addListener(new ChannelFutureListener() { @Override public void operationComplete(ChannelFuture future) throws Exception { if (future.isSuccess()) { ClientManager clientManager = WebSocketHandshakeHandler.this.clientManager.getValue(); clientManager.addClient(client); MessageChannelHandler messageChannelHandler = new MessageChannelHandler(clientManager, getMessageServer()); BuiltInServer.replaceDefaultHandler(context, messageChannelHandler); ChannelHandlerContext messageChannelHandlerContext = context.pipeline().context(messageChannelHandler); context.pipeline().addBefore(messageChannelHandlerContext.name(), "webSocketFrameAggregator", new WebSocketFrameAggregator(NettyUtil.MAX_CONTENT_LENGTH)); messageChannelHandlerContext.attr(ClientManager.CLIENT).set(client); connected(client, uriDecoder.parameters()); } } }); }
private void handleWebSocketResponse(ChannelHandlerContext ctx, Outgoing out) { WebSocketHttpResponse response = (WebSocketHttpResponse) out.message; WebSocketServerHandshaker handshaker = response.handshakerFactory().newHandshaker(lastRequest); if (handshaker == null) { HttpResponse res = new DefaultFullHttpResponse( HttpVersion.HTTP_1_1, HttpResponseStatus.UPGRADE_REQUIRED); res.headers().set(HttpHeaderNames.SEC_WEBSOCKET_VERSION, WebSocketVersion.V13.toHttpHeaderValue()); HttpUtil.setContentLength(res, 0); super.unbufferedWrite(ctx, new Outgoing(res, out.promise)); response.subscribe(new CancelledSubscriber<>()); } else { // First, insert new handlers in the chain after us for handling the websocket ChannelPipeline pipeline = ctx.pipeline(); HandlerPublisher<WebSocketFrame> publisher = new HandlerPublisher<>(ctx.executor(), WebSocketFrame.class); HandlerSubscriber<WebSocketFrame> subscriber = new HandlerSubscriber<>(ctx.executor()); pipeline.addAfter(ctx.executor(), ctx.name(), "websocket-subscriber", subscriber); pipeline.addAfter(ctx.executor(), ctx.name(), "websocket-publisher", publisher); // Now remove ourselves from the chain ctx.pipeline().remove(ctx.name()); // Now do the handshake // Wrap the request in an empty request because we don't need the WebSocket handshaker ignoring the body, // we already have handled the body. handshaker.handshake(ctx.channel(), new EmptyHttpRequest(lastRequest)); // And hook up the subscriber/publishers response.subscribe(subscriber); publisher.subscribe(response); } }
public NettyServerWebSocket(ChannelHandlerContext context, FullHttpRequest req, WebSocketServerHandshaker handshaker) { this.context = context; this.request = req; this.handshaker = handshaker; }
@Override public <T> T unwrap(Class<T> clazz) { return ChannelHandlerContext.class.isAssignableFrom(clazz) ? clazz.cast(context) : WebSocketServerHandshaker.class.isAssignableFrom(clazz) ? clazz.cast(handshaker) : FullHttpRequest.class.isAssignableFrom(clazz) ? clazz.cast(request) : null; }
@Test public void unwrap() throws Throwable { websocketAction(new Action<ServerWebSocket>() { @Override public void on(ServerWebSocket ws) { threadAssertTrue(ws.unwrap(ChannelHandlerContext.class) instanceof ChannelHandlerContext); threadAssertTrue(ws.unwrap(WebSocketServerHandshaker.class) instanceof WebSocketServerHandshaker); threadAssertTrue(ws.unwrap(FullHttpRequest.class) instanceof FullHttpRequest); resume(); } }); client.connect(new WebSocketAdapter(), URI.create(uri())); await(); }
@Override public boolean call(NettyHandler handler, ChannelHandlerContext ctx, FullHttpRequest req, Map<String, String> params) throws IOException { WebSocketServerHandshaker handshaker = new WebSocketServerHandshakerFactory( String.format("ws://%s%s", req.headers().get(Names.HOST), pattern), null, true ).newHandshaker(req); if (handshaker == null) { WebSocketServerHandshakerFactory.sendUnsupportedVersionResponse(ctx.channel()); } else { WebSocket ws = getCallback().newInstance(new WrappedRequest<>(req, params, sessions)); if (ws instanceof WebSocket) { Channel ch = handshaker.handshake(ctx.channel(), req).channel(); handler.onWsFrame(new WsBridge(handshaker, ch, ws)); ws.onOpen(); } else { FullHttpResponse forbidden = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.FORBIDDEN); ByteBufUtil.writeUtf8(forbidden.content(), "Forbidden."); ctx.writeAndFlush(forbidden); ctx.close(); } } return true; }
@Override public HandshakeFuture handshake() { WebSocketServerHandshakerFactory wsFactory = new WebSocketServerHandshakerFactory(getWebSocketURL(httpRequest), null, true); WebSocketServerHandshaker handshaker = wsFactory.newHandshaker(httpRequest); return handleHandshake(handshaker, 0); }
@Override public HandshakeFuture handshake(String[] subProtocols, boolean allowExtensions) { WebSocketServerHandshakerFactory wsFactory = new WebSocketServerHandshakerFactory(getWebSocketURL(httpRequest), getSubProtocolsCSV(subProtocols), allowExtensions); WebSocketServerHandshaker handshaker = wsFactory.newHandshaker(httpRequest); return handleHandshake(handshaker, 0); }
@Override public HandshakeFuture handshake(String[] subProtocols, boolean allowExtensions, int idleTimeout) { WebSocketServerHandshakerFactory wsFactory = new WebSocketServerHandshakerFactory(getWebSocketURL(httpRequest), getSubProtocolsCSV(subProtocols), allowExtensions); WebSocketServerHandshaker handshaker = wsFactory.newHandshaker(httpRequest); return handleHandshake(handshaker, idleTimeout); }
@Override public void cancelHandShake(int closeCode, String closeReason) { try { WebSocketServerHandshakerFactory wsFactory = new WebSocketServerHandshakerFactory(getWebSocketURL(httpRequest), getSubProtocol(), true); WebSocketServerHandshaker handshaker = wsFactory.newHandshaker(httpRequest); ChannelFuture channelFuture = handshaker.close(ctx.channel(), new CloseWebSocketFrame(closeCode, closeReason)); channelFuture.channel().close(); } finally { isCancelled = true; } }
@Test public void unwrap() { performer.onserver(new Action<ServerWebSocket>() { @Override public void on(ServerWebSocket ws) { assertThat(ws.unwrap(ChannelHandlerContext.class), instanceOf(ChannelHandlerContext.class)); assertThat(ws.unwrap(WebSocketServerHandshaker.class), instanceOf(WebSocketServerHandshaker.class)); assertThat(ws.unwrap(FullHttpRequest.class), instanceOf(FullHttpRequest.class)); performer.start(); } }) .connect(); }
public ChannelHandler serverHandshake(ChannelHandlerContext ctx, FullHttpRequest msg) { this.ctx = ctx; // Handshake WebSocketServerHandshaker handshaker; WebSocketServerHandshakerFactory wsFactory = new WebSocketServerHandshakerFactory(getWebSocketLocation(msg), null, true); handshaker = wsFactory.newHandshaker(msg); if (handshaker == null) { WebSocketServerHandshakerFactory.sendUnsupportedVersionResponse(ctx.channel()); } else { ChannelPromise promise = ctx.channel().newPromise(); promise.addListener(future -> { if (promise.isSuccess()) { this.notifyOpen(); } else { this.notifyError(); } }); handshaker.handshake(ctx.channel(), msg, null, promise); } return new MyChannelHandler((ctx1, frame) -> { handshaker.close(ctx1.channel(), (CloseWebSocketFrame) frame.retain()); }); }
private void handleHttpRequest(ChannelHandlerContext ctx, FullHttpRequest req) { // Handle a bad request. if (!req.getDecoderResult().isSuccess()) { sendErrorResponse(ctx, req, BAD_REQUEST); return; } // Allow only GET methods. if (req.getMethod() != GET) { sendErrorResponse(ctx, req, FORBIDDEN); return; } String path = req.getUri(); System.out.println("Server => Request: " + path); try { if (path.equals("/ws")) { isWebSocket = true; String wsLocation = getWebSocketLocation(ctx, req); WebSocketServerHandshaker handshaker = new WebSocketServerHandshakerFactory( wsLocation, null, false, 64 * 1024).newHandshaker(req); if (handshaker == null) { WebSocketServerHandshakerFactory.sendUnsupportedVersionResponse(ctx.channel()) .addListener(ChannelFutureListener.CLOSE); } else { handshaker.handshake(ctx.channel(), req); // Push the initial state to the client. // Do it from the server thread were it's safe bossGroup.execute(() -> { ctx.writeAndFlush(makeWebSocketEventFrame("stateChanged", lastState)); }); wsConnections.add(ctx.channel()); } } else { handleStaticFileRequest(ctx, req, path); } } catch (Throwable e) { sendErrorResponse(ctx, req, BAD_REQUEST); } }
@SuppressWarnings("unchecked") @Override public <T> T upgrade(final Class<T> type) throws Exception { if (type == NativeWebSocket.class) { String protocol = ifSecure("wss", "ws"); String webSocketURL = protocol + "://" + req.headers().get(HttpHeaderNames.HOST) + path; WebSocketServerHandshakerFactory wsFactory = new WebSocketServerHandshakerFactory( webSocketURL, null, true, wsMaxMessageSize); WebSocketServerHandshaker handshaker = wsFactory.newHandshaker(req); NettyWebSocket result = new NettyWebSocket(ctx, handshaker, (ws) -> { handshaker.handshake(ctx.channel(), (FullHttpRequest) req) .addListener(FIRE_EXCEPTION_ON_FAILURE) .addListener(payload -> ws.connect()) .addListener(FIRE_EXCEPTION_ON_FAILURE); }); ctx.channel().attr(NettyWebSocket.KEY).set(result); return (T) result; } else if (type == Sse.class) { NettySse sse = new NettySse(ctx); return (T) sse; } else if (type == NativePushPromise.class) { return (T) new NettyPush(ctx, req.headers().getInt(HttpConversionUtil.ExtensionHeaderNames.STREAM_ID.text()), header("host").orElse(ip()), ifSecure("https", "http")); } throw new UnsupportedOperationException("Not Supported: " + type); }
@SuppressWarnings("unchecked") @Test public void handleBinaryFrame() throws Exception { new MockUnit(ChannelHandlerContext.class, WebSocketServerHandshaker.class, Consumer.class, BinaryWebSocketFrame.class) .expect(unit -> { CountDownLatch ready = unit.mockConstructor(CountDownLatch.class, new Class[]{int.class }, 1); ready.await(); ByteBuffer nioBuff = ByteBuffer.wrap(new byte[0]); ByteBuf buff = unit.mock(ByteBuf.class); expect(buff.nioBuffer()).andReturn(nioBuff); BinaryWebSocketFrame frame = unit.get(BinaryWebSocketFrame.class); expect(frame.content()).andReturn(buff); Consumer<ByteBuffer> callback = unit.get(Consumer.class); callback.accept(nioBuff); }) .run(unit -> { NettyWebSocket ws = new NettyWebSocket( unit.get(ChannelHandlerContext.class), unit.get(WebSocketServerHandshaker.class), unit.get(Consumer.class)); ws.onBinaryMessage(unit.get(Consumer.class)); ws.handle(unit.get(BinaryWebSocketFrame.class)); }); }
@SuppressWarnings("unchecked") @Test public void handleCloseFrame() throws Exception { new MockUnit(ChannelHandlerContext.class, WebSocketServerHandshaker.class, Consumer.class, CloseWebSocketFrame.class, BiConsumer.class) .expect(unit -> { CountDownLatch ready = unit.mockConstructor(CountDownLatch.class, new Class[]{int.class }, 1); ready.await(); CloseWebSocketFrame retain = unit.get(CloseWebSocketFrame.class); expect(retain.statusCode()).andReturn(-1); expect(retain.reasonText()).andReturn(null); CloseWebSocketFrame frame = unit.get(CloseWebSocketFrame.class); expect(frame.retain()).andReturn(retain); BiConsumer<Integer, Optional<String>> callback = unit.get(BiConsumer.class); callback.accept(1000, Optional.empty()); Channel ch = unit.mock(Channel.class); ChannelHandlerContext ctx = unit.get(ChannelHandlerContext.class); expect(ctx.channel()).andReturn(ch); ChannelFuture future = unit.mock(ChannelFuture.class); expect(future.addListener(CLOSE)).andReturn(future); WebSocketServerHandshaker handshaker = unit.get(WebSocketServerHandshaker.class); expect(handshaker.close(ch, retain)).andReturn(future); }) .run(unit -> { NettyWebSocket ws = new NettyWebSocket( unit.get(ChannelHandlerContext.class), unit.get(WebSocketServerHandshaker.class), unit.get(Consumer.class)); ws.onCloseMessage(unit.get(BiConsumer.class)); ws.handle(unit.get(CloseWebSocketFrame.class)); }); }
@SuppressWarnings("unchecked") @Test public void handleCloseWithStatusFrame() throws Exception { new MockUnit(ChannelHandlerContext.class, WebSocketServerHandshaker.class, Consumer.class, CloseWebSocketFrame.class, BiConsumer.class) .expect(unit -> { CountDownLatch ready = unit.mockConstructor(CountDownLatch.class, new Class[]{int.class }, 1); ready.await(); CloseWebSocketFrame retain = unit.get(CloseWebSocketFrame.class); expect(retain.statusCode()).andReturn(1001); expect(retain.reasonText()).andReturn("normal"); CloseWebSocketFrame frame = unit.get(CloseWebSocketFrame.class); expect(frame.retain()).andReturn(retain); BiConsumer<Integer, Optional<String>> callback = unit.get(BiConsumer.class); callback.accept(1001, Optional.of("normal")); Channel ch = unit.mock(Channel.class); ChannelHandlerContext ctx = unit.get(ChannelHandlerContext.class); expect(ctx.channel()).andReturn(ch); ChannelFuture future = unit.mock(ChannelFuture.class); expect(future.addListener(CLOSE)).andReturn(future); WebSocketServerHandshaker handshaker = unit.get(WebSocketServerHandshaker.class); expect(handshaker.close(ch, retain)).andReturn(future); }) .run(unit -> { NettyWebSocket ws = new NettyWebSocket( unit.get(ChannelHandlerContext.class), unit.get(WebSocketServerHandshaker.class), unit.get(Consumer.class)); ws.onCloseMessage(unit.get(BiConsumer.class)); ws.handle(unit.get(CloseWebSocketFrame.class)); }); }
@Override @SuppressWarnings("PMD.OnlyOneReturn") public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { if (msg instanceof FullHttpRequest) { FullHttpRequest req = (FullHttpRequest) msg; // Handle a bad request. if (!req.decoderResult().isSuccess()) { sendHttpResponse(ctx, req, new DefaultFullHttpResponse(HTTP_1_1, BAD_REQUEST)); return; } // Allow only GET methods. if (req.method() != GET) { sendHttpResponse(ctx, req, new DefaultFullHttpResponse(HTTP_1_1, FORBIDDEN)); return; } // Handshake WebSocketServerHandshakerFactory wsFactory = new WebSocketServerHandshakerFactory( getWebSocketLocation(req), null, false); WebSocketServerHandshaker handshaker = wsFactory.newHandshaker(req); if (handshaker == null) { WebSocketServerHandshakerFactory.sendUnsupportedVersionResponse(ctx.channel()); } else { handshaker.handshake(ctx.channel(), req); } } else { ctx.fireChannelRead(msg); } }
protected WebsocketFrameHandler(WebSocketServerHandshaker handshaker) { this.handshaker = handshaker; }
public WebSocketConnection newConnect(ChannelHandlerContext context, WebSocketServerHandshaker handshaker, String uri, HttpParams param, FullHttpRequest request);
private WsBridge(WebSocketServerHandshaker handshaker, Channel ch, WebSocket endpoint) { this.handshaker = handshaker; this.endpoint = endpoint; endpoint.setChannel(ch); }