Search in sources :

Example 6 with FileRegion

use of io.netty.channel.FileRegion in project netty by netty.

the class HttpResponseEncoderTest method testLargeFileRegionChunked.

@Test
public void testLargeFileRegionChunked() throws Exception {
    EmbeddedChannel channel = new EmbeddedChannel(new HttpResponseEncoder());
    HttpResponse response = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK);
    response.headers().set(HttpHeaderNames.TRANSFER_ENCODING, HttpHeaderValues.CHUNKED);
    assertTrue(channel.writeOutbound(response));
    ByteBuf buffer = channel.readOutbound();
    assertEquals("HTTP/1.1 200 OK\r\n" + HttpHeaderNames.TRANSFER_ENCODING + ": " + HttpHeaderValues.CHUNKED + "\r\n\r\n", buffer.toString(CharsetUtil.US_ASCII));
    buffer.release();
    assertTrue(channel.writeOutbound(FILE_REGION));
    buffer = channel.readOutbound();
    assertEquals("80000000\r\n", buffer.toString(CharsetUtil.US_ASCII));
    buffer.release();
    FileRegion region = channel.readOutbound();
    assertSame(FILE_REGION, region);
    region.release();
    buffer = channel.readOutbound();
    assertEquals("\r\n", buffer.toString(CharsetUtil.US_ASCII));
    buffer.release();
    assertTrue(channel.writeOutbound(LastHttpContent.EMPTY_LAST_CONTENT));
    buffer = channel.readOutbound();
    assertEquals("0\r\n\r\n", buffer.toString(CharsetUtil.US_ASCII));
    buffer.release();
    assertFalse(channel.finish());
}
Also used : FileRegion(io.netty.channel.FileRegion) EmbeddedChannel(io.netty.channel.embedded.EmbeddedChannel) ByteBuf(io.netty.buffer.ByteBuf) Test(org.junit.jupiter.api.Test)

Example 7 with FileRegion

use of io.netty.channel.FileRegion in project netty by netty.

the class HttpObjectEncoder method encode.

@Override
protected void encode(ChannelHandlerContext ctx, Object msg, List<Object> out) throws Exception {
    ByteBuf buf = null;
    if (msg instanceof HttpMessage) {
        if (state != ST_INIT) {
            throw new IllegalStateException("unexpected message type: " + StringUtil.simpleClassName(msg) + ", state: " + state);
        }
        @SuppressWarnings({ "unchecked", "CastConflictsWithInstanceof" }) H m = (H) msg;
        buf = ctx.alloc().buffer((int) headersEncodedSizeAccumulator);
        // Encode the message.
        encodeInitialLine(buf, m);
        state = isContentAlwaysEmpty(m) ? ST_CONTENT_ALWAYS_EMPTY : HttpUtil.isTransferEncodingChunked(m) ? ST_CONTENT_CHUNK : ST_CONTENT_NON_CHUNK;
        sanitizeHeadersBeforeEncode(m, state == ST_CONTENT_ALWAYS_EMPTY);
        encodeHeaders(m.headers(), buf);
        ByteBufUtil.writeShortBE(buf, CRLF_SHORT);
        headersEncodedSizeAccumulator = HEADERS_WEIGHT_NEW * padSizeForAccumulation(buf.readableBytes()) + HEADERS_WEIGHT_HISTORICAL * headersEncodedSizeAccumulator;
    }
    // See https://github.com/netty/netty/issues/2983 for more information.
    if (msg instanceof ByteBuf) {
        final ByteBuf potentialEmptyBuf = (ByteBuf) msg;
        if (!potentialEmptyBuf.isReadable()) {
            out.add(potentialEmptyBuf.retain());
            return;
        }
    }
    if (msg instanceof HttpContent || msg instanceof ByteBuf || msg instanceof FileRegion) {
        switch(state) {
            case ST_INIT:
                throw new IllegalStateException("unexpected message type: " + StringUtil.simpleClassName(msg) + ", state: " + state);
            case ST_CONTENT_NON_CHUNK:
                final long contentLength = contentLength(msg);
                if (contentLength > 0) {
                    if (buf != null && buf.writableBytes() >= contentLength && msg instanceof HttpContent) {
                        // merge into other buffer for performance reasons
                        buf.writeBytes(((HttpContent) msg).content());
                        out.add(buf);
                    } else {
                        if (buf != null) {
                            out.add(buf);
                        }
                        out.add(encodeAndRetain(msg));
                    }
                    if (msg instanceof LastHttpContent) {
                        state = ST_INIT;
                    }
                    break;
                }
            // fall-through!
            case ST_CONTENT_ALWAYS_EMPTY:
                if (buf != null) {
                    // We allocated a buffer so add it now.
                    out.add(buf);
                } else {
                    // Need to produce some output otherwise an
                    // IllegalStateException will be thrown as we did not write anything
                    // Its ok to just write an EMPTY_BUFFER as if there are reference count issues these will be
                    // propagated as the caller of the encode(...) method will release the original
                    // buffer.
                    // Writing an empty buffer will not actually write anything on the wire, so if there is a user
                    // error with msg it will not be visible externally
                    out.add(Unpooled.EMPTY_BUFFER);
                }
                break;
            case ST_CONTENT_CHUNK:
                if (buf != null) {
                    // We allocated a buffer so add it now.
                    out.add(buf);
                }
                encodeChunkedContent(ctx, msg, contentLength(msg), out);
                break;
            default:
                throw new Error();
        }
        if (msg instanceof LastHttpContent) {
            state = ST_INIT;
        }
    } else if (buf != null) {
        out.add(buf);
    }
}
Also used : FileRegion(io.netty.channel.FileRegion) ByteBuf(io.netty.buffer.ByteBuf)

