use of io.netty.channel.ChannelInboundHandlerAdapter in project netty by netty.
the class SocketHalfClosedTest method testAllDataReadClosure.
public void testAllDataReadClosure(final boolean autoRead, final boolean allowHalfClosed, ServerBootstrap sb, Bootstrap cb) throws Throwable {
final int totalServerBytesWritten = 1024 * 16;
final int numReadsPerReadLoop = 2;
final CountDownLatch serverInitializedLatch = new CountDownLatch(1);
final CountDownLatch clientReadAllDataLatch = new CountDownLatch(1);
final CountDownLatch clientHalfClosedLatch = new CountDownLatch(1);
final AtomicInteger clientReadCompletes = new AtomicInteger();
Channel serverChannel = null;
Channel clientChannel = null;
try {
cb.option(ChannelOption.ALLOW_HALF_CLOSURE, allowHalfClosed).option(ChannelOption.AUTO_READ, autoRead).option(ChannelOption.RCVBUF_ALLOCATOR, new TestNumReadsRecvByteBufAllocator(numReadsPerReadLoop));
sb.childHandler(new ChannelInitializer<Channel>() {
@Override
protected void initChannel(Channel ch) throws Exception {
ch.pipeline().addLast(new ChannelInboundHandlerAdapter() {
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
ByteBuf buf = ctx.alloc().buffer(totalServerBytesWritten);
buf.writerIndex(buf.capacity());
ctx.writeAndFlush(buf).addListener(ChannelFutureListener.CLOSE);
serverInitializedLatch.countDown();
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
ctx.close();
}
});
}
});
cb.handler(new ChannelInitializer<Channel>() {
@Override
protected void initChannel(Channel ch) throws Exception {
ch.pipeline().addLast(new ChannelInboundHandlerAdapter() {
private int bytesRead;
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
ByteBuf buf = (ByteBuf) msg;
bytesRead += buf.readableBytes();
buf.release();
}
@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) {
if (evt == ChannelInputShutdownEvent.INSTANCE && allowHalfClosed) {
clientHalfClosedLatch.countDown();
} else if (evt == ChannelInputShutdownReadComplete.INSTANCE) {
ctx.close();
}
}
@Override
public void channelInactive(ChannelHandlerContext ctx) {
if (!allowHalfClosed) {
clientHalfClosedLatch.countDown();
}
}
@Override
public void channelReadComplete(ChannelHandlerContext ctx) {
clientReadCompletes.incrementAndGet();
if (bytesRead == totalServerBytesWritten) {
clientReadAllDataLatch.countDown();
}
if (!autoRead) {
ctx.read();
}
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
ctx.close();
}
});
}
});
serverChannel = sb.bind().sync().channel();
clientChannel = cb.connect(serverChannel.localAddress()).sync().channel();
clientChannel.read();
serverInitializedLatch.await();
clientReadAllDataLatch.await();
clientHalfClosedLatch.await();
assertTrue("too many read complete events: " + clientReadCompletes.get(), totalServerBytesWritten / numReadsPerReadLoop + 10 > clientReadCompletes.get());
} finally {
if (clientChannel != null) {
clientChannel.close().sync();
}
if (serverChannel != null) {
serverChannel.close().sync();
}
}
}
use of io.netty.channel.ChannelInboundHandlerAdapter in project netty by netty.
the class HttpContentDecoderTest method testExpectContinueResetHttpObjectDecoder.
@Test
public void testExpectContinueResetHttpObjectDecoder() {
// request with header "Expect: 100-continue" must be replied with one "100 Continue" response
// case 5: Test that HttpObjectDecoder correctly resets its internal state after a failed expectation.
HttpRequestDecoder decoder = new HttpRequestDecoder();
final int maxBytes = 10;
HttpObjectAggregator aggregator = new HttpObjectAggregator(maxBytes);
final AtomicReference<FullHttpRequest> secondRequestRef = new AtomicReference<FullHttpRequest>();
EmbeddedChannel channel = new EmbeddedChannel(decoder, aggregator, new ChannelInboundHandlerAdapter() {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
if (msg instanceof FullHttpRequest) {
if (!secondRequestRef.compareAndSet(null, (FullHttpRequest) msg)) {
((FullHttpRequest) msg).release();
}
} else {
ReferenceCountUtil.release(msg);
}
}
});
String req1 = "POST /1 HTTP/1.1\r\n" + "Content-Length: " + (maxBytes + 1) + "\r\n" + "Expect: 100-continue\r\n" + "\r\n";
assertFalse(channel.writeInbound(Unpooled.wrappedBuffer(req1.getBytes(CharsetUtil.US_ASCII))));
FullHttpResponse resp = channel.readOutbound();
assertEquals(HttpStatusClass.CLIENT_ERROR, resp.status().codeClass());
resp.release();
String req2 = "POST /2 HTTP/1.1\r\n" + "Content-Length: " + maxBytes + "\r\n" + "Expect: 100-continue\r\n" + "\r\n";
assertFalse(channel.writeInbound(Unpooled.wrappedBuffer(req2.getBytes(CharsetUtil.US_ASCII))));
resp = channel.readOutbound();
assertEquals(100, resp.status().code());
resp.release();
byte[] content = new byte[maxBytes];
assertFalse(channel.writeInbound(Unpooled.wrappedBuffer(content)));
FullHttpRequest req = secondRequestRef.get();
assertNotNull(req);
assertEquals("/2", req.uri());
assertEquals(10, req.content().readableBytes());
req.release();
assertHasInboundMessages(channel, false);
assertHasOutboundMessages(channel, false);
assertFalse(channel.finish());
}
use of io.netty.channel.ChannelInboundHandlerAdapter in project netty by netty.
the class ByteToMessageDecoderTest method testRemoveWhileInCallDecode.
// See https://github.com/netty/netty/issues/4635
@Test
public void testRemoveWhileInCallDecode() {
final Object upgradeMessage = new Object();
final ByteToMessageDecoder decoder = new ByteToMessageDecoder() {
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
assertEquals('a', in.readByte());
out.add(upgradeMessage);
}
};
EmbeddedChannel channel = new EmbeddedChannel(decoder, new ChannelInboundHandlerAdapter() {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
if (msg == upgradeMessage) {
ctx.pipeline().remove(decoder);
return;
}
ctx.fireChannelRead(msg);
}
});
ByteBuf buf = Unpooled.wrappedBuffer(new byte[] { 'a', 'b', 'c' });
assertTrue(channel.writeInbound(buf.copy()));
ByteBuf b = channel.readInbound();
assertEquals(b, buf.skipBytes(1));
assertFalse(channel.finish());
buf.release();
b.release();
}
use of io.netty.channel.ChannelInboundHandlerAdapter in project netty by netty.
the class ReplayingDecoderTest method testFireChannelReadCompleteOnInactive.
@Test
public void testFireChannelReadCompleteOnInactive() throws InterruptedException {
final BlockingQueue<Integer> queue = new LinkedBlockingDeque<Integer>();
final ByteBuf buf = Unpooled.buffer().writeBytes(new byte[] { 'a', 'b' });
EmbeddedChannel channel = new EmbeddedChannel(new ReplayingDecoder<Integer>() {
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
int readable = in.readableBytes();
assertTrue(readable > 0);
in.skipBytes(readable);
out.add("data");
}
@Override
protected void decodeLast(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
assertFalse(in.isReadable());
out.add("data");
}
}, new ChannelInboundHandlerAdapter() {
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
queue.add(3);
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
queue.add(1);
}
@Override
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
if (!ctx.channel().isActive()) {
queue.add(2);
}
}
});
assertFalse(channel.writeInbound(buf));
channel.finish();
assertEquals(1, (int) queue.take());
assertEquals(1, (int) queue.take());
assertEquals(2, (int) queue.take());
assertEquals(3, (int) queue.take());
assertTrue(queue.isEmpty());
}
use of io.netty.channel.ChannelInboundHandlerAdapter in project netty by netty.
the class EpollSpliceTest method spliceToFile.
@Test
public void spliceToFile() throws Throwable {
EventLoopGroup group = new EpollEventLoopGroup(1);
File file = File.createTempFile("netty-splice", null);
file.deleteOnExit();
SpliceHandler sh = new SpliceHandler(file);
ServerBootstrap bs = new ServerBootstrap();
bs.channel(EpollServerSocketChannel.class);
bs.group(group).childHandler(sh);
bs.childOption(EpollChannelOption.EPOLL_MODE, EpollMode.LEVEL_TRIGGERED);
Channel sc = bs.bind(new InetSocketAddress(0)).syncUninterruptibly().channel();
Bootstrap cb = new Bootstrap();
cb.group(group);
cb.channel(EpollSocketChannel.class);
cb.handler(new ChannelInboundHandlerAdapter());
Channel cc = cb.connect(sc.localAddress()).syncUninterruptibly().channel();
for (int i = 0; i < data.length; ) {
int length = Math.min(random.nextInt(1024 * 64), data.length - i);
ByteBuf buf = Unpooled.wrappedBuffer(data, i, length);
cc.writeAndFlush(buf);
i += length;
}
while (sh.future == null || !sh.future.isDone()) {
if (sh.exception.get() != null) {
break;
}
try {
Thread.sleep(50);
} catch (InterruptedException e) {
// Ignore.
}
}
sc.close().sync();
cc.close().sync();
if (sh.exception.get() != null && !(sh.exception.get() instanceof IOException)) {
throw sh.exception.get();
}
byte[] written = new byte[data.length];
FileInputStream in = new FileInputStream(file);
try {
Assert.assertEquals(written.length, in.read(written));
Assert.assertArrayEquals(data, written);
} finally {
in.close();
group.shutdownGracefully();
}
}
Aggregations