in.skipBytes(actualReadableBytes()); return; if (!in.isReadable()) { return; byte b = in.readByte(); frameFinalFlag = (b & 0x80) != 0; frameRsv = (b & 0x70) >> 4; payloadBuffer = readBytes(ctx.alloc(), in, toFrameLength(framePayloadLength)); out.add(new TextWebSocketFrame(frameFinalFlag, frameRsv, payloadBuffer)); payloadBuffer = null; return; } else if (frameOpcode == OPCODE_BINARY) { out.add(new BinaryWebSocketFrame(frameFinalFlag, frameRsv, payloadBuffer)); payloadBuffer = null; return; } else if (frameOpcode == OPCODE_CONT) { out.add(new ContinuationWebSocketFrame(frameFinalFlag, frameRsv, payloadBuffer)); payloadBuffer = null;
@Override public ContinuationWebSocketFrame replace(ByteBuf content) { return new ContinuationWebSocketFrame(isFinalFragment(), rsv(), content); }
boolean readable = msg.content().isReadable(); decoder.writeInbound(msg.content().retain()); if (appendFrameTail(msg)) { decoder.writeInbound(Unpooled.wrappedBuffer(FRAME_TAIL)); CompositeByteBuf compositeUncompressedContent = ctx.alloc().compositeBuffer(); for (;;) { ByteBuf partUncompressedContent = decoder.readInbound(); break; if (!partUncompressedContent.isReadable()) { partUncompressedContent.release(); continue; outMsg = new TextWebSocketFrame(msg.isFinalFragment(), newRsv(msg), compositeUncompressedContent); } else if (msg instanceof BinaryWebSocketFrame) { outMsg = new BinaryWebSocketFrame(msg.isFinalFragment(), newRsv(msg), compositeUncompressedContent); } else if (msg instanceof ContinuationWebSocketFrame) { outMsg = new ContinuationWebSocketFrame(msg.isFinalFragment(), newRsv(msg), compositeUncompressedContent); } else {
LOG.trace("New data read: incoming: {}", message); Channel ch = ctx.channel(); if (!handshaker.isHandshakeComplete()) { handshaker.finishHandshake(ch, (FullHttpResponse) message); LOG.trace("WebSocket Client connected! {}", ctx.channel()); FullHttpResponse response = (FullHttpResponse) message; throw new IllegalStateException( "Unexpected FullHttpResponse (getStatus=" + response.status() + ", content=" + response.content().toString(StandardCharsets.UTF_8) + ')'); if (frame instanceof TextWebSocketFrame) { TextWebSocketFrame textFrame = (TextWebSocketFrame) frame; LOG.warn("WebSocket Client received message: " + textFrame.text()); ctx.fireExceptionCaught(new IOException("Received invalid frame over WebSocket.")); } else if (frame instanceof BinaryWebSocketFrame) { BinaryWebSocketFrame binaryFrame = (BinaryWebSocketFrame) frame; LOG.trace("WebSocket Client received data: {} bytes", binaryFrame.content().readableBytes()); listener.onData(binaryFrame.content()); } else if (frame instanceof ContinuationWebSocketFrame) { ContinuationWebSocketFrame continuationFrame = (ContinuationWebSocketFrame) frame; LOG.trace("WebSocket Client received data continuation: {} bytes", continuationFrame.content().readableBytes()); listener.onData(continuationFrame.content()); } else if (frame instanceof PingWebSocketFrame) { LOG.trace("WebSocket Client received ping, response with pong");
@Override public void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception { Channel ch = ctx.channel(); if (!handshaker.isHandshakeComplete()) { handshaker.finishHandshake(ch, (FullHttpResponse) msg); throw new IllegalStateException( "Unexpected FullHttpResponse (getStatus=" + response.status() + ", content=" + response.content().toString(CharsetUtil.UTF_8) + ')'); if (frame instanceof TextWebSocketFrame) { TextWebSocketFrame textFrame = (TextWebSocketFrame) frame; if (textFrame.isFinalFragment()) { receivedTextMessage(textFrame.text()); } else { partialText.append(textFrame.text()); partialText.append(continuationFrame.text()); if (continuationFrame.isFinalFragment()) { receivedTextMessage(partialText.toString()); partialText.setLength(0);
@Override protected void encode(ChannelHandlerContext ctx, WebSocketConvertHandler.MyWebSocketFrame msg, List<Object> out) throws Exception { ByteBuf payload = msg.getData().duplicate().retain(); switch (msg.getType()) { case BINARY: out.add(new BinaryWebSocketFrame(payload)); break; case TEXT: out.add(new TextWebSocketFrame(payload)); break; case CLOSE: out.add(new CloseWebSocketFrame(true, 0, payload)); break; case CONTINUATION: out.add(new ContinuationWebSocketFrame(payload)); break; case PONG: out.add(new PongWebSocketFrame(payload)); break; case PING: out.add(new PingWebSocketFrame(payload)); break; default: throw new IllegalStateException( "Unsupported websocket msg " + msg);} }
@Override public ChannelFuture pushText(String text, boolean finalFrame) { if (continuationFrameType == WebSocketFrameType.BINARY) { throw new IllegalStateException("Cannot interrupt WebSocket binary frame continuation"); } if (closeFrameSent) { throw new IllegalStateException("Close frame already sent. Cannot push text data!"); } if (continuationFrameType != null) { if (finalFrame) { continuationFrameType = null; } return ctx.writeAndFlush(new ContinuationWebSocketFrame(finalFrame, 0, text)); } if (!finalFrame) { continuationFrameType = WebSocketFrameType.TEXT; } return ctx.writeAndFlush(new TextWebSocketFrame(finalFrame, 0, text)); }
WebSocketFrame encodeFrame(WebSocketFrameImpl frame) { ByteBuf buf = frame.getBinaryData(); if (buf != Unpooled.EMPTY_BUFFER) { buf = safeBuffer(buf, chctx.alloc()); } switch (frame.type()) { case BINARY: return new BinaryWebSocketFrame(frame.isFinal(), 0, buf); case TEXT: return new TextWebSocketFrame(frame.isFinal(), 0, buf); case CLOSE: return new CloseWebSocketFrame(true, 0, buf); case CONTINUATION: return new ContinuationWebSocketFrame(frame.isFinal(), 0, buf); case PONG: return new PongWebSocketFrame(buf); case PING: return new PingWebSocketFrame(buf); default: throw new IllegalStateException("Unsupported websocket msg " + frame); } }
@Override public ChannelFuture pushBinary(ByteBuffer data, boolean finalFrame) { if (continuationFrameType == WebSocketFrameType.TEXT) { throw new IllegalStateException("Cannot interrupt WebSocket text frame continuation"); } if (closeFrameSent) { throw new IllegalStateException("Close frame already sent. Cannot push binary data."); } if (continuationFrameType != null) { if (finalFrame) { continuationFrameType = null; } return ctx.writeAndFlush(new ContinuationWebSocketFrame(finalFrame, 0, getNettyByteBuf(data))); } if (!finalFrame) { continuationFrameType = WebSocketFrameType.BINARY; } return ctx.writeAndFlush(new BinaryWebSocketFrame(finalFrame, 0, getNettyByteBuf(data))); }
private void handleWebSocketFrame(ChannelHandlerContext ctx, WebSocketFrame frame) { if (logger.isDebugEnabled()) { logger.debug(String .format("Channel %s received %s", ctx.getChannel().getId(), frame.getClass().getSimpleName())); } if (frame instanceof CloseWebSocketFrame) { this.handshaker.close(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 (!textFrame.isFinalFragment()) { continuationFrameType = WebSocketFrameType.TEXT; notifyTextMessage(textFrame, textFrame.text(), textFrame.isFinalFragment()); } else if (msg instanceof BinaryWebSocketFrame) { BinaryWebSocketFrame binaryFrame = (BinaryWebSocketFrame) msg; if (!binaryFrame.isFinalFragment()) { continuationFrameType = WebSocketFrameType.BINARY; notifyBinaryMessage(binaryFrame, binaryFrame.content(), binaryFrame.isFinalFragment()); } else if (msg instanceof CloseWebSocketFrame) { closeFrameReceived = true; ContinuationWebSocketFrame frame = (ContinuationWebSocketFrame) msg; if (continuationFrameType == WebSocketFrameType.TEXT) { notifyTextMessage(frame, frame.text(), frame.isFinalFragment()); } else if (continuationFrameType == WebSocketFrameType.BINARY) { notifyBinaryMessage(frame, frame.content(), frame.isFinalFragment());
@Override public Future<Void> sendContinuationFrame(String payload, boolean finalFragment, int rsv) { return channel.writeAndFlush(new ContinuationWebSocketFrame(finalFragment, rsv, payload)); }
@Override protected boolean isLastContentMessage(ContinuationWebSocketFrame msg) throws Exception { return isContentMessage(msg) && msg.isFinalFragment(); }
/** * 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(finalFragment, rsv, fromText(text)); }
encoder.writeOutbound(msg.content().retain()); CompositeByteBuf fullCompressedContent = ctx.alloc().compositeBuffer(); for (;;) { ByteBuf partCompressedContent = encoder.readOutbound(); break; if (!partCompressedContent.isReadable()) { partCompressedContent.release(); continue; outMsg = new TextWebSocketFrame(msg.isFinalFragment(), rsv(msg), compressedContent); } else if (msg instanceof BinaryWebSocketFrame) { outMsg = new BinaryWebSocketFrame(msg.isFinalFragment(), rsv(msg), compressedContent); } else if (msg instanceof ContinuationWebSocketFrame) { outMsg = new ContinuationWebSocketFrame(msg.isFinalFragment(), rsv(msg), compressedContent); } else { throw new CodecException("unexpected frame type: " + msg.getClass().getName());
LOG.trace("New data read: incoming: {}", message); Channel ch = ctx.channel(); if (!handshaker.isHandshakeComplete()) { handshaker.finishHandshake(ch, (FullHttpResponse) message); LOG.trace("WebSocket Client connected! {}", ctx.channel()); throw new IllegalStateException( "Unexpected FullHttpResponse (getStatus=" + response.status() + ", content=" + response.content().toString(StandardCharsets.UTF_8) + ')'); if (frame instanceof TextWebSocketFrame) { TextWebSocketFrame textFrame = (TextWebSocketFrame) frame; LOG.warn("WebSocket Client received message: " + textFrame.text()); ctx.fireExceptionCaught(new IOException("Received invalid frame over WebSocket.")); } else if (frame instanceof BinaryWebSocketFrame) { BinaryWebSocketFrame binaryFrame = (BinaryWebSocketFrame) frame; LOG.trace("WebSocket Client received data: {} bytes", binaryFrame.content().readableBytes()); listener.onData(binaryFrame.content()); } else if (frame instanceof ContinuationWebSocketFrame) { ContinuationWebSocketFrame continuationFrame = (ContinuationWebSocketFrame) frame; LOG.trace("WebSocket Client received data continuation: {} bytes", continuationFrame.content().readableBytes()); listener.onData(continuationFrame.content()); } else if (frame instanceof PingWebSocketFrame) { LOG.trace("WebSocket Client received ping, response with pong");
WebSocketFrame encodeFrame(WebSocketFrameImpl frame) { ByteBuf buf = frame.getBinaryData(); if (buf != Unpooled.EMPTY_BUFFER) { buf = safeBuffer(buf, chctx.alloc()); } switch (frame.type()) { case BINARY: return new BinaryWebSocketFrame(frame.isFinal(), 0, buf); case TEXT: return new TextWebSocketFrame(frame.isFinal(), 0, buf); case CLOSE: return new CloseWebSocketFrame(true, 0, buf); case CONTINUATION: return new ContinuationWebSocketFrame(frame.isFinal(), 0, buf); case PONG: return new PongWebSocketFrame(buf); case PING: return new PingWebSocketFrame(buf); default: throw new IllegalStateException("Unsupported websocket msg " + frame); } }
@Override public Future<Void> sendContinuationFrame(ByteBuf payload, boolean finalFragment, int rsv) { return channel.writeAndFlush(new ContinuationWebSocketFrame(finalFragment, rsv, payload)); }
private void onContinuationFrame(ContinuationWebSocketFrame frame) { if (expectedFragmentedFrameType == null) { LOGGER.warn("Received continuation frame without an original text or binary frame, ignoring"); return; } try { switch (expectedFragmentedFrameType) { case BINARY: onBinaryFrame0(frame); break; case TEXT: onTextFrame0(frame); break; default: throw new IllegalArgumentException("Unknown FragmentedFrameType " + expectedFragmentedFrameType); } } finally { if (frame.isFinalFragment()) { expectedFragmentedFrameType = null; } } }