Example 8 with FileRegion

use of io.netty.channel.FileRegion in project netty by netty.

the class SocketFileRegionTest method testFileRegion0.

private static void testFileRegion0(ServerBootstrap sb, Bootstrap cb, boolean voidPromise, final boolean autoRead, boolean defaultFileRegion) throws Throwable {
    sb.childOption(ChannelOption.AUTO_READ, autoRead);
    cb.option(ChannelOption.AUTO_READ, autoRead);
    final int bufferSize = 1024;
    final File file = PlatformDependent.createTempFile("netty-", ".tmp", null);
    file.deleteOnExit();
    final FileOutputStream out = new FileOutputStream(file);
    final Random random = PlatformDependent.threadLocalRandom();
    // Prepend random data which will not be transferred, so that we can test non-zero start offset
    final int startOffset = random.nextInt(8192);
    for (int i = 0; i < startOffset; i++) {
        out.write(random.nextInt());
    }
    // .. and here comes the real data to transfer.
    out.write(data, bufferSize, data.length - bufferSize);
    // .. and then some extra data which is not supposed to be transferred.
    for (int i = random.nextInt(8192); i > 0; i--) {
        out.write(random.nextInt());
    }
    out.close();
    ChannelInboundHandler ch = new SimpleChannelInboundHandler<Object>() {

        @Override
        public void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {
        }

        @Override
        public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
            if (!autoRead) {
                ctx.read();
            }
        }

        @Override
        public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
            ctx.close();
        }
    };
    TestHandler sh = new TestHandler(autoRead);
    sb.childHandler(sh);
    cb.handler(ch);
    Channel sc = sb.bind().sync().channel();
    Channel cc = cb.connect(sc.localAddress()).sync().channel();
    FileRegion region = new DefaultFileRegion(new RandomAccessFile(file, "r").getChannel(), startOffset, data.length - bufferSize);
    FileRegion emptyRegion = new DefaultFileRegion(new RandomAccessFile(file, "r").getChannel(), 0, 0);
    if (!defaultFileRegion) {
        region = new FileRegionWrapper(region);
        emptyRegion = new FileRegionWrapper(emptyRegion);
    }
    // https://github.com/netty/netty/issues/2964
    if (voidPromise) {
        assertEquals(cc.voidPromise(), cc.write(Unpooled.wrappedBuffer(data, 0, bufferSize), cc.voidPromise()));
        assertEquals(cc.voidPromise(), cc.write(emptyRegion, cc.voidPromise()));
        assertEquals(cc.voidPromise(), cc.writeAndFlush(region, cc.voidPromise()));
    } else {
        assertNotEquals(cc.voidPromise(), cc.write(Unpooled.wrappedBuffer(data, 0, bufferSize)));
        assertNotEquals(cc.voidPromise(), cc.write(emptyRegion));
        assertNotEquals(cc.voidPromise(), cc.writeAndFlush(region));
    }
    while (sh.counter < data.length) {
        if (sh.exception.get() != null) {
            break;
        }
        try {
            Thread.sleep(50);
        } catch (InterruptedException e) {
        // Ignore.
        }
    }
    sh.channel.close().sync();
    cc.close().sync();
    sc.close().sync();
    if (sh.exception.get() != null && !(sh.exception.get() instanceof IOException)) {
        throw sh.exception.get();
    }
    if (sh.exception.get() != null) {
        throw sh.exception.get();
    }
    // Make sure we did not receive more than we expected.
    assertThat(sh.counter, is(data.length));
}
Also used : SimpleChannelInboundHandler(io.netty.channel.SimpleChannelInboundHandler) Channel(io.netty.channel.Channel) WritableByteChannel(java.nio.channels.WritableByteChannel) ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) IOException(java.io.IOException) DefaultFileRegion(io.netty.channel.DefaultFileRegion) Random(java.util.Random) RandomAccessFile(java.io.RandomAccessFile) FileOutputStream(java.io.FileOutputStream) FileRegion(io.netty.channel.FileRegion) DefaultFileRegion(io.netty.channel.DefaultFileRegion) ChannelInboundHandler(io.netty.channel.ChannelInboundHandler) SimpleChannelInboundHandler(io.netty.channel.SimpleChannelInboundHandler) RandomAccessFile(java.io.RandomAccessFile) File(java.io.File)

