private boolean handleCompressedFrame(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception { if (!in.isReadable(FRAME_COMPRESS_HEADER_LENGTH)) { return false; } int compressedPayloadLength = in.readInt(); if (!in.isReadable(compressedPayloadLength)) { return false; } // decompress payload Inflater inflater = new Inflater(); if (in.hasArray()) { inflater.setInput(in.array(), in.arrayOffset() + in.readerIndex(), compressedPayloadLength); in.skipBytes(compressedPayloadLength); } else { byte[] array = new byte[compressedPayloadLength]; in.readBytes(array); inflater.setInput(array); } while (!inflater.finished()) { ByteBuf decompressed = ctx.alloc().heapBuffer(1024, 1024); byte[] outArray = decompressed.array(); int count = inflater.inflate(outArray, decompressed.arrayOffset(), decompressed.writableBytes()); decompressed.writerIndex(count); // put data in the pipeline out.add(decompressed); } return true; }
/** * Read a string that is prefixed by its length encoded by a 4 bytes integer. * * @param in the buffer to consume * @return the read string or {@code null} if not enough data available to read the whole string */ private String readLengthPrefixedString(ByteBuf in) { if (!in.isReadable(INT_LENGTH)) { return null; } int length = in.readInt(); if (!in.isReadable(length)) { return null; } String str = in.toString(in.readerIndex(), length, StandardCharsets.UTF_8); in.skipBytes(length); return str; }
/** * This test makes sure that even when the decoder is confronted with various chunk sizes in the * middle of decoding, it can recover and decode all the time eventually. */ @Test public void shouldHandleNonUniformNetworkBatches() { ByteBuf incoming = Unpooled.copiedBuffer(SET_REQUEST_WITH_CONTENT); while (incoming.isReadable()) { channel.writeInbound(incoming.readBytes(5)); } BinaryMemcacheRequest request = (BinaryMemcacheRequest) channel.readInbound(); assertThat(request, notNullValue()); assertThat(request.getHeader(), notNullValue()); assertThat(request.getKey(), notNullValue()); assertThat(request.getExtras(), nullValue()); request.release(); MemcacheContent content1 = (MemcacheContent) channel.readInbound(); MemcacheContent content2 = (MemcacheContent) channel.readInbound(); assertThat(content1, instanceOf(MemcacheContent.class)); assertThat(content2, instanceOf(LastMemcacheContent.class)); assertThat(content1.content().readableBytes(), is(3)); assertThat(content2.content().readableBytes(), is(5)); content1.release(); content2.release(); }
/** * Converts the specified Netty {@link ByteBuf} into an {@link HttpData}. Unlike {@link * #of(byte[])}, this method makes a copy of the {@link ByteBuf}. * * @return a new {@link HttpData}. {@link #EMPTY_DATA} if the readable bytes of {@code buf} is 0. */ static HttpData of(ByteBuf buf) { requireNonNull(buf, "buf"); if (!buf.isReadable()) { return EMPTY_DATA; } return of(ByteBufUtil.getBytes(buf)); }
@Override public void flush() throws IOException { if (buf.isReadable()) { writeToChannel(); } chc.flush(); }
@Override public Subobject parseSubobject(final ByteBuf buffer, final boolean loose) throws PCEPDeserializerException { Preconditions.checkArgument( buffer != null && buffer.isReadable(), "Array of bytes is mandatory. Can't be null or empty."); if (buffer.readableBytes() < HEADER_LENGTH) { throw new PCEPDeserializerException( "Wrong length of array of bytes. Passed: " + buffer.readableBytes() + "; Expected: >" + HEADER_LENGTH + "."); } final BitArray reserved = BitArray.valueOf(buffer, FLAGS_SIZE); final short cType = buffer.readUnsignedByte(); final LabelType labelType = this.registry.parseLabel(cType, buffer.slice()); if (labelType == null) { throw new PCEPDeserializerException( "Unknown C-TYPE for ero label subobject. Passed: " + cType); } final LabelBuilder builder = new LabelBuilder(); builder.setUniDirectional(reserved.get(U_FLAG_OFFSET)); builder.setLabelType(labelType); return new SubobjectBuilder() .setLoose(loose) .setSubobjectType(new LabelCaseBuilder().setLabel(builder.build()).build()) .build(); }
@Override protected int doWrite(MessageList<Object> msgs, int index) throws Exception { int size = msgs.size(); int writeIndex = index; for (; ; ) { if (writeIndex >= size) { break; } Object msg = msgs.get(writeIndex); if (msg instanceof ByteBuf) { ByteBuf buf = (ByteBuf) msg; while (buf.isReadable()) { doWriteBytes(buf); } buf.release(); writeIndex++; } else if (msg instanceof FileRegion) { FileRegion region = (FileRegion) msg; doWriteFileRegion(region); region.release(); writeIndex++; } else { throw new UnsupportedOperationException( "unsupported message type: " + StringUtil.simpleClassName(msg)); } } return writeIndex - index; }
private Object[] encodeContent(HttpMessage header, HttpContent c) { ByteBuf newContent = Unpooled.buffer(); ByteBuf content = c.data(); encode(content, newContent); if (c instanceof LastHttpContent) { ByteBuf lastProduct = Unpooled.buffer(); finishEncode(lastProduct); // Generate an additional chunk if the decoder produced // the last product on closure, if (lastProduct.isReadable()) { if (header == null) { return new Object[] { new DefaultHttpContent(newContent), new DefaultLastHttpContent(lastProduct) }; } else { return new Object[] { header, new DefaultHttpContent(newContent), new DefaultLastHttpContent(lastProduct) }; } } } if (header == null) { return new Object[] {new DefaultHttpContent(newContent)}; } else { return new Object[] {header, new DefaultHttpContent(newContent)}; } }
@Override public void split(ChannelHandlerContext ctx, ByteBuf input, List<Object> list) throws Exception { input.markReaderIndex(); final byte[] array = new byte[3]; for (int i = 0; i < array.length; ++i) { if (!input.isReadable()) { input.resetReaderIndex(); return; } array[i] = input.readByte(); if (array[i] >= 0) { final PacketDataSerializer packetDataSerializer = new PacketDataSerializer( Unpooled.wrappedBuffer(array), ProtocolVersion.MINECRAFT_1_7_10); try { final int length = packetDataSerializer.readVarInt(); if (input.readableBytes() < length) { input.resetReaderIndex(); return; } list.add(input.readBytes(length)); return; } finally { packetDataSerializer.release(); } } } throw new CorruptedFrameException("length wider than 21-bit"); }
/** * Reads the content of the entry into a new buffer. Use {@link #readContent(ByteBufAllocator, * InputStream, int)} when the length of the stream is known. */ protected ByteBuf readContent(ByteBufAllocator alloc, InputStream in) throws IOException { ByteBuf buf = null; boolean success = false; try { buf = alloc.directBuffer(); for (; ; ) { if (buf.writeBytes(in, 8192) < 0) { break; } } success = true; if (buf.isReadable()) { return buf; } else { buf.release(); return Unpooled.EMPTY_BUFFER; } } finally { if (!success && buf != null) { buf.release(); } } }
protected void checkCloseFrameBody(ChannelHandlerContext ctx, ByteBuf buffer) { if (buffer == null || buffer.capacity() == 0) { return; } if (buffer.capacity() == 1) { protocolViolation(ctx, "Invalid close frame body"); } // Save reader index int idx = buffer.readerIndex(); buffer.readerIndex(0); // Must have 2 byte integer within the valid range int statusCode = buffer.readShort(); if (statusCode >= 0 && statusCode <= 999 || statusCode >= 1004 && statusCode <= 1006 || statusCode >= 1012 && statusCode <= 2999) { protocolViolation(ctx, "Invalid close frame getStatus code: " + statusCode); } // May have UTF-8 message if (buffer.isReadable()) { try { new UTF8Output(buffer); } catch (UTF8Exception ex) { protocolViolation(ctx, "Invalid close frame reason text. Invalid UTF-8 bytes"); } } // Restore reader index buffer.readerIndex(idx); }
/** * Decodes the client connection preface string from the input buffer. * * @return {@code true} if processing of the client preface string is complete. Since client * preface strings can only be received by servers, returns true immediately for client * endpoints. */ private boolean readClientPrefaceString(ByteBuf in) throws Http2Exception { if (clientPrefaceString == null) { return true; } int prefaceRemaining = clientPrefaceString.readableBytes(); int bytesRead = min(in.readableBytes(), prefaceRemaining); // If the input so far doesn't match the preface, break the connection. if (bytesRead == 0 || !ByteBufUtil.equals( in, in.readerIndex(), clientPrefaceString, clientPrefaceString.readerIndex(), bytesRead)) { String receivedBytes = hexDump( in, in.readerIndex(), min(in.readableBytes(), clientPrefaceString.readableBytes())); throw connectionError( PROTOCOL_ERROR, "HTTP/2 client preface string missing or corrupt. " + "Hex dump for received bytes: %s", receivedBytes); } in.skipBytes(bytesRead); clientPrefaceString.skipBytes(bytesRead); if (!clientPrefaceString.isReadable()) { // Entire preface has been read. clientPrefaceString.release(); clientPrefaceString = null; return true; } return false; }
private boolean handleDataFrame(ByteBuf in, List<Object> out) { if (!in.isReadable(FRAME_DATA_HEADER_LENGTH)) { return false; } int sequenceNumber = in.readInt(); int entriesCount = in.readInt(); Map<String, String> dataMessage = new LinkedHashMap<>(); while (entriesCount-- > 0) { String key = readLengthPrefixedString(in); if (key == null) { return false; } String value = readLengthPrefixedString(in); if (value == null) { return false; } dataMessage.put(key, value); } out.add(new LumberjackMessage(sequenceNumber, dataMessage)); return true; }
@Override protected void channelRead0(ChannelHandlerContext ctx, FullHttpResponse msg) throws Exception { Integer streamId = msg.headers().getInt(HttpConversionUtil.ExtensionHeaderNames.STREAM_ID.text()); if (streamId == null) { logger.error("HttpResponseHandler unexpected message received: " + msg); return; } onResponseReceived(ctx, streamIdUrlMap.get(streamId)); Map.Entry<ChannelFuture, ChannelPromise> entry = streamIdPromiseMap.get(streamId); if (entry == null) { logger.error("Message received for unknown stream id " + streamId); } else { // Do stuff with the message (for now just print it) ByteBuf content = msg.content(); ContentType contentType = ContentType.parse(msg.headers().get(HttpHeaderNames.CONTENT_TYPE)); if (content.isReadable()) { int contentLength = content.readableBytes(); byte[] arr = new byte[contentLength]; content.readBytes(arr); handleContent(arr, ctx, contentType); } entry.getValue().setSuccess(); } }
private void wrap(ChannelHandlerContext ctx, boolean inUnwrap) throws SSLException { ByteBuf out = null; ChannelPromise promise = null; ByteBufAllocator alloc = ctx.alloc(); try { for (; ; ) { Object msg = pendingUnencryptedWrites.current(); if (msg == null) { break; } ByteBuf buf = (ByteBuf) msg; if (out == null) { out = allocateOutNetBuf(ctx, buf.readableBytes()); } SSLEngineResult result = wrap(alloc, engine, buf, out); if (!buf.isReadable()) { promise = pendingUnencryptedWrites.remove(); } else { promise = null; } if (result.getStatus() == Status.CLOSED) { // SSLEngine has been closed already. // Any further write attempts should be denied. pendingUnencryptedWrites.removeAndFailAll(SSLENGINE_CLOSED); return; } else { switch (result.getHandshakeStatus()) { case NEED_TASK: runDelegatedTasks(); break; case FINISHED: setHandshakeSuccess(); // deliberate fall-through case NOT_HANDSHAKING: setHandshakeSuccessIfStillHandshaking(); // deliberate fall-through case NEED_WRAP: finishWrap(ctx, out, promise, inUnwrap); promise = null; out = null; break; case NEED_UNWRAP: return; default: throw new IllegalStateException( "Unknown handshake status: " + result.getHandshakeStatus()); } } } } catch (SSLException e) { setHandshakeFailure(ctx, e); throw e; } finally { finishWrap(ctx, out, promise, inUnwrap); } }
private boolean handleWindowFrame(ByteBuf in) { if (!in.isReadable(FRAME_WINDOW_HEADER_LENGTH)) { return false; } // update window size sessionHandler.windowSizeRead(in.readInt()); return true; }
public DestroyAllIdentificator(ByteBuf pBuf, int pTargetOrMeta, int pChainOrMeta) { this(); // Target if (pBuf.isReadable(4)) { for (int li = pBuf.readInt(); li > 0; li--) { add(pBuf.readInt(), pBuf.readByte() | pTargetOrMeta); } } // Chain if (pBuf.isReadable(4)) { int li = pBuf.readInt(); if (li > 0) { chain = new DestroyAllIdentificator(); for (; li > 0; li--) { chain.add(pBuf.readInt(), pBuf.readByte() | pChainOrMeta); } } } }
private void write(ByteBuf buff, boolean end) { int readableBytes = buff.readableBytes(); if (readableBytes == 0 && !end) { // nothing to write to the connection just return return; } if (end) { completed = true; } if (!end && !chunked && !contentLengthSet()) { throw new IllegalStateException( "You must set the Content-Length header to be the total size of the message " + "body BEFORE sending any data if you are not using HTTP chunked encoding."); } written += buff.readableBytes(); if (conn == null) { if (pendingChunks == null) { pendingChunks = buff; } else { CompositeByteBuf pending; if (pendingChunks instanceof CompositeByteBuf) { pending = (CompositeByteBuf) pendingChunks; } else { pending = Unpooled.compositeBuffer(); pending.addComponent(pendingChunks).writerIndex(pendingChunks.writerIndex()); pendingChunks = pending; } pending.addComponent(buff).writerIndex(pending.writerIndex() + buff.writerIndex()); } connect(); } else { if (!headWritten) { writeHeadWithContent(buff, end); } else { if (end) { if (buff.isReadable()) { conn.writeToChannel(new DefaultLastHttpContent(buff, false)); } else { conn.writeToChannel(LastHttpContent.EMPTY_LAST_CONTENT); } } else { conn.writeToChannel(new DefaultHttpContent(buff)); } } if (end) { conn.reportBytesWritten(written); if (respHandler != null) { conn.endRequest(); } } } }
/** * Calls {@link SSLEngine#unwrap(ByteBuffer, ByteBuffer)} with an empty buffer to handle * handshakes, etc. */ private void unwrapNonApp(ChannelHandlerContext ctx) throws SSLException { try { unwrapSingle(ctx, Unpooled.EMPTY_BUFFER.nioBuffer(), 0); } finally { ByteBuf decodeOut = this.decodeOut; if (decodeOut != null && decodeOut.isReadable()) { this.decodeOut = null; ctx.fireChannelRead(decodeOut); } } }
@Override public void fromBytes(ByteBuf buf) { dimension = ByteBufUtils.readVarInt(buf, 5); key = BoundingBoxDeserializer.deserialize(buf); boundingBoxes = new HashSet<BoundingBox>(); while (buf.isReadable()) { BoundingBox boundingBox = BoundingBoxDeserializer.deserialize(buf); boundingBoxes.add(boundingBox); } if (boundingBoxes.size() == 0) boundingBoxes.add(key); }
@Test public void testDummyIncomingAck() { ByteBuf expectResult = Unpooled.wrappedBuffer(new byte[] {(byte) 0x82, 0x00, 0x00}); ch.writeOutbound(UsnMessageHelper.makeDummyIncomingAck()); ByteBuf outBuff = (ByteBuf) ch.readOutbound(); while (expectResult.isReadable()) { assertEquals(expectResult.readUnsignedByte(), outBuff.readUnsignedByte()); } }
private static void parseHeaders(@NotNull HttpResponse response, @NotNull ByteBuf buffer) { StringBuilder builder = new StringBuilder(); while (buffer.isReadable()) { builder.setLength(0); String key = null; boolean valueExpected = true; while (true) { int b = buffer.readByte(); if (b < 0 || b == '\n') { break; } if (b != '\r') { if (valueExpected && b == ':') { valueExpected = false; key = builder.toString(); builder.setLength(0); MessageDecoder.skipWhitespace(buffer); } else { builder.append((char) b); } } } if (builder.length() == 0) { // end of headers return; } // skip standard headers if (StringUtil.isEmpty(key) || StringUtilRt.startsWithIgnoreCase(key, "http") || StringUtilRt.startsWithIgnoreCase(key, "X-Accel-")) { continue; } String value = builder.toString(); if (key.equalsIgnoreCase("status")) { int index = value.indexOf(' '); if (index == -1) { LOG.warn("Cannot parse status: " + value); response.setStatus(HttpResponseStatus.OK); } else { response.setStatus( HttpResponseStatus.valueOf(Integer.parseInt(value.substring(0, index)))); } } else if (!(key.startsWith("http") || key.startsWith("HTTP"))) { response.headers().add(key, value); } } }
@Override public void channelRead(ChannelHandlerContext ctx, Object msg) { // (2) ByteBuf in = (ByteBuf) msg; try { while (in.isReadable()) { // (1) System.out.print((char) in.readByte()); System.out.flush(); } } finally { ReferenceCountUtil.release(msg); // (2) } }
@Override public ByteBuf translateFrame(ByteBuf readBuffer) throws LimitExedeedException, InvalidDataException { while (readBuffer.isReadable()) { switch (status) { case STATUS_H: h = readBuffer.readByte(); status = STATUS_L; break; case STATUS_L: l = readBuffer.readByte(); final int blen = Protocol.order == ByteOrder.BIG_ENDIAN ? (0x0000ff00 & (h << 8)) | (0x000000ff & l) : (0x0000ff00 & (l << 8)) | (0x000000ff & h); if (context != null) { if (blen <= 0 || blen > maxFrameSize) { throw new LimitExedeedException("帧长度非法:" + h + "/" + l + ":" + blen); } } incompleteframe = PooledByteBufAllocator.DEFAULT.buffer(blen + 16 + 2); incompleteframe = incompleteframe.order(Protocol.order); incompleteframe.writeShort(blen); status = STATUS_C; break; case STATUS_C: int len = incompleteframe.writableBytes() - 16; len = len < readBuffer.readableBytes() ? len : readBuffer.readableBytes(); // incompleteframe.writeBytes(readBuffer, len); if (readBuffer.hasMemoryAddress()) { PlatformDependent.copyMemory( readBuffer.memoryAddress() + readBuffer.readerIndex(), incompleteframe.memoryAddress() + incompleteframe.writerIndex(), len); } else if (readBuffer.hasArray()) { PlatformDependent.copyMemory( readBuffer.array(), readBuffer.arrayOffset() + readBuffer.readerIndex(), incompleteframe.memoryAddress() + incompleteframe.writerIndex(), len); } incompleteframe.writerIndex(incompleteframe.writerIndex() + len); readBuffer.readerIndex(readBuffer.readerIndex() + len); if ((incompleteframe.writableBytes() - 16) <= 0) { status = STATUS_H; return incompleteframe; } break; } } return null; }
/** * Read the next decoded {@link ByteBuf} from the {@link EmbeddedChannel} or {@code null} if one * does not exist. * * @param decoder The channel to read from * @return The next decoded {@link ByteBuf} from the {@link EmbeddedChannel} or {@code null} if * one does not exist */ private static ByteBuf nextReadableBuf(EmbeddedChannel decoder) { for (; ; ) { final ByteBuf buf = decoder.readInbound(); if (buf == null) { return null; } if (!buf.isReadable()) { buf.release(); continue; } return buf; } }
// make sure we don't return without first releasing the file reference content @Override public ReturnOption handle(FileDescriptor file, ByteBuf data) { if (file == FileDescriptor.FINAL) return this.downstream.handle(file, data); ByteBuf in = data; if (in != null) { while (in.isReadable()) { int amt = Math.min(in.readableBytes(), this.size - this.currchunk); ByteBuf out = in.copy(in.readerIndex(), amt); in.skipBytes(amt); this.currchunk += amt; boolean eof = (this.currchunk == this.size) || (!in.isReadable() && file.isEof()); this.nextMessage(out, file, eof); if (eof) { this.seqnum++; this.currchunk = 0; } } in.release(); } else if (file.isEof()) { this.nextMessage(null, file, false); } // write all messages in the queue while (this.outlist.size() > 0) { ReturnOption ret = this.downstream.handle(this.outlist.remove(0), this.outbuf.remove(0)); if (ret != ReturnOption.CONTINUE) return ret; } return ReturnOption.CONTINUE; }
private void getParams() { if (request.method() == HttpMethod.GET) { params = null; } else if (request.method() == HttpMethod.POST) { ByteBuf content = request.content(); if (content.isReadable()) { String param = content.toString(WaarpStringUtils.UTF8); QueryStringDecoder queryStringDecoder2 = new QueryStringDecoder("/?" + param); params = queryStringDecoder2.parameters(); } else { params = null; } } }
private void processUtf8(ByteBuf in, ByteBuf out, boolean jsonpMode) { while (in.isReadable()) { short value = (short) (in.readByte() & 0xFF); if (value >>> 7 == 0) { if (jsonpMode && (value == '\\' || value == '\'')) { out.writeByte('\\'); } out.writeByte(value); } else { out.writeByte(((value >>> 6) | 0xC0)); out.writeByte(((value & 0x3F) | 0x80)); } } }
@Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { ByteBuf in = (ByteBuf) msg; try { // System.out.println(in.toString()); while (in.isReadable()) { System.out.print((char) in.readByte()); System.out.flush(); } } finally { // same as in.release(); ReferenceCountUtil.release(msg); } }
@Override protected void channelRead0(io.netty.channel.ChannelHandlerContext ctx, PacketsMessage message) throws Exception { ByteBuf content = message.getContent(); MainBaseClient client = message.getClient(); if (log.isTraceEnabled()) { log.trace( "In message: {} sessionId: {}", content.toString(CharsetUtil.UTF_8), client.getSessionId()); } while (content.isReadable()) { try { Packet packet = decoder.decodePackets(content, client.getSessionId()); Namespace ns = namespacesHub.get(packet.getEndpoint()); if (ns == null) { log.debug( "Can't find namespace for endpoint: {}, sessionId: {} probably it was removed.", packet.getEndpoint(), client.getSessionId()); return; } if (packet.getType() == PacketType.CONNECT) { client.addChildClient(ns); } NamespaceClient nClient = (NamespaceClient) client.getChildClient(ns); if (nClient == null) { log.debug( "Can't find namespace client in namespace: {}, sessionId: {} probably it was disconnected.", ns.getName(), client.getSessionId()); return; } packetListener.onPacket(packet, nClient); } catch (Exception ex) { String c = content.toString(CharsetUtil.UTF_8); log.error( "Error during data processing. Client sessionId: " + client.getSessionId() + ", data: " + c, ex); return; } } }