public void readData(ByteBuf data) { id = data.readShort(); parseData(data.readUnsignedShort(), data.readUnsignedByte()); dX = data.readFloat(); dY = data.readFloat(); dZ = data.readFloat(); }
public RegisterMessage decode(ByteBuf body, int version) { int length = body.readUnsignedShort(); List<Event.Type> eventTypes = new ArrayList<Event.Type>(length); for (int i = 0; i < length; ++i) eventTypes.add(CBUtil.readEnumValue(Event.Type.class, body)); return new RegisterMessage(eventTypes); }
@Override protected void decode(ChannelHandlerContext ctx, ByteBuf byteBuf, List<Object> out) throws Exception { switch (state()) { case CHECK_NULL_BYTE: { if (byteBuf.readByte() != (byte) 0x00) { break; } checkpoint(State.READ_CMD_HEADER); } case READ_CMD_HEADER: { cmdStatus = Socks4CmdStatus.valueOf(byteBuf.readByte()); checkpoint(State.READ_CMD_ADDRESS); } case READ_CMD_ADDRESS: { port = byteBuf.readUnsignedShort(); host = Socks4CommonUtils.intToIp(byteBuf.readInt()); msg = new Socks4CmdResponse(cmdStatus, host, port); } } ctx.pipeline().remove(this); out.add(msg); }
private void readSettingsFrame( ChannelHandlerContext ctx, ByteBuf payload, Http2FrameListener listener) throws Http2Exception { if (flags.ack()) { listener.onSettingsAckRead(ctx); } else { int numSettings = payloadLength / SETTING_ENTRY_LENGTH; Http2Settings settings = new Http2Settings(); for (int index = 0; index < numSettings; ++index) { char id = (char) payload.readUnsignedShort(); long value = payload.readUnsignedInt(); try { settings.put(id, Long.valueOf(value)); } catch (IllegalArgumentException e) { switch (id) { case SETTINGS_MAX_FRAME_SIZE: throw connectionError(FRAME_SIZE_ERROR, e, e.getMessage()); case SETTINGS_INITIAL_WINDOW_SIZE: throw connectionError(FLOW_CONTROL_ERROR, e, e.getMessage()); default: throw connectionError(PROTOCOL_ERROR, e, e.getMessage()); } } } listener.onSettingsRead(ctx, settings); } }
private static void checkHeader(ByteBuf buffer, boolean hasMask) { assertEquals( "Wrong oxm-class", OxmMatchConstants.OPENFLOW_BASIC_CLASS, buffer.readUnsignedShort()); short fieldAndMask = buffer.readUnsignedByte(); assertEquals("Wrong oxm-field", OxmMatchConstants.SCTP_DST, fieldAndMask >>> 1); assertEquals("Wrong hasMask", hasMask, (fieldAndMask & 1) != 0); assertEquals("Wrong length", EncodeConstants.SIZE_OF_SHORT_IN_BYTES, buffer.readUnsignedByte()); }
@Override public HandshakeMessage decode(ByteBuf buf) throws IOException { final int version = ByteBufUtils.readVarInt(buf); final String address = ByteBufUtils.readUTF8(buf); final short port = (short) buf.readUnsignedShort(); final HandshakeState state = HandshakeState.get(ByteBufUtils.readVarInt(buf)); return new HandshakeMessage(version, address, port, state); }
/** * This method will first read an unsigned short to find the length of the string and then read * the actual string based on the length. This method will also reset the reader index to end of * the string * * @param buffer The Netty buffer containing at least one unsigned short followed by a string of * similar length. * @param charset The Charset say 'UTF-8' in which the decoding needs to be done. * @return Returns the String or throws {@link IndexOutOfBoundsException} if the length is greater * than expected. */ public static String readString(ByteBuf buffer, Charset charset) { String readString = null; if (null != buffer && buffer.readableBytes() > 2) { int length = buffer.readUnsignedShort(); readString = readString(buffer, length, charset); } return readString; }
@Override public void decode(ByteBuf data) { byteCount = data.readUnsignedByte(); registers = new int[byteCount / 2]; for (int i = 0; i < registers.length; i++) { registers[i] = data.readUnsignedShort(); } }
private void processHeaderState(ByteBuf in) throws Http2Exception { if (in.readableBytes() < FRAME_HEADER_LENGTH) { // Wait until the entire frame header has been read. return; } // Read the header and prepare the unmarshaller to read the frame. payloadLength = in.readUnsignedShort() & FRAME_LENGTH_MASK; frameType = Http2FrameType.forTypeCode(in.readUnsignedByte()); flags = new Http2Flags(in.readUnsignedByte()); streamId = readUnsignedInt(in); switch (frameType) { case DATA: verifyDataFrame(); break; case HEADERS: verifyHeadersFrame(); break; case PRIORITY: verifyPriorityFrame(); break; case RST_STREAM: verifyRstStreamFrame(); break; case SETTINGS: verifySettingsFrame(); break; case PUSH_PROMISE: verifyPushPromiseFrame(); break; case PING: verifyPingFrame(); break; case GO_AWAY: verifyGoAwayFrame(); break; case WINDOW_UPDATE: verifyWindowUpdateFrame(); break; case CONTINUATION: verifyContinuationFrame(); break; case ALT_SVC: verifyAltSvcFrame(); break; case BLOCKED: verifyBlockedFrame(); break; default: throw protocolError("Unsupported frame type: %s", frameType); } // Start reading the payload for the frame. state = State.FRAME_PAYLOAD; }
@Override public GetQueueConfigOutput deserialize(ByteBuf rawMessage) { GetQueueConfigOutputBuilder builder = new GetQueueConfigOutputBuilder(); builder.setVersion((short) EncodeConstants.OF10_VERSION_ID); builder.setXid((rawMessage.readUnsignedInt())); builder.setPort(new PortNumber((long) rawMessage.readUnsignedShort())); rawMessage.skipBytes(PADDING_IN_QUEUE_GET_CONFIG_REPLY_HEADER); builder.setQueues(createQueuesList(rawMessage)); return builder.build(); }
private static List<QueueProperty> createPropertiesList(ByteBuf input, int length) { int propertiesLength = length; List<QueueProperty> propertiesList = new ArrayList<>(); while (propertiesLength > 0) { QueuePropertyBuilder propertiesBuilder = new QueuePropertyBuilder(); QueueProperties property = QueueProperties.forValue(input.readUnsignedShort()); propertiesBuilder.setProperty(property); propertiesLength -= input.readUnsignedShort(); input.skipBytes(PADDING_IN_QUEUE_PROPERTY_HEADER); if (property.equals(QueueProperties.OFPQTMINRATE)) { RateQueuePropertyBuilder rateBuilder = new RateQueuePropertyBuilder(); rateBuilder.setRate(input.readUnsignedShort()); propertiesBuilder.addAugmentation(RateQueueProperty.class, rateBuilder.build()); input.skipBytes(PADDING_IN_RATE_QUEUE_PROPERTY); } propertiesList.add(propertiesBuilder.build()); } return propertiesList; }
/** Test correct serialization */ @Test public void testSerialize() { MatchEntryBuilder builder = prepareMatchEntry(4096); ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); serializer.serialize(builder.build(), buffer); checkHeader(buffer, false); assertEquals("Wrong value", 4096, buffer.readUnsignedShort()); assertTrue("Unexpected data", buffer.readableBytes() == 0); }
@Override public Tlv parseTlv(final ByteBuf buffer) throws BmpDeserializationException { if (buffer == null) { return null; } return new PerAfiSafiLocRibTlvBuilder() .setAfi(this.afiRegistry.classForFamily(buffer.readUnsignedShort())) .setSafi(this.safiRegistry.classForFamily(buffer.readUnsignedByte())) .setCount(new Gauge64(new BigInteger(ByteArray.readAllBytes(buffer)))) .build(); }
public static int readVarShort(ByteBuf buf) { int low = buf.readUnsignedShort(); int high = 0; if ((low & 0x8000) != 0) { low = low & 0x7FFF; high = buf.readUnsignedByte(); } return ((high & 0xFF) << 15) | low; }
int decode(ByteBuf buf) { // ByteBuf bbuf = Unpooled.wrappedBuffer(buf); // ByteBuf tmpbuf = bbuf.readerIndex(pos); this.msgType = buf.readUnsignedInt(); this.seqNo = buf.readUnsignedByte(); this.msgLen = buf.readUnsignedShort(); this.flags = buf.readUnsignedByte(); return 0; }
private static List<Queues> createQueuesList(ByteBuf input) { List<Queues> queuesList = new ArrayList<>(); while (input.readableBytes() > 0) { QueuesBuilder queueBuilder = new QueuesBuilder(); queueBuilder.setQueueId(new QueueId(input.readUnsignedInt())); int length = input.readUnsignedShort(); input.skipBytes(PADDING_IN_PACKET_QUEUE_HEADER); queueBuilder.setQueueProperty( createPropertiesList(input, length - PACKET_QUEUE_HEADER_LENGTH)); queuesList.add(queueBuilder.build()); } return queuesList; }
@Test public void testEncode() { MockRelayMessage message = new MockRelayMessage(); message.code(Unsigned16.get(100)); message.length(Unsigned32.get(36L)); message.flag(new FlagData(FlagImpl.REQUEST)); message.hopByHop(Integer64.get(1L)); message.endToEnd(Integer64.get(2L)); message.addAttribute(new IgnoredAttribute(new IgnoredData(new byte[] {1, 2, 3, 4}))); ByteBuf buf = MessageFactory.getInstance().generateByteBuf(message); Assert.assertEquals(message.version().get().byteValue(), buf.readUnsignedByte()); Assert.assertEquals(message.code().get().intValue(), buf.readUnsignedShort()); assertEquals(64, buf.readUnsignedByte()); Assert.assertEquals(message.length().get().intValue(), buf.readUnsignedInt()); assertEquals(message.hopByHop().get().longValue(), buf.readLong()); assertEquals(message.endToEnd().get().longValue(), buf.readLong()); assertEquals(0, buf.readUnsignedShort()); assertEquals(4, buf.readUnsignedInt()); assertEquals(1, buf.readByte()); assertEquals(2, buf.readByte()); assertEquals(3, buf.readByte()); assertEquals(4, buf.readByte()); }
/** * Load a string from the given buffer, reading first the two bytes of len and then the UTF-8 * bytes of the string. * * @return the decoded string or null if NEED_DATA */ static String decodeString(ByteBuf in) throws UnsupportedEncodingException { if (in.readableBytes() < 2) { return null; } // int strLen = Utils.readWord(in); int strLen = in.readUnsignedShort(); if (in.readableBytes() < strLen) { return null; } byte[] strRaw = new byte[strLen]; in.readBytes(strRaw); return new String(strRaw, "UTF-8"); }
public static <T, V> V readObject(ByteBuf buffer, Transform<ByteBuf, V> decoder) { int length = 0; if (null != buffer && buffer.readableBytes() > 2) { length = buffer.readUnsignedShort(); } else { return null; } ByteBuf objBuffer = buffer.readSlice(length); V obj = null; try { obj = decoder.convert(objBuffer); } catch (Exception e) { LOG.error("Error occurred while trying to read object from buffer: {}", e); } return obj; }
@Override public void receiveCommand(String command, Side side, Object sender, ByteBuf stream) { super.receiveCommand(command, side, sender, stream); if (side.isClient()) { if ("clearItemRequirements".equals(command)) { requiredToBuild = null; } else if ("setItemRequirements".equals(command)) { int size = stream.readUnsignedMedium(); requiredToBuild = new ArrayList<RequirementItemStack>(); for (int i = 0; i < size; i++) { int itemId = stream.readUnsignedShort(); int itemDamage = stream.readShort(); int stackSize = stream.readUnsignedMedium(); boolean hasCompound = stackSize >= 0x800000; ItemStack stack = new ItemStack(Item.getItemById(itemId), 1, itemDamage); if (hasCompound) { stack.setTagCompound(NetworkUtils.readNBT(stream)); } if (stack != null && stack.getItem() != null) { requiredToBuild.add(new RequirementItemStack(stack, stackSize & 0x7FFFFF)); } else { BCLog.logger.error( "Corrupt ItemStack in TileBuilder.receiveCommand! This should not happen! (ID " + itemId + ", damage " + itemDamage + ")"); } } } } else if (side.isServer()) { EntityPlayer player = (EntityPlayer) sender; if ("eraseFluidTank".equals(command)) { int id = stream.readInt(); if (id < 0 || id >= fluidTanks.length) { return; } if (isUseableByPlayer(player) && player.getDistanceSq(xCoord, yCoord, zCoord) <= 64) { fluidTanks[id].setFluid(null); sendNetworkUpdate(); } } } }
private void readAltSvcFrame( ChannelHandlerContext ctx, ByteBuf payload, Http2FrameObserver observer) throws Http2Exception { long maxAge = payload.readUnsignedInt(); int port = payload.readUnsignedShort(); payload.skipBytes(1); short protocolIdLength = payload.readUnsignedByte(); ByteBuf protocolId = payload.readSlice(protocolIdLength); short hostLength = payload.readUnsignedByte(); String host = payload.toString(payload.readerIndex(), hostLength, UTF_8); payload.skipBytes(hostLength); String origin = null; if (payload.isReadable()) { origin = payload.toString(UTF_8); payload.skipBytes(payload.readableBytes()); } observer.onAltSvcRead(ctx, streamId, maxAge, port, protocolId, host, origin); }
@Override public SubobjectContainer parseSubobject(final ByteBuf buffer) throws RSVPParsingException { Preconditions.checkArgument( buffer != null && buffer.isReadable(), "Array of bytes is mandatory. Can't be null or empty."); if (buffer.readableBytes() != CONTENT_LENGTH) { throw new RSVPParsingException( "Wrong length of array of bytes. Passed: " + buffer.readableBytes() + "; Expected: >" + CONTENT_LENGTH + "."); } final int pathKey = buffer.readUnsignedShort(); final byte[] pceId = ByteArray.readBytes(buffer, PCE_ID_F_LENGTH); final SubobjectContainerBuilder builder = new SubobjectContainerBuilder(); final PathKeyBuilder pBuilder = new PathKeyBuilder(); pBuilder.setPceId(new PceId(pceId)); pBuilder.setPathKey(new PathKey(pathKey)); builder.setSubobjectType(new PathKeyCaseBuilder().setPathKey(pBuilder.build()).build()); return builder.build(); }
@Override protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception { int available = in.readableBytes(); if (available == 0) { return; } do { if (packetType == -1 && available >= 1) { packetType = in.readByte() - cipher.nextInt() & 0xff; packetSize = protocol.getInboundPacketSize(packetType); available--; } if (packetSize == -1) { if (available >= 1) { packetSize = in.readUnsignedByte(); available--; } else { return; } } else if (packetSize == -2) { if (available >= 2) { packetSize = in.readUnsignedShort(); available -= 2; } else { return; } } if (available < packetSize) { return; } byte[] data = new byte[packetSize]; in.readBytes(data); out.add(new GamePacket(packetType, data)); available -= packetSize; packetType = -1; } while (available > 0); }
@Override protected Object decode(ChannelHandlerContext ctx, ByteBuf buffer) throws Exception { if (result == null) { ByteBuf frame = (ByteBuf) super.decode(ctx, buffer); if (frame == null) { return null; } CompactObjectInputStream cois = new CompactObjectInputStream(new ByteBufInputStream(frame), classLoader); result = cois.readObject(); streams = ExternalizeUtil.readList(cois, StreamFactoryReference.class); streamIndex = 0; } while (streamIndex < streams.size()) { // read the new chunk size if (streamDataToRead == -1) { if (buffer.readableBytes() < 2) { return null; } streamDataToRead = buffer.readUnsignedShort(); } if (stream == null) { store = storageManager.createFileStore("temp-stream"); // $NON-NLS-1$ StreamFactoryReference sfr = streams.get(streamIndex); sfr.setStreamFactory(new FileStoreInputStreamFactory(store, Streamable.ENCODING)); this.stream = new BufferedOutputStream(store.createOutputStream()); } // end of stream if (streamDataToRead == 0) { stream.close(); stream = null; streamIndex++; streamDataToRead = -1; continue; } if (store.getLength() + streamDataToRead > maxLobSize) { if (error == null) { error = new StreamCorruptedException( "lob too big: " + (store.getLength() + streamDataToRead) + " (max: " + maxLobSize + ')'); //$NON-NLS-1$ //$NON-NLS-2$ } } if (error == null) { int toRead = Math.min(buffer.readableBytes(), streamDataToRead); if (toRead == 0) { return null; } buffer.readBytes(this.stream, toRead); streamDataToRead -= toRead; if (streamDataToRead == 0) { // get the next chunk streamDataToRead = -1; } } else { buffer.release(); streamDataToRead = -1; break; } } Object toReturn = result; result = null; streams = null; stream = null; store = null; if (error != null) { StreamCorruptedException sce = error; error = null; throw sce; } return toReturn; }
@Override public ExtendedCommunities parseExtendedCommunity( final ReferenceCache refCache, final ExtendedCommunitiesBuilder comm, final ByteBuf buffer) throws BGPDocumentedException { ExtendedCommunity c = null; if (comm.getCommType().equals(FS_TYPE)) { switch (comm.getCommSubType()) { case TRAFFIC_RATE_SUBTYPE: final ShortAsNumber as = new ShortAsNumber((long) buffer.readUnsignedShort()); final Bandwidth value = new Bandwidth(ByteArray.readBytes(buffer, TRAFFIC_RATE_SIZE)); c = new TrafficRateExtendedCommunityCaseBuilder() .setTrafficRateExtendedCommunity( new TrafficRateExtendedCommunityBuilder() .setInformativeAs(as) .setLocalAdministrator(value) .build()) .build(); break; case TRAFFIC_ACTION_SUBTYPE: buffer.skipBytes(RESERVED); final BitArray flags = BitArray.valueOf(buffer, FLAGS_SIZE); final boolean sample = flags.get(SAMPLE_BIT); final boolean terminal = flags.get(TERMINAL_BIT); c = new TrafficActionExtendedCommunityCaseBuilder() .setTrafficActionExtendedCommunity( new TrafficActionExtendedCommunityBuilder() .setSample(sample) .setTerminalAction(terminal) .build()) .build(); break; case REDIRECT_SUBTYPE: final ShortAsNumber as1 = new ShortAsNumber((long) buffer.readUnsignedShort()); final byte[] byteValue = ByteArray.readBytes(buffer, TRAFFIC_RATE_SIZE); c = new RedirectExtendedCommunityCaseBuilder() .setRedirectExtendedCommunity( new RedirectExtendedCommunityBuilder() .setGlobalAdministrator(as1) .setLocalAdministrator(byteValue) .build()) .build(); break; case TRAFFIC_MARKING_SUBTYPE: buffer.skipBytes(RESERVED); final Dscp dscp = new Dscp(buffer.readUnsignedByte()); c = new TrafficMarkingExtendedCommunityCaseBuilder() .setTrafficMarkingExtendedCommunity( new TrafficMarkingExtendedCommunityBuilder() .setGlobalAdministrator(dscp) .build()) .build(); break; default: throw new BGPDocumentedException( "Could not parse Flowspec Extended Community type: " + comm.getCommSubType(), BGPError.OPT_ATTR_ERROR); } } if (c == null) { LOG.debug("Extended community is not from Flowspec, fallback to original communities."); return super.parseExtendedCommunity(refCache, comm, buffer); } return comm.setExtendedCommunity(c).build(); }
@Override public Object decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception { // Discard all data received if closing handshake was received before. if (receivedClosingHandshake) { in.skipBytes(actualReadableBytes()); return null; } switch (state()) { case FRAME_START: framePayloadBytesRead = 0; framePayloadLength = -1; framePayload = null; // FIN, RSV, OPCODE byte b = in.readByte(); frameFinalFlag = (b & 0x80) != 0; frameRsv = (b & 0x70) >> 4; frameOpcode = b & 0x0F; if (logger.isDebugEnabled()) { logger.debug("Decoding WebSocket Frame opCode={}", frameOpcode); } // MASK, PAYLOAD LEN 1 b = in.readByte(); boolean frameMasked = (b & 0x80) != 0; int framePayloadLen1 = b & 0x7F; if (frameRsv != 0 && !allowExtensions) { protocolViolation(ctx, "RSV != 0 and no extension negotiated, RSV:" + frameRsv); return null; } if (maskedPayload && !frameMasked) { protocolViolation(ctx, "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(ctx, "fragmented control frame"); return null; } // control frames MUST have payload 125 octets or less if (framePayloadLen1 > 125) { protocolViolation(ctx, "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(ctx, "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 getStatus code if (frameOpcode == 8 && framePayloadLen1 == 1) { protocolViolation(ctx, "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(ctx, "data frame using reserved opcode " + frameOpcode); return null; } // check opcode vs message fragmentation state 1/2 if (fragmentedFramesCount == 0 && frameOpcode == OPCODE_CONT) { protocolViolation(ctx, "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( ctx, "received non-continuation data frame while inside fragmented message"); return null; } } // Read frame payload length if (framePayloadLen1 == 126) { framePayloadLength = in.readUnsignedShort(); if (framePayloadLength < 126) { protocolViolation(ctx, "invalid data frame length (not using minimal length encoding)"); return null; } } else if (framePayloadLen1 == 127) { framePayloadLength = in.readLong(); // TODO: check if it's bigger than 0x7FFFFFFFFFFFFFFF, Maybe // just check if it's negative? if (framePayloadLength < 65536) { protocolViolation(ctx, "invalid data frame length (not using minimal length encoding)"); return null; } } else { framePayloadLength = framePayloadLen1; } if (framePayloadLength > maxFramePayloadLength) { protocolViolation( ctx, "Max frame length of " + maxFramePayloadLength + " has been exceeded."); return null; } if (logger.isDebugEnabled()) { logger.debug("Decoding WebSocket Frame length={}", framePayloadLength); } checkpoint(State.MASKING_KEY); case MASKING_KEY: if (maskedPayload) { maskingKey = in.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(); ByteBuf payloadBuffer = null; long 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 = ctx.alloc().buffer(rbytes); payloadBuffer.writeBytes(in, rbytes); } else if (willHaveReadByteCount < framePayloadLength) { // We don't have all our content so accumulate payload. // Returning null means we will get called back if (framePayload == null) { framePayload = ctx.alloc().buffer(toFrameLength(framePayloadLength)); } framePayload.writeBytes(in, rbytes); 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 if (framePayload == null) { framePayload = ctx.alloc().buffer(toFrameLength(framePayloadLength)); } framePayload.writeBytes(in, toFrameLength(framePayloadLength - framePayloadBytesRead)); } // 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 if (payloadBuffer != null) { framePayload.writeBytes(payloadBuffer); } // Unmask data if needed if (maskedPayload) { unmask(framePayload); } // Processing ping/pong/close frames because they cannot be // fragmented if (frameOpcode == OPCODE_PING) { return new PingWebSocketFrame(frameFinalFlag, frameRsv, framePayload); } if (frameOpcode == OPCODE_PONG) { return new PongWebSocketFrame(frameFinalFlag, frameRsv, framePayload); } if (frameOpcode == OPCODE_CLOSE) { checkCloseFrameBody(ctx, framePayload); receivedClosingHandshake = true; return new CloseWebSocketFrame(frameFinalFlag, frameRsv, framePayload); } // 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(ctx, framePayload); // 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(ctx, framePayload); } } else { // Subsequent frames - only check if init frame is text if (fragmentedFramesText != null) { checkUTF8String(ctx, framePayload); } } // 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. in.readByte(); return null; default: throw new Error("Shouldn't reach here."); } }
@Override Integer read(ByteBuf buf) { return buf.readUnsignedShort(); }
@Override public int readUInt16() { return buf.readUnsignedShort(); }
@Override public int readUnsignedShort() { return buffer.readUnsignedShort(); }
@Override public void channelRead(final ChannelHandlerContext ctx, final Object inputObj) throws Exception { try { final ByteBuf input = (ByteBuf) inputObj; if (!input.isReadable()) { return; } final Channel channel = ctx.channel(); receivedData.writeBytes(input); ProtocolVersion handshakeversion = ProtocolVersion.NOT_SET; receivedData.readerIndex(0); int firstbyte = receivedData.readUnsignedByte(); switch (firstbyte) { case 0xFE: { // old ping try { if (receivedData.readableBytes() == 0) { // really old protocol probably scheduleTask(ctx, new Ping11ResponseTask(channel), 1000, TimeUnit.MILLISECONDS); } else if (receivedData.readUnsignedByte() == 1) { if (receivedData.readableBytes() == 0) { // 1.5.2 probably scheduleTask( ctx, new Ping152ResponseTask(this, channel), 500, TimeUnit.MILLISECONDS); } else if ((receivedData.readUnsignedByte() == 0xFA) && "MC|PingHost" .equals( new String( Utils.toArray( receivedData.readBytes(receivedData.readUnsignedShort() * 2)), StandardCharsets.UTF_16BE))) { // 1.6.* receivedData.readUnsignedShort(); handshakeversion = ProtocolVersion.fromId(receivedData.readUnsignedByte()); } } } catch (IndexOutOfBoundsException ex) { } break; } case 0x02: { // 1.6 or 1.5.2 handshake try { handshakeversion = ProtocolVersion.fromId(receivedData.readUnsignedByte()); } catch (IndexOutOfBoundsException ex) { } break; } default: { // 1.7 or 1.8 handshake receivedData.readerIndex(0); ByteBuf data = getVarIntPrefixedData(receivedData); if (data != null) { handshakeversion = readNPHandshake(data); } break; } } // if we detected the protocol than we save it and process data if (handshakeversion != ProtocolVersion.NOT_SET) { setProtocol(channel, receivedData, handshakeversion); } } catch (Throwable t) { ctx.channel().close(); } finally { ReferenceCountUtil.release(inputObj); } }