Example 9 with FileRegion

use of io.netty.channel.FileRegion in project rocketmq-rocketmq-all-4.1.0-incubating by lirenzuo.

the class QueryMessageProcessor method viewMessageById.

public RemotingCommand viewMessageById(ChannelHandlerContext ctx, RemotingCommand request) throws RemotingCommandException {
    final RemotingCommand response = RemotingCommand.createResponseCommand(null);
    final ViewMessageRequestHeader requestHeader = (ViewMessageRequestHeader) request.decodeCommandCustomHeader(ViewMessageRequestHeader.class);
    response.setOpaque(request.getOpaque());
    final SelectMappedBufferResult selectMappedBufferResult = this.brokerController.getMessageStore().selectOneMessageByOffset(requestHeader.getOffset());
    if (selectMappedBufferResult != null) {
        response.setCode(ResponseCode.SUCCESS);
        response.setRemark(null);
        try {
            FileRegion fileRegion = new OneMessageTransfer(response.encodeHeader(selectMappedBufferResult.getSize()), selectMappedBufferResult);
            ctx.channel().writeAndFlush(fileRegion).addListener(new ChannelFutureListener() {

                @Override
                public void operationComplete(ChannelFuture future) throws Exception {
                    selectMappedBufferResult.release();
                    if (!future.isSuccess()) {
                        log.error("Transfer one message from page cache failed, ", future.cause());
                    }
                }
            });
        } catch (Throwable e) {
            log.error("", e);
            selectMappedBufferResult.release();
        }
        return null;
    } else {
        response.setCode(ResponseCode.SYSTEM_ERROR);
        response.setRemark("can not find message by the offset, " + requestHeader.getOffset());
    }
    return response;
}
Also used : RemotingCommand(org.apache.rocketmq.remoting.protocol.RemotingCommand) ViewMessageRequestHeader(org.apache.rocketmq.common.protocol.header.ViewMessageRequestHeader) ChannelFuture(io.netty.channel.ChannelFuture) OneMessageTransfer(org.apache.rocketmq.broker.pagecache.OneMessageTransfer) FileRegion(io.netty.channel.FileRegion) SelectMappedBufferResult(org.apache.rocketmq.store.SelectMappedBufferResult) ChannelFutureListener(io.netty.channel.ChannelFutureListener) RemotingCommandException(org.apache.rocketmq.remoting.exception.RemotingCommandException)

Example 10 with FileRegion

use of io.netty.channel.FileRegion in project netty by netty.

the class AbstractNioByteChannel method doWrite.

@Override
protected void doWrite(ChannelOutboundBuffer in) throws Exception {
    int writeSpinCount = -1;
    boolean setOpWrite = false;
    for (; ; ) {
        Object msg = in.current();
        if (msg == null) {
            // Wrote all messages.
            clearOpWrite();
            // Directly return here so incompleteWrite(...) is not called.
            return;
        }
        if (msg instanceof ByteBuf) {
            ByteBuf buf = (ByteBuf) msg;
            int readableBytes = buf.readableBytes();
            if (readableBytes == 0) {
                in.remove();
                continue;
            }
            boolean done = false;
            long flushedAmount = 0;
            if (writeSpinCount == -1) {
                writeSpinCount = config().getWriteSpinCount();
            }
            for (int i = writeSpinCount - 1; i >= 0; i--) {
                int localFlushedAmount = doWriteBytes(buf);
                if (localFlushedAmount == 0) {
                    setOpWrite = true;
                    break;
                }
                flushedAmount += localFlushedAmount;
                if (!buf.isReadable()) {
                    done = true;
                    break;
                }
            }
            in.progress(flushedAmount);
            if (done) {
                in.remove();
            } else {
                // Break the loop and so incompleteWrite(...) is called.
                break;
            }
        } else if (msg instanceof FileRegion) {
            FileRegion region = (FileRegion) msg;
            boolean done = region.transferred() >= region.count();
            if (!done) {
                long flushedAmount = 0;
                if (writeSpinCount == -1) {
                    writeSpinCount = config().getWriteSpinCount();
                }
                for (int i = writeSpinCount - 1; i >= 0; i--) {
                    long localFlushedAmount = doWriteFileRegion(region);
                    if (localFlushedAmount == 0) {
                        setOpWrite = true;
                        break;
                    }
                    flushedAmount += localFlushedAmount;
                    if (region.transferred() >= region.count()) {
                        done = true;
                        break;
                    }
                }
                in.progress(flushedAmount);
            }
            if (done) {
                in.remove();
            } else {
                // Break the loop and so incompleteWrite(...) is called.
                break;
            }
        } else {
            // Should not reach here.
            throw new Error();
        }
    }
    incompleteWrite(setOpWrite);
}
Also used : FileRegion(io.netty.channel.FileRegion) ByteBuf(io.netty.buffer.ByteBuf)

Aggregations

FileRegion (io.netty.channel.FileRegion)21 ByteBuf (io.netty.buffer.ByteBuf)10 ChannelFuture (io.netty.channel.ChannelFuture)10 ChannelFutureListener (io.netty.channel.ChannelFutureListener)8 RemotingCommand (org.apache.rocketmq.remoting.protocol.RemotingCommand)8 RemotingCommandException (org.apache.rocketmq.remoting.exception.RemotingCommandException)6 DefaultFileRegion (io.netty.channel.DefaultFileRegion)5 IOException (java.io.IOException)5 WritableByteChannel (java.nio.channels.WritableByteChannel)4 OneMessageTransfer (org.apache.rocketmq.broker.pagecache.OneMessageTransfer)4 Channel (io.netty.channel.Channel)3 ChannelHandlerContext (io.netty.channel.ChannelHandlerContext)3 EmbeddedChannel (io.netty.channel.embedded.EmbeddedChannel)3 File (java.io.File)3 FileOutputStream (java.io.FileOutputStream)2 RandomAccessFile (java.io.RandomAccessFile)2 Random (java.util.Random)2 ConsumerGroupInfo (org.apache.rocketmq.broker.client.ConsumerGroupInfo)2 ConsumerFilterData (org.apache.rocketmq.broker.filter.ConsumerFilterData)2 ExpressionForRetryMessageFilter (org.apache.rocketmq.broker.filter.ExpressionForRetryMessageFilter)2