From 0e4c073bcfad744120a226cf4a02a5c2c7c59b9a Mon Sep 17 00:00:00 2001 From: Norman Maurer Date: Mon, 16 Dec 2019 21:00:32 +0100 Subject: [PATCH] =?UTF-8?q?Remove=20the=20intermediate=20List=20from=20Byt?= =?UTF-8?q?eToMessageDecoder=20(and=20sub-class=E2=80=A6=20(#8626)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Motivation: ByteToMessageDecoder requires using an intermediate List to put results into. This intermediate list adds overhead (memory/CPU) which grows as the number of objects increases. This overhead can be avoided by directly propagating events through the ChannelPipeline via ctx.fireChannelRead(...). This also makes the semantics more clear and allows us to keep track if we need to call ctx.read() in all cases. Modifications: - Remove List from the method signature of ByteToMessageDecoder.decode(...) and decodeLast(...) - Adjust all sub-classes - Adjust unit tests - Fix javadocs. Result: Adjust ByteToMessageDecoder as noted in https://github.com/netty/netty/issues/8525. --- .../codec/dns/DatagramDnsQueryDecoder.java | 13 +- .../codec/dns/DatagramDnsResponseDecoder.java | 6 +- .../codec/dns/TcpDnsResponseDecoder.java | 4 +- .../codec/haproxy/HAProxyMessageDecoder.java | 8 +- .../http/DelegatingChannelHandlerContext.java | 268 ++++++++++++ .../handler/codec/http/HttpClientCodec.java | 34 +- .../codec/http/HttpClientUpgradeHandler.java | 33 +- .../codec/http/HttpContentDecoder.java | 196 +++++---- .../codec/http/HttpContentEncoder.java | 4 +- .../handler/codec/http/HttpObjectDecoder.java | 44 +- .../handler/codec/http/HttpServerCodec.java | 29 +- .../codec/http/HttpServerUpgradeHandler.java | 41 +- .../websocketx/WebSocket00FrameDecoder.java | 5 +- .../websocketx/WebSocket08FrameDecoder.java | 22 +- .../WebSocketClientProtocolHandler.java | 5 +- .../websocketx/WebSocketProtocolHandler.java | 4 +- .../WebSocketServerProtocolHandler.java | 5 +- .../compression/DeflateDecoder.java | 5 +- .../compression/PerMessageDeflateDecoder.java | 10 +- .../WebSocket08FrameDecoderTest.java | 1 + .../WebSocketHandshakeHandOverTest.java | 5 +- .../WebSocketExtensionTestUtil.java | 6 +- .../CleartextHttp2ServerUpgradeHandler.java | 4 +- .../DecoratingHttp2ConnectionDecoder.java | 4 +- .../http2/DefaultHttp2ConnectionDecoder.java | 4 +- .../codec/http2/Http2ConnectionDecoder.java | 2 +- .../codec/http2/Http2ConnectionHandler.java | 17 +- .../handler/codec/http2/Http2FrameCodec.java | 9 +- .../codec/http2/Http2MultiplexCodec.java | 1 + .../Http2StreamFrameToHttpObjectCodec.java | 14 +- .../DefaultHttp2ConnectionDecoderTest.java | 2 +- .../http2/Http2ConnectionHandlerTest.java | 20 +- .../codec/http2/Http2FrameCodecTest.java | 50 +-- .../codec/http2/Http2MultiplexTest.java | 31 +- .../handler/codec/http2/Http2TestUtil.java | 3 +- .../http2/StreamBufferingEncoderTest.java | 4 +- .../binary/AbstractBinaryMemcacheDecoder.java | 18 +- .../binary/BinaryMemcacheClientCodec.java | 217 +++++++++- .../netty/handler/codec/mqtt/MqttDecoder.java | 10 +- .../handler/codec/mqtt/MqttCodecTest.java | 170 ++++---- .../codec/redis/RedisArrayAggregator.java | 4 +- .../handler/codec/redis/RedisDecoder.java | 42 +- .../codec/smtp/SmtpResponseDecoder.java | 4 +- .../codec/socks/SocksAuthRequestDecoder.java | 8 +- .../codec/socks/SocksAuthResponseDecoder.java | 10 +- .../codec/socks/SocksCmdRequestDecoder.java | 14 +- .../codec/socks/SocksCmdResponseDecoder.java | 14 +- .../codec/socks/SocksInitRequestDecoder.java | 6 +- .../codec/socks/SocksInitResponseDecoder.java | 8 +- .../SocksPortUnificationServerHandler.java | 4 +- .../codec/socksx/v4/Socks4ClientDecoder.java | 14 +- .../codec/socksx/v4/Socks4ServerDecoder.java | 14 +- .../v5/Socks5CommandRequestDecoder.java | 14 +- .../v5/Socks5CommandResponseDecoder.java | 14 +- .../v5/Socks5InitialRequestDecoder.java | 14 +- .../v5/Socks5InitialResponseDecoder.java | 14 +- .../v5/Socks5PasswordAuthRequestDecoder.java | 14 +- .../v5/Socks5PasswordAuthResponseDecoder.java | 15 +- .../codec/stomp/StompSubframeDecoder.java | 16 +- .../netty/handler/codec/xml/XmlDecoder.java | 26 +- .../handler/codec/ByteToMessageCodec.java | 20 +- .../handler/codec/ByteToMessageDecoder.java | 405 ++++++++++++++---- .../handler/codec/DatagramPacketDecoder.java | 4 +- .../codec/DelimiterBasedFrameDecoder.java | 12 +- .../codec/FixedLengthFrameDecoder.java | 10 +- .../codec/LengthFieldBasedFrameDecoder.java | 9 +- .../handler/codec/LineBasedFrameDecoder.java | 10 +- .../handler/codec/MessageAggregator.java | 12 +- .../handler/codec/MessageToMessageCodec.java | 8 +- .../codec/MessageToMessageDecoder.java | 14 +- .../netty/handler/codec/ReplayingDecoder.java | 63 +-- .../handler/codec/base64/Base64Decoder.java | 4 +- .../handler/codec/bytes/ByteArrayDecoder.java | 4 +- .../codec/compression/Bzip2Decoder.java | 6 +- .../codec/compression/FastLzFrameDecoder.java | 5 +- .../codec/compression/JZlibDecoder.java | 6 +- .../codec/compression/JdkZlibDecoder.java | 5 +- .../codec/compression/Lz4FrameDecoder.java | 5 +- .../handler/codec/compression/LzfDecoder.java | 8 +- .../codec/compression/SnappyFrameDecoder.java | 8 +- .../handler/codec/json/JsonObjectDecoder.java | 8 +- .../CompatibleMarshallingDecoder.java | 9 +- .../codec/marshalling/MarshallingDecoder.java | 4 +- .../codec/protobuf/ProtobufDecoder.java | 12 +- .../codec/protobuf/ProtobufDecoderNano.java | 5 +- .../ProtobufVarint32FrameDecoder.java | 6 +- .../codec/serialization/ObjectDecoder.java | 4 +- .../handler/codec/string/StringDecoder.java | 5 +- .../handler/codec/xml/XmlFrameDecoder.java | 6 +- .../handler/codec/ByteToMessageCodecTest.java | 10 +- .../codec/ByteToMessageDecoderTest.java | 39 +- .../codec/DatagramPacketDecoderTest.java | 2 +- .../handler/codec/ReplayingDecoderTest.java | 23 +- .../example/factorial/BigIntegerDecoder.java | 5 +- .../PortUnificationServerHandler.java | 4 +- .../netty/handler/ssl/AbstractSniHandler.java | 3 +- .../netty/handler/ssl/OptionalSslHandler.java | 3 +- .../java/io/netty/handler/ssl/SslHandler.java | 5 +- .../handler/flow/FlowControlHandlerTest.java | 9 +- .../handler/ssl/OptionalSslHandlerTest.java | 8 +- .../io/netty/handler/ssl/SslHandlerTest.java | 4 +- .../sctp/SctpInboundByteStreamHandler.java | 6 +- .../sctp/SctpMessageCompletionHandler.java | 14 +- 103 files changed, 1483 insertions(+), 926 deletions(-) create mode 100644 codec-http/src/main/java/io/netty/handler/codec/http/DelegatingChannelHandlerContext.java diff --git a/codec-dns/src/main/java/io/netty/handler/codec/dns/DatagramDnsQueryDecoder.java b/codec-dns/src/main/java/io/netty/handler/codec/dns/DatagramDnsQueryDecoder.java index 760c57cc66..016046a4bc 100644 --- a/codec-dns/src/main/java/io/netty/handler/codec/dns/DatagramDnsQueryDecoder.java +++ b/codec-dns/src/main/java/io/netty/handler/codec/dns/DatagramDnsQueryDecoder.java @@ -23,7 +23,6 @@ import io.netty.handler.codec.CorruptedFrameException; import io.netty.handler.codec.MessageToMessageDecoder; import io.netty.util.internal.UnstableApi; -import java.util.List; import static java.util.Objects.requireNonNull; @@ -51,11 +50,10 @@ public class DatagramDnsQueryDecoder extends MessageToMessageDecoder out) throws Exception { + protected void decode(ChannelHandlerContext ctx, DatagramPacket packet) throws Exception { final ByteBuf buf = packet.content(); - final DnsQuery query = newQuery(packet, buf); - boolean success = false; + DnsQuery query = newQuery(packet, buf); try { final int questionCount = buf.readUnsignedShort(); final int answerCount = buf.readUnsignedShort(); @@ -67,10 +65,11 @@ public class DatagramDnsQueryDecoder extends MessageToMessageDecoder out) throws Exception { - out.add(decodeResponse(ctx, packet)); + protected void decode(ChannelHandlerContext ctx, DatagramPacket packet) throws Exception { + DnsResponse response = decodeResponse(ctx, packet); + ctx.fireChannelRead(response); } protected DnsResponse decodeResponse(ChannelHandlerContext ctx, DatagramPacket packet) throws Exception { diff --git a/codec-dns/src/main/java/io/netty/handler/codec/dns/TcpDnsResponseDecoder.java b/codec-dns/src/main/java/io/netty/handler/codec/dns/TcpDnsResponseDecoder.java index f8a92d9929..ef42284249 100644 --- a/codec-dns/src/main/java/io/netty/handler/codec/dns/TcpDnsResponseDecoder.java +++ b/codec-dns/src/main/java/io/netty/handler/codec/dns/TcpDnsResponseDecoder.java @@ -52,8 +52,8 @@ public final class TcpDnsResponseDecoder extends LengthFieldBasedFrameDecoder { } @Override - protected Object decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception { - ByteBuf frame = (ByteBuf) super.decode(ctx, in); + protected Object decode0(ChannelHandlerContext ctx, ByteBuf in) throws Exception { + ByteBuf frame = (ByteBuf) super.decode0(ctx, in); if (frame == null) { return null; } diff --git a/codec-haproxy/src/main/java/io/netty/handler/codec/haproxy/HAProxyMessageDecoder.java b/codec-haproxy/src/main/java/io/netty/handler/codec/haproxy/HAProxyMessageDecoder.java index 87bea65a71..b8fcf1bc1b 100644 --- a/codec-haproxy/src/main/java/io/netty/handler/codec/haproxy/HAProxyMessageDecoder.java +++ b/codec-haproxy/src/main/java/io/netty/handler/codec/haproxy/HAProxyMessageDecoder.java @@ -21,8 +21,6 @@ import io.netty.handler.codec.ByteToMessageDecoder; import io.netty.handler.codec.ProtocolDetectionResult; import io.netty.util.CharsetUtil; -import java.util.List; - /** * Decodes an HAProxy proxy protocol header * @@ -256,7 +254,7 @@ public class HAProxyMessageDecoder extends ByteToMessageDecoder { } @Override - protected final void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { + protected final void decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception { // determine the specification version if (version == -1) { if ((version = findVersion(in)) == -1) { @@ -276,9 +274,9 @@ public class HAProxyMessageDecoder extends ByteToMessageDecoder { finished = true; try { if (version == 1) { - out.add(HAProxyMessage.decodeHeader(decoded.toString(CharsetUtil.US_ASCII))); + ctx.fireChannelRead(HAProxyMessage.decodeHeader(decoded.toString(CharsetUtil.US_ASCII))); } else { - out.add(HAProxyMessage.decodeHeader(decoded)); + ctx.fireChannelRead(HAProxyMessage.decodeHeader(decoded)); } } catch (HAProxyProtocolException e) { fail(ctx, null, e); diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/DelegatingChannelHandlerContext.java b/codec-http/src/main/java/io/netty/handler/codec/http/DelegatingChannelHandlerContext.java new file mode 100644 index 0000000000..d12c10afdb --- /dev/null +++ b/codec-http/src/main/java/io/netty/handler/codec/http/DelegatingChannelHandlerContext.java @@ -0,0 +1,268 @@ +/* + * Copyright 2018 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package io.netty.handler.codec.http; + +import io.netty.buffer.ByteBufAllocator; +import io.netty.channel.Channel; +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelHandler; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelPipeline; +import io.netty.channel.ChannelProgressivePromise; +import io.netty.channel.ChannelPromise; +import io.netty.util.Attribute; +import io.netty.util.AttributeKey; +import io.netty.util.concurrent.EventExecutor; +import io.netty.util.internal.ObjectUtil; + +import java.net.SocketAddress; + +abstract class DelegatingChannelHandlerContext implements ChannelHandlerContext { + + private final ChannelHandlerContext ctx; + + DelegatingChannelHandlerContext(ChannelHandlerContext ctx) { + this.ctx = ObjectUtil.checkNotNull(ctx, "ctx"); + } + + @Override + public Channel channel() { + return ctx.channel(); + } + + @Override + public EventExecutor executor() { + return ctx.executor(); + } + + @Override + public String name() { + return ctx.name(); + } + + @Override + public ChannelHandler handler() { + return ctx.handler(); + } + + @Override + public boolean isRemoved() { + return ctx.isRemoved(); + } + + @Override + public ChannelHandlerContext fireChannelRegistered() { + ctx.fireChannelRegistered(); + return this; + } + + @Override + public ChannelHandlerContext fireChannelUnregistered() { + ctx.fireChannelUnregistered(); + return this; + } + + @Override + public ChannelHandlerContext fireChannelActive() { + ctx.fireChannelActive(); + return this; + } + + @Override + public ChannelHandlerContext fireChannelInactive() { + ctx.fireChannelInactive(); + return this; + } + + @Override + public ChannelHandlerContext fireExceptionCaught(Throwable cause) { + ctx.fireExceptionCaught(cause); + return this; + } + + @Override + public ChannelHandlerContext fireUserEventTriggered(Object evt) { + ctx.fireUserEventTriggered(evt); + return this; + } + + @Override + public ChannelHandlerContext fireChannelRead(Object msg) { + + ctx.fireChannelRead(msg); + return this; + } + + @Override + public ChannelHandlerContext fireChannelReadComplete() { + ctx.fireChannelReadComplete(); + return this; + } + + @Override + public ChannelHandlerContext fireChannelWritabilityChanged() { + ctx.fireChannelWritabilityChanged(); + return this; + } + + @Override + public ChannelHandlerContext read() { + ctx.read(); + return this; + } + + @Override + public ChannelHandlerContext flush() { + ctx.flush(); + return this; + } + + @Override + public ChannelPipeline pipeline() { + return ctx.pipeline(); + } + + @Override + public ByteBufAllocator alloc() { + return ctx.alloc(); + } + + @Deprecated + public Attribute attr(AttributeKey key) { + return ctx.attr(key); + } + + @Deprecated + public boolean hasAttr(AttributeKey key) { + return ctx.hasAttr(key); + } + + @Override + public ChannelFuture bind(SocketAddress localAddress) { + return ctx.bind(localAddress); + } + + @Override + public ChannelFuture connect(SocketAddress remoteAddress) { + return ctx.connect(remoteAddress); + } + + @Override + public ChannelFuture connect(SocketAddress remoteAddress, SocketAddress localAddress) { + return ctx.connect(remoteAddress, localAddress); + } + + @Override + public ChannelFuture disconnect() { + return ctx.disconnect(); + } + + @Override + public ChannelFuture close() { + return ctx.close(); + } + + @Override + public ChannelFuture deregister() { + return ctx.deregister(); + } + + @Override + public ChannelFuture register() { + return ctx.register(); + } + + @Override + public ChannelFuture register(ChannelPromise promise) { + return ctx.register(promise); + } + + @Override + public ChannelFuture bind(SocketAddress localAddress, ChannelPromise promise) { + return ctx.bind(localAddress, promise); + } + + @Override + public ChannelFuture connect(SocketAddress remoteAddress, ChannelPromise promise) { + return ctx.connect(remoteAddress, promise); + } + + @Override + public ChannelFuture connect( + SocketAddress remoteAddress, SocketAddress localAddress, ChannelPromise promise) { + return ctx.connect(remoteAddress, localAddress, promise); + } + + @Override + public ChannelFuture disconnect(ChannelPromise promise) { + return ctx.disconnect(promise); + } + + @Override + public ChannelFuture close(ChannelPromise promise) { + return ctx.close(promise); + } + + @Override + public ChannelFuture deregister(ChannelPromise promise) { + return ctx.deregister(promise); + } + + @Override + public ChannelFuture write(Object msg) { + return ctx.write(msg); + } + + @Override + public ChannelFuture write(Object msg, ChannelPromise promise) { + return ctx.write(msg, promise); + } + + @Override + public ChannelFuture writeAndFlush(Object msg, ChannelPromise promise) { + return ctx.writeAndFlush(msg, promise); + } + + @Override + public ChannelFuture writeAndFlush(Object msg) { + return ctx.writeAndFlush(msg); + } + + @Override + public ChannelPromise newPromise() { + return ctx.newPromise(); + } + + @Override + public ChannelProgressivePromise newProgressivePromise() { + return ctx.newProgressivePromise(); + } + + @Override + public ChannelFuture newSucceededFuture() { + return ctx.newSucceededFuture(); + } + + @Override + public ChannelFuture newFailedFuture(Throwable cause) { + return ctx.newFailedFuture(cause); + } + + @Override + public ChannelPromise voidPromise() { + return ctx.voidPromise(); + } +} diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/HttpClientCodec.java b/codec-http/src/main/java/io/netty/handler/codec/http/HttpClientCodec.java index 990faf78da..ee7685fe78 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/HttpClientCodec.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/HttpClientCodec.java @@ -177,6 +177,9 @@ public final class HttpClientCodec extends CombinedChannelDuplexHandler out) throws Exception { + protected void handlerAdded0(ChannelHandlerContext ctx) { + if (failOnMissingResponse) { + context = new DelegatingChannelHandlerContext(ctx) { + @Override + public ChannelHandlerContext fireChannelRead(Object msg) { + decrement(msg); + + super.fireChannelRead(msg); + return this; + } + }; + } else { + context = ctx; + } + } + + @Override + protected void decode(ChannelHandlerContext ctx, ByteBuf buffer) throws Exception { if (done) { int readable = actualReadableBytes(); if (readable == 0) { @@ -196,16 +215,9 @@ public final class HttpClientCodec extends CombinedChannelDuplexHandler out) + protected void decode(final ChannelHandlerContext ctx, HttpObject msg) throws Exception { FullHttpResponse response = null; try { @@ -212,21 +211,30 @@ public class HttpClientUpgradeHandler extends HttpObjectAggregator { if (msg instanceof FullHttpResponse) { response = (FullHttpResponse) msg; + // Need to retain since the base class will release after returning from this method. - response.retain(); - out.add(response); + tryUpgrade(ctx, response.retain()); } else { // Call the base class to handle the aggregation of the full request. - super.decode(ctx, msg, out); - if (out.isEmpty()) { - // The full request hasn't been created yet, still awaiting more data. - return; - } - - assert out.size() == 1; - response = (FullHttpResponse) out.get(0); + super.decode(new DelegatingChannelHandlerContext(ctx) { + @Override + public ChannelHandlerContext fireChannelRead(Object msg) { + FullHttpResponse response = (FullHttpResponse) msg; + tryUpgrade(ctx, response); + return this; + } + }, msg); } + } catch (Throwable t) { + release(response); + ctx.fireExceptionCaught(t); + removeThisHandler(ctx); + } + } + + private void tryUpgrade(ChannelHandlerContext ctx, FullHttpResponse response) { + try { CharSequence upgradeHeader = response.headers().get(HttpHeaderNames.UPGRADE); if (upgradeHeader != null && !AsciiString.contentEqualsIgnoreCase(upgradeCodec.protocol(), upgradeHeader)) { throw new IllegalStateException( @@ -247,7 +255,6 @@ public class HttpClientUpgradeHandler extends HttpObjectAggregator { // We switched protocols, so we're done with the upgrade response. // Release it and clear it from the output. response.release(); - out.clear(); removeThisHandler(ctx); } catch (Throwable t) { release(response); diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/HttpContentDecoder.java b/codec-http/src/main/java/io/netty/handler/codec/http/HttpContentDecoder.java index d2513e4a5a..8f0c4a3727 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/HttpContentDecoder.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/HttpContentDecoder.java @@ -23,8 +23,6 @@ import io.netty.handler.codec.DecoderResult; import io.netty.handler.codec.MessageToMessageDecoder; import io.netty.util.ReferenceCountUtil; -import java.util.List; - /** * Decodes the content of the received {@link HttpRequest} and {@link HttpContent}. * The original content is replaced with the new content decoded by the @@ -54,123 +52,118 @@ public abstract class HttpContentDecoder extends MessageToMessageDecoder out) throws Exception { - try { - if (msg instanceof HttpResponse && ((HttpResponse) msg).status().code() == 100) { + protected void decode(ChannelHandlerContext ctx, HttpObject msg) throws Exception { + if (msg instanceof HttpResponse && ((HttpResponse) msg).status().code() == 100) { - if (!(msg instanceof LastHttpContent)) { + if (!(msg instanceof LastHttpContent)) { continueResponse = true; - } - // 100-continue response must be passed through. - out.add(ReferenceCountUtil.retain(msg)); - return; } + // 100-continue response must be passed through. + fireChannelRead(ctx, ReferenceCountUtil.retain(msg)); + return; + } - if (continueResponse) { - if (msg instanceof LastHttpContent) { - continueResponse = false; - } - // 100-continue response must be passed through. - out.add(ReferenceCountUtil.retain(msg)); - return; + if (continueResponse) { + if (msg instanceof LastHttpContent) { + continueResponse = false; } + // 100-continue response must be passed through. + fireChannelRead(ctx, ReferenceCountUtil.retain(msg)); + return; + } - if (msg instanceof HttpMessage) { - cleanup(); - final HttpMessage message = (HttpMessage) msg; - final HttpHeaders headers = message.headers(); - - // Determine the content encoding. - String contentEncoding = headers.get(HttpHeaderNames.CONTENT_ENCODING); - if (contentEncoding != null) { - contentEncoding = contentEncoding.trim(); - } else { - contentEncoding = IDENTITY; - } - decoder = newContentDecoder(contentEncoding); - - if (decoder == null) { - if (message instanceof HttpContent) { - ((HttpContent) message).retain(); - } - out.add(message); - return; - } - - // Remove content-length header: - // the correct value can be set only after all chunks are processed/decoded. - // If buffering is not an issue, add HttpObjectAggregator down the chain, it will set the header. - // Otherwise, rely on LastHttpContent message. - if (headers.contains(HttpHeaderNames.CONTENT_LENGTH)) { - headers.remove(HttpHeaderNames.CONTENT_LENGTH); - headers.set(HttpHeaderNames.TRANSFER_ENCODING, HttpHeaderValues.CHUNKED); - } - // Either it is already chunked or EOF terminated. - // See https://github.com/netty/netty/issues/5892 - - // set new content encoding, - CharSequence targetContentEncoding = getTargetContentEncoding(contentEncoding); - if (HttpHeaderValues.IDENTITY.contentEquals(targetContentEncoding)) { - // Do NOT set the 'Content-Encoding' header if the target encoding is 'identity' - // as per: http://tools.ietf.org/html/rfc2616#section-14.11 - headers.remove(HttpHeaderNames.CONTENT_ENCODING); - } else { - headers.set(HttpHeaderNames.CONTENT_ENCODING, targetContentEncoding); - } + if (msg instanceof HttpMessage) { + cleanup(); + final HttpMessage message = (HttpMessage) msg; + final HttpHeaders headers = message.headers(); + // Determine the content encoding. + String contentEncoding = headers.get(HttpHeaderNames.CONTENT_ENCODING); + if (contentEncoding != null) { + contentEncoding = contentEncoding.trim(); + } else { + contentEncoding = IDENTITY; + } + decoder = newContentDecoder(contentEncoding); + if (decoder == null) { if (message instanceof HttpContent) { - // If message is a full request or response object (headers + data), don't copy data part into out. - // Output headers only; data part will be decoded below. - // Note: "copy" object must not be an instance of LastHttpContent class, - // as this would (erroneously) indicate the end of the HttpMessage to other handlers. - HttpMessage copy; - if (message instanceof HttpRequest) { - HttpRequest r = (HttpRequest) message; // HttpRequest or FullHttpRequest - copy = new DefaultHttpRequest(r.protocolVersion(), r.method(), r.uri()); - } else if (message instanceof HttpResponse) { - HttpResponse r = (HttpResponse) message; // HttpResponse or FullHttpResponse - copy = new DefaultHttpResponse(r.protocolVersion(), r.status()); - } else { - throw new CodecException("Object of class " + message.getClass().getName() + - " is not an HttpRequest or HttpResponse"); - } - copy.headers().set(message.headers()); - copy.setDecoderResult(message.decoderResult()); - out.add(copy); - } else { - out.add(message); + ((HttpContent) message).retain(); } + fireChannelRead(ctx, message); + return; } - if (msg instanceof HttpContent) { - final HttpContent c = (HttpContent) msg; - if (decoder == null) { - out.add(c.retain()); - } else { - decodeContent(c, out); - } + // Remove content-length header: + // the correct value can be set only after all chunks are processed/decoded. + // If buffering is not an issue, add HttpObjectAggregator down the chain, it will set the header. + // Otherwise, rely on LastHttpContent message. + if (headers.contains(HttpHeaderNames.CONTENT_LENGTH)) { + headers.remove(HttpHeaderNames.CONTENT_LENGTH); + headers.set(HttpHeaderNames.TRANSFER_ENCODING, HttpHeaderValues.CHUNKED); + } + // Either it is already chunked or EOF terminated. + // See https://github.com/netty/netty/issues/5892 + + // set new content encoding, + CharSequence targetContentEncoding = getTargetContentEncoding(contentEncoding); + if (HttpHeaderValues.IDENTITY.contentEquals(targetContentEncoding)) { + // Do NOT set the 'Content-Encoding' header if the target encoding is 'identity' + // as per: http://tools.ietf.org/html/rfc2616#section-14.11 + headers.remove(HttpHeaderNames.CONTENT_ENCODING); + } else { + headers.set(HttpHeaderNames.CONTENT_ENCODING, targetContentEncoding); + } + + if (message instanceof HttpContent) { + // If message is a full request or response object (headers + data), don't copy data part into out. + // Output headers only; data part will be decoded below. + // Note: "copy" object must not be an instance of LastHttpContent class, + // as this would (erroneously) indicate the end of the HttpMessage to other handlers. + HttpMessage copy; + if (message instanceof HttpRequest) { + HttpRequest r = (HttpRequest) message; // HttpRequest or FullHttpRequest + copy = new DefaultHttpRequest(r.protocolVersion(), r.method(), r.uri()); + } else if (message instanceof HttpResponse) { + HttpResponse r = (HttpResponse) message; // HttpResponse or FullHttpResponse + copy = new DefaultHttpResponse(r.protocolVersion(), r.status()); + } else { + throw new CodecException("Object of class " + message.getClass().getName() + + " is not an HttpRequest or HttpResponse"); + } + copy.headers().set(message.headers()); + copy.setDecoderResult(message.decoderResult()); + fireChannelRead(ctx, copy); + } else { + fireChannelRead(ctx, message); + } + } + + if (msg instanceof HttpContent) { + final HttpContent c = (HttpContent) msg; + if (decoder == null) { + fireChannelRead(ctx, c.retain()); + } else { + decodeContent(ctx, c); } - } finally { - needRead = out.isEmpty(); } } - private void decodeContent(HttpContent c, List out) { + private void decodeContent(ChannelHandlerContext ctx, HttpContent c) { ByteBuf content = c.content(); - decode(content, out); + decode(ctx, content); if (c instanceof LastHttpContent) { - finishDecode(out); + finishDecode(ctx); LastHttpContent last = (LastHttpContent) c; // Generate an additional chunk if the decoder produced // the last product on closure, HttpHeaders headers = last.trailingHeaders(); if (headers.isEmpty()) { - out.add(LastHttpContent.EMPTY_LAST_CONTENT); + fireChannelRead(ctx, LastHttpContent.EMPTY_LAST_CONTENT); } else { - out.add(new ComposedLastHttpContent(headers, DecoderResult.SUCCESS)); + fireChannelRead(ctx, new ComposedLastHttpContent(headers, DecoderResult.SUCCESS)); } } } @@ -249,20 +242,20 @@ public abstract class HttpContentDecoder extends MessageToMessageDecoder out) { + private void decode(ChannelHandlerContext ctx, ByteBuf in) { // call retain here as it will call release after its written to the channel decoder.writeInbound(in.retain()); - fetchDecoderOutput(out); + fetchDecoderOutput(ctx); } - private void finishDecode(List out) { + private void finishDecode(ChannelHandlerContext ctx) { if (decoder.finish()) { - fetchDecoderOutput(out); + fetchDecoderOutput(ctx); } decoder = null; } - private void fetchDecoderOutput(List out) { + private void fetchDecoderOutput(ChannelHandlerContext ctx) { for (;;) { ByteBuf buf = decoder.readInbound(); if (buf == null) { @@ -272,7 +265,12 @@ public abstract class HttpContentDecoder extends MessageToMessageDecoder out) throws Exception { + protected void decode(ChannelHandlerContext ctx, HttpRequest msg) throws Exception { CharSequence acceptEncoding; List acceptEncodingHeaders = msg.headers().getAll(ACCEPT_ENCODING); switch (acceptEncodingHeaders.size()) { @@ -100,7 +100,7 @@ public abstract class HttpContentEncoder extends MessageToMessageCodec out) throws Exception { + protected void decode(ChannelHandlerContext ctx, ByteBuf buffer) throws Exception { if (resetRequested) { resetNow(); } @@ -207,7 +207,7 @@ public abstract class HttpObjectDecoder extends ByteToMessageDecoder { currentState = State.READ_HEADER; // fall-through } catch (Exception e) { - out.add(invalidMessage(buffer, e)); + ctx.fireChannelRead(invalidMessage(buffer, e)); return; } case READ_HEADER: try { @@ -220,8 +220,8 @@ public abstract class HttpObjectDecoder extends ByteToMessageDecoder { case SKIP_CONTROL_CHARS: // fast-path // No content is expected. - out.add(message); - out.add(LastHttpContent.EMPTY_LAST_CONTENT); + ctx.fireChannelRead(message); + ctx.fireChannelRead(LastHttpContent.EMPTY_LAST_CONTENT); resetNow(); return; case READ_CHUNK_SIZE: @@ -229,7 +229,7 @@ public abstract class HttpObjectDecoder extends ByteToMessageDecoder { throw new IllegalArgumentException("Chunked messages not supported"); } // Chunked encoding - generate HttpMessage first. HttpChunks will follow. - out.add(message); + ctx.fireChannelRead(message); return; default: /** @@ -240,8 +240,8 @@ public abstract class HttpObjectDecoder extends ByteToMessageDecoder { */ long contentLength = contentLength(); if (contentLength == 0 || contentLength == -1 && isDecodingRequest()) { - out.add(message); - out.add(LastHttpContent.EMPTY_LAST_CONTENT); + ctx.fireChannelRead(message); + ctx.fireChannelRead(LastHttpContent.EMPTY_LAST_CONTENT); resetNow(); return; } @@ -249,7 +249,7 @@ public abstract class HttpObjectDecoder extends ByteToMessageDecoder { assert nextState == State.READ_FIXED_LENGTH_CONTENT || nextState == State.READ_VARIABLE_LENGTH_CONTENT; - out.add(message); + ctx.fireChannelRead(message); if (nextState == State.READ_FIXED_LENGTH_CONTENT) { // chunkSize will be decreased as the READ_FIXED_LENGTH_CONTENT state reads data chunk by chunk. @@ -260,7 +260,7 @@ public abstract class HttpObjectDecoder extends ByteToMessageDecoder { return; } } catch (Exception e) { - out.add(invalidMessage(buffer, e)); + ctx.fireChannelRead(invalidMessage(buffer, e)); return; } case READ_VARIABLE_LENGTH_CONTENT: { @@ -268,7 +268,7 @@ public abstract class HttpObjectDecoder extends ByteToMessageDecoder { int toRead = buffer.readableBytes(); if (toRead > 0) { ByteBuf content = buffer.readRetainedSlice(toRead); - out.add(new DefaultHttpContent(content)); + ctx.fireChannelRead(new DefaultHttpContent(content)); } return; } @@ -294,10 +294,10 @@ public abstract class HttpObjectDecoder extends ByteToMessageDecoder { if (chunkSize == 0) { // Read all content. - out.add(new DefaultLastHttpContent(content, validateHeaders)); + ctx.fireChannelRead(new DefaultLastHttpContent(content, validateHeaders)); resetNow(); } else { - out.add(new DefaultHttpContent(content)); + ctx.fireChannelRead(new DefaultHttpContent(content)); } return; } @@ -319,7 +319,7 @@ public abstract class HttpObjectDecoder extends ByteToMessageDecoder { currentState = State.READ_CHUNKED_CONTENT; // fall-through } catch (Exception e) { - out.add(invalidChunk(buffer, e)); + ctx.fireChannelRead(invalidChunk(buffer, e)); return; } case READ_CHUNKED_CONTENT: { @@ -332,7 +332,7 @@ public abstract class HttpObjectDecoder extends ByteToMessageDecoder { HttpContent chunk = new DefaultHttpContent(buffer.readRetainedSlice(toRead)); chunkSize -= toRead; - out.add(chunk); + ctx.fireChannelRead(chunk); if (chunkSize != 0) { return; @@ -358,11 +358,11 @@ public abstract class HttpObjectDecoder extends ByteToMessageDecoder { if (trailer == null) { return; } - out.add(trailer); + ctx.fireChannelRead(trailer); resetNow(); return; } catch (Exception e) { - out.add(invalidChunk(buffer, e)); + ctx.fireChannelRead(invalidChunk(buffer, e)); return; } case BAD_MESSAGE: { @@ -377,7 +377,7 @@ public abstract class HttpObjectDecoder extends ByteToMessageDecoder { // other handler will replace this codec with the upgraded protocol codec to // take the traffic over at some point then. // See https://github.com/netty/netty/issues/2173 - out.add(buffer.readBytes(readableBytes)); + ctx.fireChannelRead(buffer.readBytes(readableBytes)); } break; } @@ -385,8 +385,8 @@ public abstract class HttpObjectDecoder extends ByteToMessageDecoder { } @Override - protected void decodeLast(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { - super.decodeLast(ctx, in, out); + protected void decodeLast(ChannelHandlerContext ctx, ByteBuf in) throws Exception { + super.decodeLast(ctx, in); if (resetRequested) { // If a reset was requested by decodeLast() we need to do it now otherwise we may produce a @@ -398,7 +398,7 @@ public abstract class HttpObjectDecoder extends ByteToMessageDecoder { boolean chunked = HttpUtil.isTransferEncodingChunked(message); if (currentState == State.READ_VARIABLE_LENGTH_CONTENT && !in.isReadable() && !chunked) { // End of connection. - out.add(LastHttpContent.EMPTY_LAST_CONTENT); + ctx.fireChannelRead(LastHttpContent.EMPTY_LAST_CONTENT); resetNow(); return; } @@ -406,7 +406,7 @@ public abstract class HttpObjectDecoder extends ByteToMessageDecoder { if (currentState == State.READ_HEADER) { // If we are still in the state of reading headers we need to create a new invalid message that // signals that the connection was closed before we received the headers. - out.add(invalidMessage(Unpooled.EMPTY_BUFFER, + ctx.fireChannelRead(invalidMessage(Unpooled.EMPTY_BUFFER, new PrematureChannelClosureException("Connection closed before received headers"))); resetNow(); return; @@ -425,7 +425,7 @@ public abstract class HttpObjectDecoder extends ByteToMessageDecoder { } if (!prematureClosure) { - out.add(LastHttpContent.EMPTY_LAST_CONTENT); + ctx.fireChannelRead(LastHttpContent.EMPTY_LAST_CONTENT); } resetNow(); } diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/HttpServerCodec.java b/codec-http/src/main/java/io/netty/handler/codec/http/HttpServerCodec.java index ccd3123727..9c8a238361 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/HttpServerCodec.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/HttpServerCodec.java @@ -20,7 +20,6 @@ import io.netty.channel.ChannelHandlerContext; import io.netty.channel.CombinedChannelDuplexHandler; import java.util.ArrayDeque; -import java.util.List; import java.util.Queue; /** @@ -81,6 +80,9 @@ public final class HttpServerCodec extends CombinedChannelDuplexHandler out) throws Exception { - int oldSize = out.size(); - super.decode(ctx, buffer, out); - int size = out.size(); - for (int i = oldSize; i < size; i++) { - Object obj = out.get(i); - if (obj instanceof HttpRequest) { - queue.add(((HttpRequest) obj).method()); + protected void decode(final ChannelHandlerContext ctx, ByteBuf buffer) throws Exception { + super.decode(context, buffer); + } + + @Override + protected void handlerAdded0(final ChannelHandlerContext ctx) { + context = new DelegatingChannelHandlerContext(ctx) { + + @Override + public ChannelHandlerContext fireChannelRead(Object msg) { + if (msg instanceof HttpRequest) { + queue.add(((HttpRequest) msg).method()); + } + super.fireChannelRead(msg); + return this; } - } + }; } } diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/HttpServerUpgradeHandler.java b/codec-http/src/main/java/io/netty/handler/codec/http/HttpServerUpgradeHandler.java index 5879b482cf..7fd1c5a61d 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/HttpServerUpgradeHandler.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/HttpServerUpgradeHandler.java @@ -206,45 +206,42 @@ public class HttpServerUpgradeHandler extends HttpObjectAggregator { } @Override - protected void decode(ChannelHandlerContext ctx, HttpObject msg, List out) + protected void decode(final ChannelHandlerContext ctx, HttpObject msg) throws Exception { // Determine if we're already handling an upgrade request or just starting a new one. handlingUpgrade |= isUpgradeRequest(msg); if (!handlingUpgrade) { // Not handling an upgrade request, just pass it to the next handler. ReferenceCountUtil.retain(msg); - out.add(msg); + ctx.fireChannelRead(msg); return; } FullHttpRequest fullRequest; if (msg instanceof FullHttpRequest) { fullRequest = (FullHttpRequest) msg; - ReferenceCountUtil.retain(msg); - out.add(msg); + tryUpgrade(ctx, fullRequest.retain()); } else { // Call the base class to handle the aggregation of the full request. - super.decode(ctx, msg, out); - if (out.isEmpty()) { - // The full request hasn't been created yet, still awaiting more data. - return; - } - - // Finished aggregating the full request, get it from the output list. - assert out.size() == 1; - handlingUpgrade = false; - fullRequest = (FullHttpRequest) out.get(0); + super.decode(new DelegatingChannelHandlerContext(ctx) { + @Override + public ChannelHandlerContext fireChannelRead(Object msg) { + // Finished aggregating the full request, get it from the output list. + handlingUpgrade = false; + tryUpgrade(ctx, (FullHttpRequest) msg); + return this; + } + }, msg); } + } - if (upgrade(ctx, fullRequest)) { - // The upgrade was successful, remove the message from the output list - // so that it's not propagated to the next handler. This request will - // be propagated as a user event instead. - out.clear(); + private void tryUpgrade(ChannelHandlerContext ctx, FullHttpRequest request) { + if (!upgrade(ctx, request)) { + + // The upgrade did not succeed, just allow the full request to propagate to the + // next handler. + ctx.fireChannelRead(request); } - - // The upgrade did not succeed, just allow the full request to propagate to the - // next handler. } /** diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocket00FrameDecoder.java b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocket00FrameDecoder.java index a4da84a981..63246d3e0e 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocket00FrameDecoder.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocket00FrameDecoder.java @@ -20,7 +20,6 @@ import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.ReplayingDecoder; import io.netty.handler.codec.TooLongFrameException; -import java.util.List; import java.util.Objects; import static io.netty.buffer.ByteBufUtil.readBytes; @@ -65,7 +64,7 @@ public class WebSocket00FrameDecoder extends ReplayingDecoder implements W } @Override - protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { + protected void decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception { // Discard all data received if closing handshake was received before. if (receivedClosingHandshake) { in.skipBytes(actualReadableBytes()); @@ -84,7 +83,7 @@ public class WebSocket00FrameDecoder extends ReplayingDecoder implements W } if (frame != null) { - out.add(frame); + ctx.fireChannelRead(frame); } } diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocket08FrameDecoder.java b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocket08FrameDecoder.java index 19dc04f107..5d55a6dcf5 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocket08FrameDecoder.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocket08FrameDecoder.java @@ -63,7 +63,6 @@ import io.netty.util.internal.logging.InternalLogger; import io.netty.util.internal.logging.InternalLoggerFactory; import java.nio.ByteOrder; -import java.util.List; import java.util.Objects; import static io.netty.buffer.ByteBufUtil.readBytes; @@ -158,7 +157,7 @@ public class WebSocket08FrameDecoder extends ByteToMessageDecoder } @Override - protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { + protected void decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception { // Discard all data received if closing handshake was received before. if (receivedClosingHandshake) { in.skipBytes(actualReadableBytes()); @@ -325,20 +324,23 @@ public class WebSocket08FrameDecoder extends ByteToMessageDecoder // Processing ping/pong/close frames because they cannot be // fragmented if (frameOpcode == OPCODE_PING) { - out.add(new PingWebSocketFrame(frameFinalFlag, frameRsv, payloadBuffer)); + WebSocketFrame frame = new PingWebSocketFrame(frameFinalFlag, frameRsv, payloadBuffer); payloadBuffer = null; + ctx.fireChannelRead(frame); return; } if (frameOpcode == OPCODE_PONG) { - out.add(new PongWebSocketFrame(frameFinalFlag, frameRsv, payloadBuffer)); + WebSocketFrame frame = new PongWebSocketFrame(frameFinalFlag, frameRsv, payloadBuffer); payloadBuffer = null; + ctx.fireChannelRead(frame); return; } if (frameOpcode == OPCODE_CLOSE) { receivedClosingHandshake = true; checkCloseFrameBody(ctx, payloadBuffer); - out.add(new CloseWebSocketFrame(frameFinalFlag, frameRsv, payloadBuffer)); + WebSocketFrame frame = new CloseWebSocketFrame(frameFinalFlag, frameRsv, payloadBuffer); payloadBuffer = null; + ctx.fireChannelRead(frame); return; } @@ -357,17 +359,19 @@ public class WebSocket08FrameDecoder extends ByteToMessageDecoder // Return the frame if (frameOpcode == OPCODE_TEXT) { - out.add(new TextWebSocketFrame(frameFinalFlag, frameRsv, payloadBuffer)); + WebSocketFrame frame = new TextWebSocketFrame(frameFinalFlag, frameRsv, payloadBuffer); payloadBuffer = null; + ctx.fireChannelRead(frame); return; } else if (frameOpcode == OPCODE_BINARY) { - out.add(new BinaryWebSocketFrame(frameFinalFlag, frameRsv, payloadBuffer)); + WebSocketFrame frame = new BinaryWebSocketFrame(frameFinalFlag, frameRsv, payloadBuffer); payloadBuffer = null; + ctx.fireChannelRead(frame); return; } else if (frameOpcode == OPCODE_CONT) { - out.add(new ContinuationWebSocketFrame(frameFinalFlag, frameRsv, - payloadBuffer)); + WebSocketFrame frame = new ContinuationWebSocketFrame(frameFinalFlag, frameRsv, payloadBuffer); payloadBuffer = null; + ctx.fireChannelRead(frame); return; } else { throw new UnsupportedOperationException("Cannot decode web socket frame with opcode: " diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketClientProtocolHandler.java b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketClientProtocolHandler.java index 4c0e43e71c..b3938e5225 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketClientProtocolHandler.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketClientProtocolHandler.java @@ -21,7 +21,6 @@ import io.netty.channel.ChannelPipeline; import io.netty.handler.codec.http.HttpHeaders; import java.net.URI; -import java.util.List; import java.util.Objects; import static io.netty.handler.codec.http.websocketx.WebSocketClientProtocolConfig.DEFAULT; @@ -357,12 +356,12 @@ public class WebSocketClientProtocolHandler extends WebSocketProtocolHandler { } @Override - protected void decode(ChannelHandlerContext ctx, WebSocketFrame frame, List out) throws Exception { + protected void decode(ChannelHandlerContext ctx, WebSocketFrame frame) throws Exception { if (clientConfig.handleCloseFrames() && frame instanceof CloseWebSocketFrame) { ctx.close(); return; } - super.decode(ctx, frame, out); + super.decode(ctx, frame); } @Override diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketProtocolHandler.java b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketProtocolHandler.java index 84f96ea344..bfbb719c48 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketProtocolHandler.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketProtocolHandler.java @@ -44,7 +44,7 @@ abstract class WebSocketProtocolHandler extends MessageToMessageDecoder out) throws Exception { + protected void decode(ChannelHandlerContext ctx, WebSocketFrame frame) throws Exception { if (frame instanceof PingWebSocketFrame) { frame.content().retain(); ctx.channel().writeAndFlush(new PongWebSocketFrame(frame.content())); @@ -56,7 +56,7 @@ abstract class WebSocketProtocolHandler extends MessageToMessageDecoder out) throws Exception { + protected void decode(ChannelHandlerContext ctx, WebSocketFrame frame) throws Exception { if (serverConfig.handleCloseFrames() && frame instanceof CloseWebSocketFrame) { WebSocketServerHandshaker handshaker = getHandshaker(ctx.channel()); if (handshaker != null) { @@ -246,7 +245,7 @@ public class WebSocketServerProtocolHandler extends WebSocketProtocolHandler { } return; } - super.decode(ctx, frame, out); + super.decode(ctx, frame); } @Override diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/extensions/compression/DeflateDecoder.java b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/extensions/compression/DeflateDecoder.java index 880d5e1a77..4f914e08f6 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/extensions/compression/DeflateDecoder.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/extensions/compression/DeflateDecoder.java @@ -30,7 +30,6 @@ import io.netty.handler.codec.http.websocketx.WebSocketFrame; import io.netty.handler.codec.http.websocketx.extensions.WebSocketExtensionDecoder; import io.netty.handler.codec.http.websocketx.extensions.WebSocketExtensionFilter; -import java.util.List; import java.util.Objects; /** @@ -75,7 +74,7 @@ abstract class DeflateDecoder extends WebSocketExtensionDecoder { protected abstract int newRsv(WebSocketFrame msg); @Override - protected void decode(ChannelHandlerContext ctx, WebSocketFrame msg, List out) throws Exception { + protected void decode(ChannelHandlerContext ctx, WebSocketFrame msg) throws Exception { final ByteBuf decompressedContent = decompressContent(ctx, msg); final WebSocketFrame outMsg; @@ -89,7 +88,7 @@ abstract class DeflateDecoder extends WebSocketExtensionDecoder { throw new CodecException("unexpected frame type: " + msg.getClass().getName()); } - out.add(outMsg); + ctx.fireChannelRead(outMsg); } @Override diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/extensions/compression/PerMessageDeflateDecoder.java b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/extensions/compression/PerMessageDeflateDecoder.java index d2512bb2b6..92d609b01c 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/extensions/compression/PerMessageDeflateDecoder.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/extensions/compression/PerMessageDeflateDecoder.java @@ -23,8 +23,6 @@ import io.netty.handler.codec.http.websocketx.WebSocketFrame; import io.netty.handler.codec.http.websocketx.extensions.WebSocketExtension; import io.netty.handler.codec.http.websocketx.extensions.WebSocketExtensionFilter; -import java.util.List; - /** * Per-message implementation of deflate decompressor. */ @@ -82,11 +80,11 @@ class PerMessageDeflateDecoder extends DeflateDecoder { } @Override - protected void decode(ChannelHandlerContext ctx, WebSocketFrame msg, - List out) throws Exception { - super.decode(ctx, msg, out); + protected void decode(ChannelHandlerContext ctx, WebSocketFrame msg) throws Exception { + boolean isFinal = msg.isFinalFragment(); + super.decode(ctx, msg); - if (msg.isFinalFragment()) { + if (isFinal) { compressing = false; } else if (msg instanceof TextWebSocketFrame || msg instanceof BinaryWebSocketFrame) { compressing = true; diff --git a/codec-http/src/test/java/io/netty/handler/codec/http/websocketx/WebSocket08FrameDecoderTest.java b/codec-http/src/test/java/io/netty/handler/codec/http/websocketx/WebSocket08FrameDecoderTest.java index fc80180378..cac995ec5e 100644 --- a/codec-http/src/test/java/io/netty/handler/codec/http/websocketx/WebSocket08FrameDecoderTest.java +++ b/codec-http/src/test/java/io/netty/handler/codec/http/websocketx/WebSocket08FrameDecoderTest.java @@ -32,6 +32,7 @@ public class WebSocket08FrameDecoderTest { public void channelInactive() throws Exception { final WebSocket08FrameDecoder decoder = new WebSocket08FrameDecoder(true, true, 65535, false); final ChannelHandlerContext ctx = mock(ChannelHandlerContext.class); + decoder.handlerAdded(ctx); decoder.channelInactive(ctx); verify(ctx).fireChannelInactive(); } diff --git a/codec-http/src/test/java/io/netty/handler/codec/http/websocketx/WebSocketHandshakeHandOverTest.java b/codec-http/src/test/java/io/netty/handler/codec/http/websocketx/WebSocketHandshakeHandOverTest.java index 86b449c80a..8d5790e24b 100644 --- a/codec-http/src/test/java/io/netty/handler/codec/http/websocketx/WebSocketHandshakeHandOverTest.java +++ b/codec-http/src/test/java/io/netty/handler/codec/http/websocketx/WebSocketHandshakeHandOverTest.java @@ -33,7 +33,6 @@ import org.junit.Before; import org.junit.Test; import java.net.URI; -import java.util.List; import java.util.concurrent.CompletionException; import static org.junit.Assert.*; @@ -58,12 +57,12 @@ public class WebSocketHandshakeHandOverTest { } @Override - protected void decode(ChannelHandlerContext ctx, WebSocketFrame frame, List out) throws Exception { + protected void decode(ChannelHandlerContext ctx, WebSocketFrame frame) throws Exception { if (frame instanceof CloseWebSocketFrame) { serverReceivedCloseHandshake = true; return; } - super.decode(ctx, frame, out); + super.decode(ctx, frame); } } diff --git a/codec-http/src/test/java/io/netty/handler/codec/http/websocketx/extensions/WebSocketExtensionTestUtil.java b/codec-http/src/test/java/io/netty/handler/codec/http/websocketx/extensions/WebSocketExtensionTestUtil.java index 38867febd1..d5f35910f6 100644 --- a/codec-http/src/test/java/io/netty/handler/codec/http/websocketx/extensions/WebSocketExtensionTestUtil.java +++ b/codec-http/src/test/java/io/netty/handler/codec/http/websocketx/extensions/WebSocketExtensionTestUtil.java @@ -97,8 +97,7 @@ public final class WebSocketExtensionTestUtil { static class DummyDecoder extends WebSocketExtensionDecoder { @Override - protected void decode(ChannelHandlerContext ctx, WebSocketFrame msg, - List out) throws Exception { + protected void decode(ChannelHandlerContext ctx, WebSocketFrame msg) throws Exception { // unused } } @@ -113,8 +112,7 @@ public final class WebSocketExtensionTestUtil { static class Dummy2Decoder extends WebSocketExtensionDecoder { @Override - protected void decode(ChannelHandlerContext ctx, WebSocketFrame msg, - List out) throws Exception { + protected void decode(ChannelHandlerContext ctx, WebSocketFrame msg) throws Exception { // unused } } diff --git a/codec-http2/src/main/java/io/netty/handler/codec/http2/CleartextHttp2ServerUpgradeHandler.java b/codec-http2/src/main/java/io/netty/handler/codec/http2/CleartextHttp2ServerUpgradeHandler.java index 25efbdad06..9b543d63ee 100644 --- a/codec-http2/src/main/java/io/netty/handler/codec/http2/CleartextHttp2ServerUpgradeHandler.java +++ b/codec-http2/src/main/java/io/netty/handler/codec/http2/CleartextHttp2ServerUpgradeHandler.java @@ -25,8 +25,6 @@ import io.netty.handler.codec.http.HttpServerCodec; import io.netty.handler.codec.http.HttpServerUpgradeHandler; import io.netty.util.internal.UnstableApi; -import java.util.List; - import static io.netty.buffer.Unpooled.unreleasableBuffer; import static io.netty.handler.codec.http2.Http2CodecUtil.connectionPrefaceBuf; @@ -77,7 +75,7 @@ public final class CleartextHttp2ServerUpgradeHandler extends ChannelHandlerAdap */ private final class PriorKnowledgeHandler extends ByteToMessageDecoder { @Override - protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { + protected void decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception { int prefaceLength = CONNECTION_PREFACE.readableBytes(); int bytesRead = Math.min(in.readableBytes(), prefaceLength); diff --git a/codec-http2/src/main/java/io/netty/handler/codec/http2/DecoratingHttp2ConnectionDecoder.java b/codec-http2/src/main/java/io/netty/handler/codec/http2/DecoratingHttp2ConnectionDecoder.java index d0872f43ed..43441ad553 100644 --- a/codec-http2/src/main/java/io/netty/handler/codec/http2/DecoratingHttp2ConnectionDecoder.java +++ b/codec-http2/src/main/java/io/netty/handler/codec/http2/DecoratingHttp2ConnectionDecoder.java @@ -59,8 +59,8 @@ public class DecoratingHttp2ConnectionDecoder implements Http2ConnectionDecoder } @Override - public void decodeFrame(ChannelHandlerContext ctx, ByteBuf in, List out) throws Http2Exception { - delegate.decodeFrame(ctx, in, out); + public void decodeFrame(ChannelHandlerContext ctx, ByteBuf in) throws Http2Exception { + delegate.decodeFrame(ctx, in); } @Override diff --git a/codec-http2/src/main/java/io/netty/handler/codec/http2/DefaultHttp2ConnectionDecoder.java b/codec-http2/src/main/java/io/netty/handler/codec/http2/DefaultHttp2ConnectionDecoder.java index 2371212768..d13e4f6cb4 100644 --- a/codec-http2/src/main/java/io/netty/handler/codec/http2/DefaultHttp2ConnectionDecoder.java +++ b/codec-http2/src/main/java/io/netty/handler/codec/http2/DefaultHttp2ConnectionDecoder.java @@ -22,8 +22,6 @@ import io.netty.util.internal.UnstableApi; import io.netty.util.internal.logging.InternalLogger; import io.netty.util.internal.logging.InternalLoggerFactory; -import java.util.List; - import static io.netty.handler.codec.http.HttpStatusClass.INFORMATIONAL; import static io.netty.handler.codec.http2.Http2CodecUtil.DEFAULT_PRIORITY_WEIGHT; import static io.netty.handler.codec.http2.Http2Error.INTERNAL_ERROR; @@ -185,7 +183,7 @@ public class DefaultHttp2ConnectionDecoder implements Http2ConnectionDecoder { } @Override - public void decodeFrame(ChannelHandlerContext ctx, ByteBuf in, List out) throws Http2Exception { + public void decodeFrame(ChannelHandlerContext ctx, ByteBuf in) throws Http2Exception { frameReader.readFrame(ctx, in, internalFrameListener); } diff --git a/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2ConnectionDecoder.java b/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2ConnectionDecoder.java index 4505f85f6d..3f6559a790 100644 --- a/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2ConnectionDecoder.java +++ b/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2ConnectionDecoder.java @@ -60,7 +60,7 @@ public interface Http2ConnectionDecoder extends Closeable { /** * Called by the {@link Http2ConnectionHandler} to decode the next frame from the input buffer. */ - void decodeFrame(ChannelHandlerContext ctx, ByteBuf in, List out) throws Http2Exception; + void decodeFrame(ChannelHandlerContext ctx, ByteBuf in) throws Http2Exception; /** * Gets the local settings for this endpoint of the HTTP/2 connection. diff --git a/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2ConnectionHandler.java b/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2ConnectionHandler.java index d6f0b18ddc..9684fb27e9 100644 --- a/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2ConnectionHandler.java +++ b/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2ConnectionHandler.java @@ -32,7 +32,6 @@ import io.netty.util.internal.logging.InternalLogger; import io.netty.util.internal.logging.InternalLoggerFactory; import java.net.SocketAddress; -import java.util.List; import java.util.concurrent.TimeUnit; import static io.netty.buffer.ByteBufUtil.hexDump; @@ -193,7 +192,7 @@ public class Http2ConnectionHandler extends ByteToMessageDecoder implements Http } private abstract class BaseDecoder { - public abstract void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception; + public abstract void decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception; public void handlerRemoved(ChannelHandlerContext ctx) throws Exception { } public void channelActive(ChannelHandlerContext ctx) throws Exception { } @@ -232,12 +231,12 @@ public class Http2ConnectionHandler extends ByteToMessageDecoder implements Http } @Override - public void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { + public void decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception { try { if (ctx.channel().isActive() && readClientPrefaceString(in) && verifyFirstFrameIsSettings(in)) { // After the preface is read, it is time to hand over control to the post initialized decoder. byteDecoder = new FrameDecoder(); - byteDecoder.decode(ctx, in, out); + byteDecoder.decode(ctx, in); } } catch (Throwable e) { onError(ctx, false, e); @@ -371,9 +370,9 @@ public class Http2ConnectionHandler extends ByteToMessageDecoder implements Http private final class FrameDecoder extends BaseDecoder { @Override - public void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { + public void decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception { try { - decoder.decodeFrame(ctx, in, out); + decoder.decodeFrame(ctx, in); } catch (Throwable e) { onError(ctx, false, e); } @@ -381,7 +380,7 @@ public class Http2ConnectionHandler extends ByteToMessageDecoder implements Http } @Override - public void handlerAdded(ChannelHandlerContext ctx) throws Exception { + public void handlerAdded0(ChannelHandlerContext ctx) throws Exception { // Initialize the encoder, decoder, flow controllers, and internal state. encoder.lifecycleManager(this); decoder.lifecycleManager(this); @@ -432,8 +431,8 @@ public class Http2ConnectionHandler extends ByteToMessageDecoder implements Http } @Override - protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { - byteDecoder.decode(ctx, in, out); + protected void decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception { + byteDecoder.decode(ctx, in); } @Override diff --git a/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2FrameCodec.java b/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2FrameCodec.java index 2040389390..4b275eb071 100644 --- a/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2FrameCodec.java +++ b/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2FrameCodec.java @@ -209,10 +209,9 @@ public class Http2FrameCodec extends Http2ConnectionHandler { } @Override - public final void handlerAdded(ChannelHandlerContext ctx) throws Exception { + public void handlerAdded0(ChannelHandlerContext ctx) throws Exception { + super.handlerAdded0(ctx); this.ctx = ctx; - super.handlerAdded(ctx); - handlerAdded0(ctx); // Must be after Http2ConnectionHandler does its initialization in handlerAdded above. // The server will not send a connection preface so we are good to send a window update. Http2Connection connection = connection(); @@ -237,10 +236,6 @@ public class Http2FrameCodec extends Http2ConnectionHandler { } } - void handlerAdded0(@SuppressWarnings("unsed") ChannelHandlerContext ctx) throws Exception { - // sub-class can override this for extra steps that needs to be done when the handler is added. - } - /** * Handles the cleartext HTTP upgrade event. If an upgrade occurred, sends a simple response via * HTTP/2 on stream 1 (the stream specifically reserved for cleartext HTTP upgrade). diff --git a/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2MultiplexCodec.java b/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2MultiplexCodec.java index fe38382962..a4912bb265 100644 --- a/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2MultiplexCodec.java +++ b/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2MultiplexCodec.java @@ -124,6 +124,7 @@ public class Http2MultiplexCodec extends Http2FrameCodec { throw new IllegalStateException("EventExecutor must be EventLoop of Channel"); } this.ctx = ctx; + super.handlerAdded0(ctx); } @Override diff --git a/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2StreamFrameToHttpObjectCodec.java b/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2StreamFrameToHttpObjectCodec.java index e13a45fe01..054cf96c69 100644 --- a/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2StreamFrameToHttpObjectCodec.java +++ b/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2StreamFrameToHttpObjectCodec.java @@ -82,7 +82,7 @@ public class Http2StreamFrameToHttpObjectCodec extends MessageToMessageCodec out) throws Exception { + protected void decode(ChannelHandlerContext ctx, Http2StreamFrame frame) throws Exception { if (frame instanceof Http2HeadersFrame) { Http2HeadersFrame headersFrame = (Http2HeadersFrame) frame; Http2Headers headers = headersFrame.headers(); @@ -95,7 +95,7 @@ public class Http2StreamFrameToHttpObjectCodec extends MessageToMessageCodec internalListener = ArgumentCaptor.forClass(Http2FrameListener.class); doNothing().when(reader).readFrame(eq(ctx), any(ByteBuf.class), internalListener.capture()); - decoder.decodeFrame(ctx, EMPTY_BUFFER, Collections.emptyList()); + decoder.decodeFrame(ctx, EMPTY_BUFFER); return internalListener.getValue(); } diff --git a/codec-http2/src/test/java/io/netty/handler/codec/http2/Http2ConnectionHandlerTest.java b/codec-http2/src/test/java/io/netty/handler/codec/http2/Http2ConnectionHandlerTest.java index 61266f0098..3e0d341651 100644 --- a/codec-http2/src/test/java/io/netty/handler/codec/http2/Http2ConnectionHandlerTest.java +++ b/codec-http2/src/test/java/io/netty/handler/codec/http2/Http2ConnectionHandlerTest.java @@ -39,9 +39,7 @@ import org.junit.After; import org.junit.Before; import org.junit.Test; import org.mockito.ArgumentCaptor; -import org.mockito.ArgumentMatchers; import org.mockito.Mock; -import org.mockito.Mockito; import org.mockito.MockitoAnnotations; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; @@ -49,7 +47,6 @@ import org.mockito.stubbing.Answer; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicReference; import static io.netty.buffer.Unpooled.copiedBuffer; import static io.netty.handler.codec.http2.Http2CodecUtil.connectionPrefaceBuf; @@ -192,7 +189,8 @@ public class Http2ConnectionHandlerTest { when(connection.stream(STREAM_ID)).thenReturn(stream); when(connection.goAwaySent(anyInt(), anyLong(), any(ByteBuf.class))).thenReturn(true); when(stream.open(anyBoolean())).thenReturn(stream); - when(encoder.writeSettings(eq(ctx), any(Http2Settings.class), eq(promise))).thenReturn(future); + when(encoder.writeSettings(any(ChannelHandlerContext.class), + any(Http2Settings.class), eq(promise))).thenReturn(future); when(ctx.alloc()).thenReturn(UnpooledByteBufAllocator.DEFAULT); when(ctx.channel()).thenReturn(channel); when(ctx.newSucceededFuture()).thenReturn(future); @@ -293,7 +291,7 @@ public class Http2ConnectionHandlerTest { handler = newHandler(); handler.channelRead(ctx, copiedBuffer("BAD_PREFACE", UTF_8)); ArgumentCaptor captor = ArgumentCaptor.forClass(ByteBuf.class); - verify(frameWriter).writeGoAway(eq(ctx), eq(0), eq(PROTOCOL_ERROR.code()), + verify(frameWriter).writeGoAway(any(ChannelHandlerContext.class), eq(0), eq(PROTOCOL_ERROR.code()), captor.capture(), eq(promise)); assertEquals(0, captor.getValue().refCnt()); } @@ -304,7 +302,7 @@ public class Http2ConnectionHandlerTest { handler = newHandler(); handler.channelRead(ctx, copiedBuffer("GET /path HTTP/1.1", US_ASCII)); ArgumentCaptor captor = ArgumentCaptor.forClass(ByteBuf.class); - verify(frameWriter).writeGoAway(eq(ctx), eq(0), eq(PROTOCOL_ERROR.code()), + verify(frameWriter).writeGoAway(any(ChannelHandlerContext.class), eq(0), eq(PROTOCOL_ERROR.code()), captor.capture(), eq(promise)); assertEquals(0, captor.getValue().refCnt()); assertTrue(goAwayDebugCap.contains("/path")); @@ -320,8 +318,8 @@ public class Http2ConnectionHandlerTest { ByteBuf buf = Unpooled.buffer().writeBytes(connectionPrefaceBuf()).writeZero(10); handler.channelRead(ctx, buf); ArgumentCaptor captor = ArgumentCaptor.forClass(ByteBuf.class); - verify(frameWriter, atLeastOnce()).writeGoAway(eq(ctx), eq(0), eq(PROTOCOL_ERROR.code()), - captor.capture(), eq(promise)); + verify(frameWriter, atLeastOnce()).writeGoAway(any(ChannelHandlerContext.class), + eq(0), eq(PROTOCOL_ERROR.code()), captor.capture(), eq(promise)); assertEquals(0, captor.getValue().refCnt()); } @@ -332,7 +330,7 @@ public class Http2ConnectionHandlerTest { ByteBuf prefacePlusSome = addSettingsHeader(Unpooled.buffer().writeBytes(connectionPrefaceBuf())); handler.channelRead(ctx, prefacePlusSome); verify(decoder, atLeastOnce()).decodeFrame(any(ChannelHandlerContext.class), - any(ByteBuf.class), ArgumentMatchers.any()); + any(ByteBuf.class)); } @Test @@ -344,7 +342,7 @@ public class Http2ConnectionHandlerTest { ByteBuf preface = connectionPrefaceBuf(); handler.channelRead(ctx, preface); verify(decoder, never()).decodeFrame(any(ChannelHandlerContext.class), - any(ByteBuf.class), ArgumentMatchers.any()); + any(ByteBuf.class)); // Now remove and add the handler...this is setting up the test condition. handler.handlerRemoved(ctx); @@ -353,7 +351,7 @@ public class Http2ConnectionHandlerTest { // Now verify we can continue as normal, reading connection preface plus more. ByteBuf prefacePlusSome = addSettingsHeader(Unpooled.buffer().writeBytes(connectionPrefaceBuf())); handler.channelRead(ctx, prefacePlusSome); - verify(decoder, atLeastOnce()).decodeFrame(eq(ctx), any(ByteBuf.class), ArgumentMatchers.any()); + verify(decoder, atLeastOnce()).decodeFrame(any(ChannelHandlerContext.class), any(ByteBuf.class)); } @SuppressWarnings("unchecked") diff --git a/codec-http2/src/test/java/io/netty/handler/codec/http2/Http2FrameCodecTest.java b/codec-http2/src/test/java/io/netty/handler/codec/http2/Http2FrameCodecTest.java index 91c69f020c..5983031435 100644 --- a/codec-http2/src/test/java/io/netty/handler/codec/http2/Http2FrameCodecTest.java +++ b/codec-http2/src/test/java/io/netty/handler/codec/http2/Http2FrameCodecTest.java @@ -70,10 +70,8 @@ import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static org.mockito.Mockito.any; -import static org.mockito.Mockito.anyBoolean; import static org.mockito.Mockito.anyInt; import static org.mockito.Mockito.anyLong; -import static org.mockito.Mockito.anyShort; import static org.mockito.Mockito.eq; import static org.mockito.Mockito.never; import static org.mockito.Mockito.same; @@ -141,13 +139,13 @@ public class Http2FrameCodecTest { channel.pipeline().fireChannelActive(); // Handshake - verify(frameWriter).writeSettings(eqFrameCodecCtx(), anyHttp2Settings(), anyChannelPromise()); + verify(frameWriter).writeSettings(any(ChannelHandlerContext.class), anyHttp2Settings(), anyChannelPromise()); verifyNoMoreInteractions(frameWriter); channel.writeInbound(Http2CodecUtil.connectionPrefaceBuf()); frameInboundWriter.writeInboundSettings(initialRemoteSettings); - verify(frameWriter).writeSettingsAck(eqFrameCodecCtx(), anyChannelPromise()); + verify(frameWriter).writeSettingsAck(any(ChannelHandlerContext.class), anyChannelPromise()); frameInboundWriter.writeInboundSettingsAck(); @@ -177,10 +175,10 @@ public class Http2FrameCodecTest { channel.writeOutbound(new DefaultHttp2HeadersFrame(response, true, 27).stream(stream2)); verify(frameWriter).writeHeaders( - eqFrameCodecCtx(), eq(1), eq(response), + any(ChannelHandlerContext.class), eq(1), eq(response), eq(27), eq(true), anyChannelPromise()); verify(frameWriter, never()).writeRstStream( - eqFrameCodecCtx(), anyInt(), anyLong(), anyChannelPromise()); + any(ChannelHandlerContext.class), anyInt(), anyLong(), anyChannelPromise()); assertEquals(State.CLOSED, stream.state()); event = inboundHandler.readInboundMessageOrUserEvent(); @@ -206,10 +204,10 @@ public class Http2FrameCodecTest { channel.writeOutbound(new DefaultHttp2HeadersFrame(response, true, 27).stream(stream2)); verify(frameWriter).writeHeaders( - eqFrameCodecCtx(), eq(1), eq(response), + any(ChannelHandlerContext.class), eq(1), eq(response), eq(27), eq(true), anyChannelPromise()); verify(frameWriter, never()).writeRstStream( - eqFrameCodecCtx(), anyInt(), anyLong(), anyChannelPromise()); + any(ChannelHandlerContext.class), anyInt(), anyLong(), anyChannelPromise()); assertEquals(State.CLOSED, stream.state()); assertTrue(channel.isActive()); @@ -264,13 +262,13 @@ public class Http2FrameCodecTest { assertNull(inboundHandler.readInbound()); - channel.writeOutbound(new DefaultHttp2HeadersFrame(response, false).stream(stream2)); - verify(frameWriter).writeHeaders(eqFrameCodecCtx(), eq(1), eq(response), - eq(0), eq(false), anyChannelPromise()); + inboundHandler.writeOutbound(new DefaultHttp2HeadersFrame(response, false).stream(stream2)); + verify(frameWriter).writeHeaders(any(ChannelHandlerContext.class), eq(1), eq(response), eq(0), + eq(false), anyChannelPromise()); channel.writeOutbound(new DefaultHttp2DataFrame(bb("world"), true, 27).stream(stream2)); ArgumentCaptor outboundData = ArgumentCaptor.forClass(ByteBuf.class); - verify(frameWriter).writeData(eqFrameCodecCtx(), eq(1), outboundData.capture(), eq(27), + verify(frameWriter).writeData(any(ChannelHandlerContext.class), eq(1), outboundData.capture(), eq(27), eq(true), anyChannelPromise()); ByteBuf bb = bb("world"); @@ -279,7 +277,8 @@ public class Http2FrameCodecTest { bb.release(); outboundData.getValue().release(); - verify(frameWriter, never()).writeRstStream(eqFrameCodecCtx(), anyInt(), anyLong(), anyChannelPromise()); + verify(frameWriter, never()).writeRstStream(any(ChannelHandlerContext.class), + anyInt(), anyLong(), anyChannelPromise()); assertTrue(channel.isActive()); } @@ -300,7 +299,7 @@ public class Http2FrameCodecTest { assertEquals(3, stream2.id()); channel.writeOutbound(new DefaultHttp2ResetFrame(314 /* non-standard error */).stream(stream2)); - verify(frameWriter).writeRstStream(eqFrameCodecCtx(), eq(3), eq(314L), anyChannelPromise()); + verify(frameWriter).writeRstStream(any(ChannelHandlerContext.class), eq(3), eq(314L), anyChannelPromise()); assertEquals(State.CLOSED, stream.state()); assertTrue(channel.isActive()); } @@ -341,7 +340,7 @@ public class Http2FrameCodecTest { goAwayFrame.setExtraStreamIds(2); channel.writeOutbound(goAwayFrame); - verify(frameWriter).writeGoAway(eqFrameCodecCtx(), eq(7), + verify(frameWriter).writeGoAway(any(ChannelHandlerContext.class), eq(7), eq(NO_ERROR.code()), eq(expected), anyChannelPromise()); assertEquals(State.OPEN, stream.state()); assertTrue(channel.isActive()); @@ -405,7 +404,7 @@ public class Http2FrameCodecTest { channel.writeOutbound(goAwayFrame); // When the last stream id computation overflows, the last stream id should just be set to 2^31 - 1. - verify(frameWriter).writeGoAway(eqFrameCodecCtx(), eq(Integer.MAX_VALUE), + verify(frameWriter).writeGoAway(any(ChannelHandlerContext.class), eq(Integer.MAX_VALUE), eq(NO_ERROR.code()), eq(debugData), anyChannelPromise()); debugData.release(); assertEquals(State.OPEN, stream.state()); @@ -581,7 +580,7 @@ public class Http2FrameCodecTest { unknownFrame.stream(stream); channel.write(unknownFrame); - verify(frameWriter).writeFrame(eqFrameCodecCtx(), eq(unknownFrame.frameType()), + verify(frameWriter).writeFrame(any(ChannelHandlerContext.class), eq(unknownFrame.frameType()), eq(unknownFrame.stream().id()), eq(unknownFrame.flags()), eq(buffer), any(ChannelPromise.class)); } @@ -590,7 +589,7 @@ public class Http2FrameCodecTest { Http2Settings settings = new Http2Settings(); channel.write(new DefaultHttp2SettingsFrame(settings)); - verify(frameWriter).writeSettings(eqFrameCodecCtx(), same(settings), any(ChannelPromise.class)); + verify(frameWriter).writeSettings(any(ChannelHandlerContext.class), same(settings), any(ChannelPromise.class)); } @Test(timeout = 5000) @@ -751,7 +750,8 @@ public class Http2FrameCodecTest { public void sendPing() { channel.writeAndFlush(new DefaultHttp2PingFrame(12345)); - verify(frameWriter).writePing(eqFrameCodecCtx(), eq(false), eq(12345L), anyChannelPromise()); + verify(frameWriter).writePing(any(ChannelHandlerContext.class), eq(false), + eq(12345L), anyChannelPromise()); } @Test @@ -769,7 +769,7 @@ public class Http2FrameCodecTest { Http2Settings settings = new Http2Settings().maxConcurrentStreams(1); channel.writeAndFlush(new DefaultHttp2SettingsFrame(settings)); - verify(frameWriter).writeSettings(eqFrameCodecCtx(), eq(settings), anyChannelPromise()); + verify(frameWriter).writeSettings(any(ChannelHandlerContext.class), eq(settings), anyChannelPromise()); } @Test @@ -825,21 +825,21 @@ public class Http2FrameCodecTest { Http2PingFrame frame = inboundHandler.readInbound(); assertFalse(frame.ack()); assertEquals(8, frame.content()); - verify(frameWriter).writePing(eqFrameCodecCtx(), eq(true), eq(8L), anyChannelPromise()); + verify(frameWriter).writePing(any(ChannelHandlerContext.class), eq(true), eq(8L), anyChannelPromise()); } @Test public void autoAckPingFalse() throws Exception { setUp(Http2FrameCodecBuilder.forServer().autoAckPingFrame(false), new Http2Settings()); frameInboundWriter.writeInboundPing(false, 8); - verify(frameWriter, never()).writePing(eqFrameCodecCtx(), eq(true), eq(8L), anyChannelPromise()); + verify(frameWriter, never()).writePing(any(ChannelHandlerContext.class), eq(true), eq(8L), anyChannelPromise()); Http2PingFrame frame = inboundHandler.readInbound(); assertFalse(frame.ack()); assertEquals(8, frame.content()); // Now ack the frame manually. channel.writeAndFlush(new DefaultHttp2PingFrame(8, true)); - verify(frameWriter).writePing(eqFrameCodecCtx(), eq(true), eq(8L), anyChannelPromise()); + verify(frameWriter).writePing(any(ChannelHandlerContext.class), eq(true), eq(8L), anyChannelPromise()); } @Test @@ -911,8 +911,4 @@ public class Http2FrameCodecTest { "HTTP/2", request); channel.pipeline().fireUserEventTriggered(upgradeEvent); } - - private ChannelHandlerContext eqFrameCodecCtx() { - return eq(frameCodec.ctx); - } } diff --git a/codec-http2/src/test/java/io/netty/handler/codec/http2/Http2MultiplexTest.java b/codec-http2/src/test/java/io/netty/handler/codec/http2/Http2MultiplexTest.java index 4dbeddecd9..67002db1e5 100644 --- a/codec-http2/src/test/java/io/netty/handler/codec/http2/Http2MultiplexTest.java +++ b/codec-http2/src/test/java/io/netty/handler/codec/http2/Http2MultiplexTest.java @@ -64,7 +64,6 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyLong; -import static org.mockito.ArgumentMatchers.anyShort; import static org.mockito.ArgumentMatchers.argThat; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.never; @@ -108,7 +107,7 @@ public abstract class Http2MultiplexTest { Http2Settings settings = new Http2Settings().initialWindowSize(initialRemoteStreamWindow); frameInboundWriter.writeInboundSettings(settings); - verify(frameWriter).writeSettingsAck(eqCodecCtx(), anyChannelPromise()); + verify(frameWriter).writeSettingsAck(any(ChannelHandlerContext.class), anyChannelPromise()); frameInboundWriter.writeInboundSettingsAck(); @@ -118,14 +117,10 @@ public abstract class Http2MultiplexTest { assertNotNull(settingsAckFrame); // Handshake - verify(frameWriter).writeSettings(eqCodecCtx(), + verify(frameWriter).writeSettings(any(ChannelHandlerContext.class), anyHttp2Settings(), anyChannelPromise()); } - private ChannelHandlerContext eqCodecCtx() { - return eq(codec.ctx); - } - @After public void tearDown() throws Exception { if (childChannelInitializer.handler instanceof LastInboundHandler) { @@ -152,8 +147,8 @@ public abstract class Http2MultiplexTest { }); assertTrue(childChannel.isActive()); - verify(frameWriter).writeFrame(eq(codec.ctx), eq((byte) 99), eqStreamId(childChannel), any(Http2Flags.class), - any(ByteBuf.class), any(ChannelPromise.class)); + verify(frameWriter).writeFrame(any(ChannelHandlerContext.class), eq((byte) 99), eqStreamId(childChannel), + any(Http2Flags.class), any(ByteBuf.class), any(ChannelPromise.class)); } private Http2StreamChannel newInboundStream(int streamId, boolean endStream, final ChannelHandler childHandler) { @@ -418,13 +413,13 @@ public abstract class Http2MultiplexTest { assertTrue(childChannel.isActive()); childChannel.close(); - verify(frameWriter).writeRstStream(eqCodecCtx(), + verify(frameWriter).writeRstStream(any(ChannelHandlerContext.class), eqStreamId(childChannel), eq(Http2Error.CANCEL.code()), anyChannelPromise()); } @Test public void outboundStreamShouldNotWriteResetFrameOnClose_IfStreamDidntExist() { - when(frameWriter.writeHeaders(eqCodecCtx(), anyInt(), + when(frameWriter.writeHeaders(any(ChannelHandlerContext.class), anyInt(), any(Http2Headers.class), anyInt(), anyBoolean(), any(ChannelPromise.class))).thenAnswer(new Answer() { @@ -453,8 +448,8 @@ public abstract class Http2MultiplexTest { childChannel.close(); // The channel was never active so we should not generate a RST frame. - verify(frameWriter, never()).writeRstStream(eqCodecCtx(), eqStreamId(childChannel), anyLong(), - anyChannelPromise()); + verify(frameWriter, never()).writeRstStream(any(ChannelHandlerContext.class), + eqStreamId(childChannel), anyLong(), anyChannelPromise()); assertTrue(parentChannel.outboundMessages().isEmpty()); } @@ -469,7 +464,7 @@ public abstract class Http2MultiplexTest { assertFalse(inboundHandler.isChannelActive()); // A RST_STREAM frame should NOT be emitted, as we received a RST_STREAM. - verify(frameWriter, Mockito.never()).writeRstStream(eqCodecCtx(), eqStreamId(channel), + verify(frameWriter, Mockito.never()).writeRstStream(any(ChannelHandlerContext.class), eqStreamId(channel), anyLong(), anyChannelPromise()); } @@ -493,7 +488,7 @@ public abstract class Http2MultiplexTest { assertTrue(childChannel.isActive()); Http2Headers headers = new DefaultHttp2Headers(); - when(frameWriter.writeHeaders(eqCodecCtx(), anyInt(), + when(frameWriter.writeHeaders(any(ChannelHandlerContext.class), anyInt(), eq(headers), anyInt(), anyBoolean(), any(ChannelPromise.class))).thenAnswer(invocationOnMock -> { return ((ChannelPromise) invocationOnMock.getArgument(5)).setFailure( @@ -537,7 +532,7 @@ public abstract class Http2MultiplexTest { childChannel.close(); // An active outbound stream should emit a RST_STREAM frame. - verify(frameWriter).writeRstStream(eqCodecCtx(), eqStreamId(childChannel), + verify(frameWriter).writeRstStream(any(ChannelHandlerContext.class), eqStreamId(childChannel), anyLong(), anyChannelPromise()); assertFalse(childChannel.isOpen()); @@ -555,7 +550,7 @@ public abstract class Http2MultiplexTest { assertTrue(childChannel.isActive()); Http2Headers headers = new DefaultHttp2Headers(); - when(frameWriter.writeHeaders(eqCodecCtx(), anyInt(), + when(frameWriter.writeHeaders(any(ChannelHandlerContext.class), anyInt(), eq(headers), anyInt(), anyBoolean(), any(ChannelPromise.class))).thenAnswer(invocationOnMock -> { return ((ChannelPromise) invocationOnMock.getArgument(5)).setFailure( new Http2NoMoreStreamIdsException()); @@ -637,7 +632,7 @@ public abstract class Http2MultiplexTest { final AtomicBoolean channelActive = new AtomicBoolean(true); Http2Headers headers = new DefaultHttp2Headers(); - when(frameWriter.writeHeaders(eqCodecCtx(), anyInt(), + when(frameWriter.writeHeaders(any(ChannelHandlerContext.class), anyInt(), eq(headers), anyInt(), anyBoolean(), any(ChannelPromise.class))).thenAnswer(invocationOnMock -> { ChannelPromise promise = invocationOnMock.getArgument(5); diff --git a/codec-http2/src/test/java/io/netty/handler/codec/http2/Http2TestUtil.java b/codec-http2/src/test/java/io/netty/handler/codec/http2/Http2TestUtil.java index d27dc149a4..ffc8939284 100644 --- a/codec-http2/src/test/java/io/netty/handler/codec/http2/Http2TestUtil.java +++ b/codec-http2/src/test/java/io/netty/handler/codec/http2/Http2TestUtil.java @@ -35,7 +35,6 @@ import org.mockito.Mockito; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; -import java.util.List; import java.util.Random; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.CountDownLatch; @@ -204,7 +203,7 @@ public final class Http2TestUtil { } @Override - protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { + protected void decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception { reader.readFrame(ctx, in, new Http2FrameListener() { @Override public int onDataRead(ChannelHandlerContext ctx, int streamId, ByteBuf data, int padding, diff --git a/codec-http2/src/test/java/io/netty/handler/codec/http2/StreamBufferingEncoderTest.java b/codec-http2/src/test/java/io/netty/handler/codec/http2/StreamBufferingEncoderTest.java index 0e35555616..fc7f7fb822 100644 --- a/codec-http2/src/test/java/io/netty/handler/codec/http2/StreamBufferingEncoderTest.java +++ b/codec-http2/src/test/java/io/netty/handler/codec/http2/StreamBufferingEncoderTest.java @@ -165,8 +165,8 @@ public class StreamBufferingEncoderTest { writeVerifyWriteHeaders(times(2), 3); // Contiguous data writes are coalesced ArgumentCaptor bufCaptor = ArgumentCaptor.forClass(ByteBuf.class); - verify(writer, times(1)) - .writeData(eq(ctx), eq(3), bufCaptor.capture(), eq(0), eq(false), any(ChannelPromise.class)); + verify(writer, times(1)).writeData(any(ChannelHandlerContext.class), eq(3), + bufCaptor.capture(), eq(0), eq(false), any(ChannelPromise.class)); assertEquals(expectedBytes, bufCaptor.getValue().readableBytes()); } diff --git a/codec-memcache/src/main/java/io/netty/handler/codec/memcache/binary/AbstractBinaryMemcacheDecoder.java b/codec-memcache/src/main/java/io/netty/handler/codec/memcache/binary/AbstractBinaryMemcacheDecoder.java index bec754afbd..5784ee3bd7 100644 --- a/codec-memcache/src/main/java/io/netty/handler/codec/memcache/binary/AbstractBinaryMemcacheDecoder.java +++ b/codec-memcache/src/main/java/io/netty/handler/codec/memcache/binary/AbstractBinaryMemcacheDecoder.java @@ -28,8 +28,6 @@ import io.netty.handler.codec.memcache.LastMemcacheContent; import io.netty.handler.codec.memcache.MemcacheContent; import io.netty.util.internal.UnstableApi; -import java.util.List; - /** * Decoder for both {@link BinaryMemcacheRequest} and {@link BinaryMemcacheResponse}. *

@@ -67,7 +65,7 @@ public abstract class AbstractBinaryMemcacheDecoder out) throws Exception { + protected void decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception { switch (state) { case READ_HEADER: try { if (in.readableBytes() < 24) { @@ -79,7 +77,7 @@ public abstract class AbstractBinaryMemcacheDecoder out) throws Exception { - int oldSize = out.size(); - super.decode(ctx, in, out); + protected void handlerAdded0(final ChannelHandlerContext ctx) { + context = new ChannelHandlerContext() { + @Override + public Channel channel() { + return ctx.channel(); + } - if (failOnMissingResponse) { - final int size = out.size(); - for (int i = oldSize; i < size; i ++) { - Object msg = out.get(i); - if (msg instanceof LastMemcacheContent) { + public EventExecutor executor() { + return ctx.executor(); + } + + public String name() { + return ctx.name(); + } + + public ChannelHandler handler() { + return ctx.handler(); + } + + public boolean isRemoved() { + return ctx.isRemoved(); + } + + public ChannelHandlerContext fireChannelRegistered() { + ctx.fireChannelRegistered(); + return this; + } + + public ChannelHandlerContext fireChannelUnregistered() { + ctx.fireChannelUnregistered(); + return this; + } + + public ChannelHandlerContext fireChannelActive() { + ctx.fireChannelActive(); + return this; + } + + public ChannelHandlerContext fireChannelInactive() { + ctx.fireChannelInactive(); + return this; + } + + public ChannelHandlerContext fireExceptionCaught(Throwable cause) { + ctx.fireExceptionCaught(cause); + return this; + } + + public ChannelHandlerContext fireUserEventTriggered(Object evt) { + ctx.fireUserEventTriggered(evt); + return this; + } + + public ChannelHandlerContext fireChannelRead(Object msg) { + if (failOnMissingResponse && msg instanceof LastMemcacheContent) { requestResponseCounter.decrementAndGet(); } + ctx.fireChannelRead(msg); + return this; } - } + + public ChannelHandlerContext fireChannelReadComplete() { + ctx.fireChannelReadComplete(); + return this; + } + + public ChannelHandlerContext fireChannelWritabilityChanged() { + ctx.fireChannelWritabilityChanged(); + return this; + } + + public ChannelHandlerContext read() { + ctx.read(); + return this; + } + + public ChannelHandlerContext flush() { + ctx.flush(); + return this; + } + + public ChannelPipeline pipeline() { + return ctx.pipeline(); + } + + public ByteBufAllocator alloc() { + return ctx.alloc(); + } + + @Deprecated + public Attribute attr(AttributeKey key) { + return ctx.attr(key); + } + + @Deprecated + public boolean hasAttr(AttributeKey key) { + return ctx.hasAttr(key); + } + + public ChannelFuture bind(SocketAddress localAddress) { + return ctx.bind(localAddress); + } + + public ChannelFuture connect(SocketAddress remoteAddress) { + return ctx.connect(remoteAddress); + } + + public ChannelFuture connect(SocketAddress remoteAddress, SocketAddress localAddress) { + return ctx.connect(remoteAddress, localAddress); + } + + public ChannelFuture disconnect() { + return ctx.disconnect(); + } + + public ChannelFuture close() { + return ctx.close(); + } + + public ChannelFuture deregister() { + return ctx.deregister(); + } + + @Override + public ChannelFuture register() { + return ctx.register(); + } + + @Override + public ChannelFuture register(ChannelPromise promise) { + return ctx.register(promise); + } + + public ChannelFuture bind(SocketAddress localAddress, ChannelPromise promise) { + return ctx.bind(localAddress, promise); + } + + public ChannelFuture connect(SocketAddress remoteAddress, ChannelPromise promise) { + return ctx.connect(remoteAddress, promise); + } + + public ChannelFuture connect( + SocketAddress remoteAddress, SocketAddress localAddress, ChannelPromise promise) { + return ctx.connect(remoteAddress, localAddress, promise); + } + + public ChannelFuture disconnect(ChannelPromise promise) { + return ctx.disconnect(promise); + } + + public ChannelFuture close(ChannelPromise promise) { + return ctx.close(promise); + } + + public ChannelFuture deregister(ChannelPromise promise) { + return ctx.deregister(promise); + } + + public ChannelFuture write(Object msg) { + return ctx.write(msg); + } + + public ChannelFuture write(Object msg, ChannelPromise promise) { + return ctx.write(msg, promise); + } + + public ChannelFuture writeAndFlush(Object msg, ChannelPromise promise) { + return ctx.writeAndFlush(msg, promise); + } + + public ChannelFuture writeAndFlush(Object msg) { + return ctx.writeAndFlush(msg); + } + + public ChannelPromise newPromise() { + return ctx.newPromise(); + } + + public ChannelProgressivePromise newProgressivePromise() { + return ctx.newProgressivePromise(); + } + + public ChannelFuture newSucceededFuture() { + return ctx.newSucceededFuture(); + } + + public ChannelFuture newFailedFuture(Throwable cause) { + return ctx.newFailedFuture(cause); + } + + public ChannelPromise voidPromise() { + return ctx.voidPromise(); + } + }; + } + + @Override + protected void decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception { + super.decode(context, in); } @Override diff --git a/codec-mqtt/src/main/java/io/netty/handler/codec/mqtt/MqttDecoder.java b/codec-mqtt/src/main/java/io/netty/handler/codec/mqtt/MqttDecoder.java index db1234ae1c..16f73e7dd3 100644 --- a/codec-mqtt/src/main/java/io/netty/handler/codec/mqtt/MqttDecoder.java +++ b/codec-mqtt/src/main/java/io/netty/handler/codec/mqtt/MqttDecoder.java @@ -69,7 +69,7 @@ public final class MqttDecoder extends ReplayingDecoder { } @Override - protected void decode(ChannelHandlerContext ctx, ByteBuf buffer, List out) throws Exception { + protected void decode(ChannelHandlerContext ctx, ByteBuf buffer) throws Exception { switch (state()) { case READ_FIXED_HEADER: try { mqttFixedHeader = decodeFixedHeader(buffer); @@ -77,7 +77,7 @@ public final class MqttDecoder extends ReplayingDecoder { checkpoint(DecoderState.READ_VARIABLE_HEADER); // fall through } catch (Exception cause) { - out.add(invalidMessage(cause)); + ctx.fireChannelRead(invalidMessage(cause)); return; } @@ -91,7 +91,7 @@ public final class MqttDecoder extends ReplayingDecoder { checkpoint(DecoderState.READ_PAYLOAD); // fall through } catch (Exception cause) { - out.add(invalidMessage(cause)); + ctx.fireChannelRead(invalidMessage(cause)); return; } @@ -113,10 +113,10 @@ public final class MqttDecoder extends ReplayingDecoder { mqttFixedHeader, variableHeader, decodedPayload.value); mqttFixedHeader = null; variableHeader = null; - out.add(message); + ctx.fireChannelRead(message); break; } catch (Exception cause) { - out.add(invalidMessage(cause)); + ctx.fireChannelRead(invalidMessage(cause)); return; } diff --git a/codec-mqtt/src/test/java/io/netty/handler/codec/mqtt/MqttCodecTest.java b/codec-mqtt/src/test/java/io/netty/handler/codec/mqtt/MqttCodecTest.java index e7fb3cd9fd..5b903fc271 100644 --- a/codec-mqtt/src/test/java/io/netty/handler/codec/mqtt/MqttCodecTest.java +++ b/codec-mqtt/src/test/java/io/netty/handler/codec/mqtt/MqttCodecTest.java @@ -25,6 +25,7 @@ import io.netty.handler.codec.DecoderException; import io.netty.util.CharsetUtil; import org.junit.Before; import org.junit.Test; +import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; @@ -74,12 +75,11 @@ public class MqttCodecTest { final MqttConnectMessage message = createConnectMessage(MqttVersion.MQTT_3_1); ByteBuf byteBuf = MqttEncoder.doEncode(ALLOCATOR, message); - final List out = new LinkedList<>(); - mqttDecoder.decode(ctx, byteBuf, out); + ArgumentCaptor captor = ArgumentCaptor.forClass(MqttConnectMessage.class); + mqttDecoder.decode(ctx, byteBuf); + verify(ctx).fireChannelRead(captor.capture()); - assertEquals("Expected one object but got " + out.size(), 1, out.size()); - - final MqttConnectMessage decodedMessage = (MqttConnectMessage) out.get(0); + final MqttConnectMessage decodedMessage = captor.getValue(); validateFixedHeaders(message.fixedHeader(), decodedMessage.fixedHeader()); validateConnectVariableHeader(message.variableHeader(), decodedMessage.variableHeader()); @@ -91,12 +91,11 @@ public class MqttCodecTest { final MqttConnectMessage message = createConnectMessage(MqttVersion.MQTT_3_1_1); ByteBuf byteBuf = MqttEncoder.doEncode(ALLOCATOR, message); - final List out = new LinkedList<>(); - mqttDecoder.decode(ctx, byteBuf, out); + ArgumentCaptor captor = ArgumentCaptor.forClass(MqttConnectMessage.class); + mqttDecoder.decode(ctx, byteBuf); + verify(ctx).fireChannelRead(captor.capture()); - assertEquals("Expected one object but got " + out.size(), 1, out.size()); - - final MqttConnectMessage decodedMessage = (MqttConnectMessage) out.get(0); + final MqttConnectMessage decodedMessage = captor.getValue(); validateFixedHeaders(message.fixedHeader(), decodedMessage.fixedHeader()); validateConnectVariableHeader(message.variableHeader(), decodedMessage.variableHeader()); @@ -110,12 +109,12 @@ public class MqttCodecTest { try { // Set the reserved flag in the CONNECT Packet to 1 byteBuf.setByte(9, byteBuf.getByte(9) | 0x1); - final List out = new LinkedList<>(); - mqttDecoder.decode(ctx, byteBuf, out); - assertEquals("Expected one object but got " + out.size(), 1, out.size()); + ArgumentCaptor captor = ArgumentCaptor.forClass(MqttMessage.class); + mqttDecoder.decode(ctx, byteBuf); + verify(ctx).fireChannelRead(captor.capture()); - final MqttMessage decodedMessage = (MqttMessage) out.get(0); + final MqttMessage decodedMessage = captor.getValue(); assertTrue(decodedMessage.decoderResult().isFailure()); Throwable cause = decodedMessage.decoderResult().cause(); assertTrue(cause instanceof DecoderException); @@ -141,12 +140,11 @@ public class MqttCodecTest { final MqttConnAckMessage message = createConnAckMessage(); ByteBuf byteBuf = MqttEncoder.doEncode(ALLOCATOR, message); - final List out = new LinkedList<>(); - mqttDecoder.decode(ctx, byteBuf, out); + ArgumentCaptor captor = ArgumentCaptor.forClass(MqttConnAckMessage.class); + mqttDecoder.decode(ctx, byteBuf); + verify(ctx).fireChannelRead(captor.capture()); - assertEquals("Expected one object but got " + out.size(), 1, out.size()); - - final MqttConnAckMessage decodedMessage = (MqttConnAckMessage) out.get(0); + final MqttConnAckMessage decodedMessage = captor.getValue(); validateFixedHeaders(message.fixedHeader(), decodedMessage.fixedHeader()); validateConnAckVariableHeader(message.variableHeader(), decodedMessage.variableHeader()); } @@ -156,12 +154,11 @@ public class MqttCodecTest { final MqttPublishMessage message = createPublishMessage(); ByteBuf byteBuf = MqttEncoder.doEncode(ALLOCATOR, message); - final List out = new LinkedList<>(); - mqttDecoder.decode(ctx, byteBuf, out); + ArgumentCaptor captor = ArgumentCaptor.forClass(MqttPublishMessage.class); + mqttDecoder.decode(ctx, byteBuf); + verify(ctx).fireChannelRead(captor.capture()); - assertEquals("Expected one object but got " + out.size(), 1, out.size()); - - final MqttPublishMessage decodedMessage = (MqttPublishMessage) out.get(0); + final MqttPublishMessage decodedMessage = captor.getValue(); validateFixedHeaders(message.fixedHeader(), decodedMessage.fixedHeader()); validatePublishVariableHeader(message.variableHeader(), decodedMessage.variableHeader()); validatePublishPayload(message.payload(), decodedMessage.payload()); @@ -192,12 +189,11 @@ public class MqttCodecTest { final MqttSubscribeMessage message = createSubscribeMessage(); ByteBuf byteBuf = MqttEncoder.doEncode(ALLOCATOR, message); - final List out = new LinkedList<>(); - mqttDecoder.decode(ctx, byteBuf, out); + ArgumentCaptor captor = ArgumentCaptor.forClass(MqttSubscribeMessage.class); + mqttDecoder.decode(ctx, byteBuf); + verify(ctx).fireChannelRead(captor.capture()); - assertEquals("Expected one object but got " + out.size(), 1, out.size()); - - final MqttSubscribeMessage decodedMessage = (MqttSubscribeMessage) out.get(0); + final MqttSubscribeMessage decodedMessage = captor.getValue(); validateFixedHeaders(message.fixedHeader(), decodedMessage.fixedHeader()); validateMessageIdVariableHeader(message.variableHeader(), decodedMessage.variableHeader()); validateSubscribePayload(message.payload(), decodedMessage.payload()); @@ -208,12 +204,11 @@ public class MqttCodecTest { final MqttSubAckMessage message = createSubAckMessage(); ByteBuf byteBuf = MqttEncoder.doEncode(ALLOCATOR, message); - final List out = new LinkedList<>(); - mqttDecoder.decode(ctx, byteBuf, out); + ArgumentCaptor captor = ArgumentCaptor.forClass(MqttSubAckMessage.class); + mqttDecoder.decode(ctx, byteBuf); + verify(ctx).fireChannelRead(captor.capture()); - assertEquals("Expected one object but got " + out.size(), 1, out.size()); - - final MqttSubAckMessage decodedMessage = (MqttSubAckMessage) out.get(0); + final MqttSubAckMessage decodedMessage = captor.getValue(); validateFixedHeaders(message.fixedHeader(), decodedMessage.fixedHeader()); validateMessageIdVariableHeader(message.variableHeader(), decodedMessage.variableHeader()); validateSubAckPayload(message.payload(), decodedMessage.payload()); @@ -230,12 +225,11 @@ public class MqttCodecTest { ByteBuf byteBuf = MqttEncoder.doEncode(ALLOCATOR, message); - List out = new LinkedList<>(); - mqttDecoder.decode(ctx, byteBuf, out); + ArgumentCaptor captor = ArgumentCaptor.forClass(MqttSubAckMessage.class); + mqttDecoder.decode(ctx, byteBuf); + verify(ctx).fireChannelRead(captor.capture()); - assertEquals("Expected one object but got " + out.size(), 1, out.size()); - - MqttSubAckMessage decodedMessage = (MqttSubAckMessage) out.get(0); + MqttSubAckMessage decodedMessage = captor.getValue(); validateFixedHeaders(message.fixedHeader(), decodedMessage.fixedHeader()); validateMessageIdVariableHeader(message.variableHeader(), decodedMessage.variableHeader()); validateSubAckPayload(message.payload(), decodedMessage.payload()); @@ -248,12 +242,11 @@ public class MqttCodecTest { final MqttUnsubscribeMessage message = createUnsubscribeMessage(); ByteBuf byteBuf = MqttEncoder.doEncode(ALLOCATOR, message); - final List out = new LinkedList<>(); - mqttDecoder.decode(ctx, byteBuf, out); + ArgumentCaptor captor = ArgumentCaptor.forClass(MqttUnsubscribeMessage.class); + mqttDecoder.decode(ctx, byteBuf); + verify(ctx).fireChannelRead(captor.capture()); - assertEquals("Expected one object but got " + out.size(), 1, out.size()); - - final MqttUnsubscribeMessage decodedMessage = (MqttUnsubscribeMessage) out.get(0); + final MqttUnsubscribeMessage decodedMessage = captor.getValue(); validateFixedHeaders(message.fixedHeader(), decodedMessage.fixedHeader()); validateMessageIdVariableHeader(message.variableHeader(), decodedMessage.variableHeader()); validateUnsubscribePayload(message.payload(), decodedMessage.payload()); @@ -287,12 +280,12 @@ public class MqttCodecTest { try { // setting an invalid message type (15, reserved and forbidden by MQTT 3.1.1 spec) byteBuf.setByte(0, 0xF0); - final List out = new LinkedList<>(); - mqttDecoder.decode(ctx, byteBuf, out); - assertEquals("Expected one object but got " + out.size(), 1, out.size()); + ArgumentCaptor captor = ArgumentCaptor.forClass(MqttMessage.class); + mqttDecoder.decode(ctx, byteBuf); + verify(ctx).fireChannelRead(captor.capture()); - final MqttMessage decodedMessage = (MqttMessage) out.get(0); + final MqttMessage decodedMessage = captor.getValue(); assertTrue(decodedMessage.decoderResult().isFailure()); Throwable cause = decodedMessage.decoderResult().cause(); assertTrue(cause instanceof IllegalArgumentException); @@ -308,12 +301,11 @@ public class MqttCodecTest { ByteBuf byteBuf = MqttEncoder.doEncode(ALLOCATOR, message); try { - final List out = new LinkedList<>(); - mqttDecoderLimitedMessageSize.decode(ctx, byteBuf, out); + ArgumentCaptor captor = ArgumentCaptor.forClass(MqttMessage.class); + mqttDecoderLimitedMessageSize.decode(ctx, byteBuf); + verify(ctx).fireChannelRead(captor.capture()); - assertEquals("Expected one object but got " + out.size(), 1, out.size()); - - final MqttMessage decodedMessage = (MqttMessage) out.get(0); + final MqttMessage decodedMessage = captor.getValue(); validateFixedHeaders(message.fixedHeader(), decodedMessage.fixedHeader()); validateConnectVariableHeader(message.variableHeader(), @@ -330,12 +322,11 @@ public class MqttCodecTest { ByteBuf byteBuf = MqttEncoder.doEncode(ALLOCATOR, message); try { - final List out = new LinkedList<>(); - mqttDecoderLimitedMessageSize.decode(ctx, byteBuf, out); + ArgumentCaptor captor = ArgumentCaptor.forClass(MqttMessage.class); + mqttDecoderLimitedMessageSize.decode(ctx, byteBuf); + verify(ctx).fireChannelRead(captor.capture()); - assertEquals("Expected one object but got " + out.size(), 1, out.size()); - - final MqttMessage decodedMessage = (MqttMessage) out.get(0); + final MqttMessage decodedMessage = captor.getValue(); validateFixedHeaders(message.fixedHeader(), decodedMessage.fixedHeader()); validateConnectVariableHeader(message.variableHeader(), @@ -352,12 +343,11 @@ public class MqttCodecTest { ByteBuf byteBuf = MqttEncoder.doEncode(ALLOCATOR, message); try { - final List out = new LinkedList<>(); - mqttDecoderLimitedMessageSize.decode(ctx, byteBuf, out); + ArgumentCaptor captor = ArgumentCaptor.forClass(MqttMessage.class); + mqttDecoderLimitedMessageSize.decode(ctx, byteBuf); + verify(ctx).fireChannelRead(captor.capture()); - assertEquals("Expected one object but got " + out.size(), 1, out.size()); - - final MqttMessage decodedMessage = (MqttMessage) out.get(0); + final MqttMessage decodedMessage = captor.getValue(); validateFixedHeaders(message.fixedHeader(), decodedMessage.fixedHeader()); validateDecoderExceptionTooLargeMessage(decodedMessage); } finally { @@ -371,12 +361,11 @@ public class MqttCodecTest { ByteBuf byteBuf = MqttEncoder.doEncode(ALLOCATOR, message); try { - final List out = new LinkedList<>(); - mqttDecoderLimitedMessageSize.decode(ctx, byteBuf, out); + ArgumentCaptor captor = ArgumentCaptor.forClass(MqttMessage.class); + mqttDecoderLimitedMessageSize.decode(ctx, byteBuf); + verify(ctx).fireChannelRead(captor.capture()); - assertEquals("Expected one object but got " + out.size(), 1, out.size()); - - final MqttMessage decodedMessage = (MqttMessage) out.get(0); + final MqttMessage decodedMessage = captor.getValue(); validateFixedHeaders(message.fixedHeader(), decodedMessage.fixedHeader()); validatePublishVariableHeader(message.variableHeader(), @@ -393,12 +382,11 @@ public class MqttCodecTest { ByteBuf byteBuf = MqttEncoder.doEncode(ALLOCATOR, message); try { - final List out = new LinkedList<>(); - mqttDecoderLimitedMessageSize.decode(ctx, byteBuf, out); + ArgumentCaptor captor = ArgumentCaptor.forClass(MqttMessage.class); + mqttDecoderLimitedMessageSize.decode(ctx, byteBuf); + verify(ctx).fireChannelRead(captor.capture()); - assertEquals("Expected one object but got " + out.size(), 1, out.size()); - - final MqttMessage decodedMessage = (MqttMessage) out.get(0); + final MqttMessage decodedMessage = captor.getValue(); validateFixedHeaders(message.fixedHeader(), decodedMessage.fixedHeader()); validateMessageIdVariableHeader(message.variableHeader(), (MqttMessageIdVariableHeader) decodedMessage.variableHeader()); @@ -414,12 +402,11 @@ public class MqttCodecTest { ByteBuf byteBuf = MqttEncoder.doEncode(ALLOCATOR, message); try { - final List out = new LinkedList<>(); - mqttDecoderLimitedMessageSize.decode(ctx, byteBuf, out); + ArgumentCaptor captor = ArgumentCaptor.forClass(MqttMessage.class); + mqttDecoderLimitedMessageSize.decode(ctx, byteBuf); + verify(ctx).fireChannelRead(captor.capture()); - assertEquals("Expected one object but got " + out.size(), 1, out.size()); - - final MqttMessage decodedMessage = (MqttMessage) out.get(0); + final MqttMessage decodedMessage = captor.getValue(); validateFixedHeaders(message.fixedHeader(), decodedMessage.fixedHeader()); validateMessageIdVariableHeader(message.variableHeader(), (MqttMessageIdVariableHeader) decodedMessage.variableHeader()); @@ -435,12 +422,11 @@ public class MqttCodecTest { ByteBuf byteBuf = MqttEncoder.doEncode(ALLOCATOR, message); try { - final List out = new LinkedList<>(); - mqttDecoderLimitedMessageSize.decode(ctx, byteBuf, out); + ArgumentCaptor captor = ArgumentCaptor.forClass(MqttMessage.class); + mqttDecoderLimitedMessageSize.decode(ctx, byteBuf); + verify(ctx).fireChannelRead(captor.capture()); - assertEquals("Expected one object but got " + out.size(), 1, out.size()); - - final MqttMessage decodedMessage = (MqttMessage) out.get(0); + final MqttMessage decodedMessage = captor.getValue(); validateFixedHeaders(message.fixedHeader(), decodedMessage.fixedHeader()); validateMessageIdVariableHeader(message.variableHeader(), (MqttMessageIdVariableHeader) decodedMessage.variableHeader()); @@ -453,12 +439,11 @@ public class MqttCodecTest { private void testMessageWithOnlyFixedHeader(MqttMessage message) throws Exception { ByteBuf byteBuf = MqttEncoder.doEncode(ALLOCATOR, message); - final List out = new LinkedList<>(); - mqttDecoder.decode(ctx, byteBuf, out); + ArgumentCaptor captor = ArgumentCaptor.forClass(MqttMessage.class); + mqttDecoder.decode(ctx, byteBuf); + verify(ctx).fireChannelRead(captor.capture()); - assertEquals("Expected one object but got " + out.size(), 1, out.size()); - - final MqttMessage decodedMessage = (MqttMessage) out.get(0); + final MqttMessage decodedMessage = captor.getValue(); validateFixedHeaders(message.fixedHeader(), decodedMessage.fixedHeader()); } @@ -468,12 +453,11 @@ public class MqttCodecTest { ByteBuf byteBuf = MqttEncoder.doEncode(ALLOCATOR, message); - final List out = new LinkedList<>(); - mqttDecoder.decode(ctx, byteBuf, out); + ArgumentCaptor captor = ArgumentCaptor.forClass(MqttMessage.class); + mqttDecoder.decode(ctx, byteBuf); + verify(ctx).fireChannelRead(captor.capture()); - assertEquals("Expected one object but got " + out.size(), 1, out.size()); - - final MqttMessage decodedMessage = (MqttMessage) out.get(0); + final MqttMessage decodedMessage = captor.getValue(); validateFixedHeaders(message.fixedHeader(), decodedMessage.fixedHeader()); validateMessageIdVariableHeader( (MqttMessageIdVariableHeader) message.variableHeader(), diff --git a/codec-redis/src/main/java/io/netty/handler/codec/redis/RedisArrayAggregator.java b/codec-redis/src/main/java/io/netty/handler/codec/redis/RedisArrayAggregator.java index 513a0a1bdd..a7c2530de7 100644 --- a/codec-redis/src/main/java/io/netty/handler/codec/redis/RedisArrayAggregator.java +++ b/codec-redis/src/main/java/io/netty/handler/codec/redis/RedisArrayAggregator.java @@ -36,7 +36,7 @@ public final class RedisArrayAggregator extends MessageToMessageDecoder depths = new ArrayDeque<>(4); @Override - protected void decode(ChannelHandlerContext ctx, RedisMessage msg, List out) throws Exception { + protected void decode(ChannelHandlerContext ctx, RedisMessage msg) throws Exception { if (msg instanceof ArrayHeaderRedisMessage) { msg = decodeRedisArrayHeader((ArrayHeaderRedisMessage) msg); if (msg == null) { @@ -60,7 +60,7 @@ public final class RedisArrayAggregator extends MessageToMessageDecoderRESP (REdis Serialization Protocol). @@ -95,7 +93,7 @@ public final class RedisDecoder extends ByteToMessageDecoder { } @Override - protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { + protected void decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception { try { for (;;) { switch (state) { @@ -105,22 +103,22 @@ public final class RedisDecoder extends ByteToMessageDecoder { } break; case DECODE_INLINE: - if (!decodeInline(in, out)) { + if (!decodeInline(ctx, in)) { return; } break; case DECODE_LENGTH: - if (!decodeLength(in, out)) { + if (!decodeLength(ctx, in)) { return; } break; case DECODE_BULK_STRING_EOL: - if (!decodeBulkStringEndOfLine(in, out)) { + if (!decodeBulkStringEndOfLine(ctx, in)) { return; } break; case DECODE_BULK_STRING_CONTENT: - if (!decodeBulkStringContent(in, out)) { + if (!decodeBulkStringContent(ctx, in)) { return; } break; @@ -152,7 +150,7 @@ public final class RedisDecoder extends ByteToMessageDecoder { return true; } - private boolean decodeInline(ByteBuf in, List out) throws Exception { + private boolean decodeInline(ChannelHandlerContext ctx, ByteBuf in) throws Exception { ByteBuf lineBytes = readLine(in); if (lineBytes == null) { if (in.readableBytes() > maxInlineMessageLength) { @@ -161,12 +159,12 @@ public final class RedisDecoder extends ByteToMessageDecoder { } return false; } - out.add(newInlineRedisMessage(type, lineBytes)); + ctx.fireChannelRead(newInlineRedisMessage(type, lineBytes)); resetDecoder(); return true; } - private boolean decodeLength(ByteBuf in, List out) throws Exception { + private boolean decodeLength(ChannelHandlerContext ctx, ByteBuf in) throws Exception { ByteBuf lineByteBuf = readLine(in); if (lineByteBuf == null) { return false; @@ -177,7 +175,7 @@ public final class RedisDecoder extends ByteToMessageDecoder { } switch (type) { case ARRAY_HEADER: - out.add(new ArrayHeaderRedisMessage(length)); + ctx.fireChannelRead(new ArrayHeaderRedisMessage(length)); resetDecoder(); return true; case BULK_STRING: @@ -186,41 +184,41 @@ public final class RedisDecoder extends ByteToMessageDecoder { RedisConstants.REDIS_MESSAGE_MAX_LENGTH + ")"); } remainingBulkLength = (int) length; // range(int) is already checked. - return decodeBulkString(in, out); + return decodeBulkString(ctx, in); default: throw new RedisCodecException("bad type: " + type); } } - private boolean decodeBulkString(ByteBuf in, List out) throws Exception { + private boolean decodeBulkString(ChannelHandlerContext ctx, ByteBuf in) throws Exception { switch (remainingBulkLength) { case RedisConstants.NULL_VALUE: // $-1\r\n - out.add(FullBulkStringRedisMessage.NULL_INSTANCE); + ctx.fireChannelRead(FullBulkStringRedisMessage.NULL_INSTANCE); resetDecoder(); return true; case 0: state = State.DECODE_BULK_STRING_EOL; - return decodeBulkStringEndOfLine(in, out); + return decodeBulkStringEndOfLine(ctx, in); default: // expectedBulkLength is always positive. - out.add(new BulkStringHeaderRedisMessage(remainingBulkLength)); + ctx.fireChannelRead(new BulkStringHeaderRedisMessage(remainingBulkLength)); state = State.DECODE_BULK_STRING_CONTENT; - return decodeBulkStringContent(in, out); + return decodeBulkStringContent(ctx, in); } } // $0\r\n \r\n - private boolean decodeBulkStringEndOfLine(ByteBuf in, List out) throws Exception { + private boolean decodeBulkStringEndOfLine(ChannelHandlerContext ctx, ByteBuf in) throws Exception { if (in.readableBytes() < RedisConstants.EOL_LENGTH) { return false; } readEndOfLine(in); - out.add(FullBulkStringRedisMessage.EMPTY_INSTANCE); + ctx.fireChannelRead(FullBulkStringRedisMessage.EMPTY_INSTANCE); resetDecoder(); return true; } // ${expectedBulkLength}\r\n {data...}\r\n - private boolean decodeBulkStringContent(ByteBuf in, List out) throws Exception { + private boolean decodeBulkStringContent(ChannelHandlerContext ctx, ByteBuf in) throws Exception { final int readableBytes = in.readableBytes(); if (readableBytes == 0 || remainingBulkLength == 0 && readableBytes < RedisConstants.EOL_LENGTH) { return false; @@ -231,7 +229,7 @@ public final class RedisDecoder extends ByteToMessageDecoder { ByteBuf content = in.readSlice(remainingBulkLength); readEndOfLine(in); // Only call retain after readEndOfLine(...) as the method may throw an exception. - out.add(new DefaultLastBulkStringRedisContent(content.retain())); + ctx.fireChannelRead(new DefaultLastBulkStringRedisContent(content.retain())); resetDecoder(); return true; } @@ -239,7 +237,7 @@ public final class RedisDecoder extends ByteToMessageDecoder { // chunked write. int toRead = Math.min(remainingBulkLength, readableBytes); remainingBulkLength -= toRead; - out.add(new DefaultBulkStringRedisContent(in.readSlice(toRead).retain())); + ctx.fireChannelRead(new DefaultBulkStringRedisContent(in.readSlice(toRead).retain())); return true; } diff --git a/codec-smtp/src/main/java/io/netty/handler/codec/smtp/SmtpResponseDecoder.java b/codec-smtp/src/main/java/io/netty/handler/codec/smtp/SmtpResponseDecoder.java index 96c75636dd..d7f978578c 100644 --- a/codec-smtp/src/main/java/io/netty/handler/codec/smtp/SmtpResponseDecoder.java +++ b/codec-smtp/src/main/java/io/netty/handler/codec/smtp/SmtpResponseDecoder.java @@ -42,8 +42,8 @@ public final class SmtpResponseDecoder extends LineBasedFrameDecoder { } @Override - protected SmtpResponse decode(ChannelHandlerContext ctx, ByteBuf buffer) throws Exception { - ByteBuf frame = (ByteBuf) super.decode(ctx, buffer); + protected SmtpResponse decode0(ChannelHandlerContext ctx, ByteBuf buffer) throws Exception { + ByteBuf frame = (ByteBuf) super.decode0(ctx, buffer); if (frame == null) { // No full line received yet. return null; diff --git a/codec-socks/src/main/java/io/netty/handler/codec/socks/SocksAuthRequestDecoder.java b/codec-socks/src/main/java/io/netty/handler/codec/socks/SocksAuthRequestDecoder.java index be93f03f28..07043fcae9 100644 --- a/codec-socks/src/main/java/io/netty/handler/codec/socks/SocksAuthRequestDecoder.java +++ b/codec-socks/src/main/java/io/netty/handler/codec/socks/SocksAuthRequestDecoder.java @@ -20,8 +20,6 @@ import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.ReplayingDecoder; import io.netty.handler.codec.socks.SocksAuthRequestDecoder.State; -import java.util.List; - /** * Decodes {@link ByteBuf}s into {@link SocksAuthRequest}. * Before returning SocksRequest decoder removes itself from pipeline. @@ -35,11 +33,11 @@ public class SocksAuthRequestDecoder extends ReplayingDecoder { } @Override - protected void decode(ChannelHandlerContext ctx, ByteBuf byteBuf, List out) throws Exception { + protected void decode(ChannelHandlerContext ctx, ByteBuf byteBuf) throws Exception { switch (state()) { case CHECK_PROTOCOL_VERSION: { if (byteBuf.readByte() != SocksSubnegotiationVersion.AUTH_PASSWORD.byteValue()) { - out.add(SocksCommonUtils.UNKNOWN_SOCKS_REQUEST); + ctx.fireChannelRead(SocksCommonUtils.UNKNOWN_SOCKS_REQUEST); break; } checkpoint(State.READ_USERNAME); @@ -52,7 +50,7 @@ public class SocksAuthRequestDecoder extends ReplayingDecoder { case READ_PASSWORD: { int fieldLength = byteBuf.readByte(); String password = SocksCommonUtils.readUsAscii(byteBuf, fieldLength); - out.add(new SocksAuthRequest(username, password)); + ctx.fireChannelRead(new SocksAuthRequest(username, password)); break; } default: { diff --git a/codec-socks/src/main/java/io/netty/handler/codec/socks/SocksAuthResponseDecoder.java b/codec-socks/src/main/java/io/netty/handler/codec/socks/SocksAuthResponseDecoder.java index 8bbb005266..52bfb457a0 100644 --- a/codec-socks/src/main/java/io/netty/handler/codec/socks/SocksAuthResponseDecoder.java +++ b/codec-socks/src/main/java/io/netty/handler/codec/socks/SocksAuthResponseDecoder.java @@ -20,8 +20,6 @@ import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.ReplayingDecoder; import io.netty.handler.codec.socks.SocksAuthResponseDecoder.State; -import java.util.List; - /** * Decodes {@link ByteBuf}s into {@link SocksAuthResponse}. * Before returning SocksResponse decoder removes itself from pipeline. @@ -33,26 +31,26 @@ public class SocksAuthResponseDecoder extends ReplayingDecoder { } @Override - protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf, List out) + protected void decode(ChannelHandlerContext ctx, ByteBuf byteBuf) throws Exception { switch (state()) { case CHECK_PROTOCOL_VERSION: { if (byteBuf.readByte() != SocksSubnegotiationVersion.AUTH_PASSWORD.byteValue()) { - out.add(SocksCommonUtils.UNKNOWN_SOCKS_RESPONSE); + ctx.fireChannelRead(SocksCommonUtils.UNKNOWN_SOCKS_RESPONSE); break; } checkpoint(State.READ_AUTH_RESPONSE); } case READ_AUTH_RESPONSE: { SocksAuthStatus authStatus = SocksAuthStatus.valueOf(byteBuf.readByte()); - out.add(new SocksAuthResponse(authStatus)); + ctx.fireChannelRead(new SocksAuthResponse(authStatus)); break; } default: { throw new Error(); } } - channelHandlerContext.pipeline().remove(this); + ctx.pipeline().remove(this); } enum State { diff --git a/codec-socks/src/main/java/io/netty/handler/codec/socks/SocksCmdRequestDecoder.java b/codec-socks/src/main/java/io/netty/handler/codec/socks/SocksCmdRequestDecoder.java index c0441b4b96..2aba8f3301 100644 --- a/codec-socks/src/main/java/io/netty/handler/codec/socks/SocksCmdRequestDecoder.java +++ b/codec-socks/src/main/java/io/netty/handler/codec/socks/SocksCmdRequestDecoder.java @@ -21,8 +21,6 @@ import io.netty.handler.codec.ReplayingDecoder; import io.netty.handler.codec.socks.SocksCmdRequestDecoder.State; import io.netty.util.NetUtil; -import java.util.List; - /** * Decodes {@link ByteBuf}s into {@link SocksCmdRequest}. * Before returning SocksRequest decoder removes itself from pipeline. @@ -37,11 +35,11 @@ public class SocksCmdRequestDecoder extends ReplayingDecoder { } @Override - protected void decode(ChannelHandlerContext ctx, ByteBuf byteBuf, List out) throws Exception { + protected void decode(ChannelHandlerContext ctx, ByteBuf byteBuf) throws Exception { switch (state()) { case CHECK_PROTOCOL_VERSION: { if (byteBuf.readByte() != SocksProtocolVersion.SOCKS5.byteValue()) { - out.add(SocksCommonUtils.UNKNOWN_SOCKS_REQUEST); + ctx.fireChannelRead(SocksCommonUtils.UNKNOWN_SOCKS_REQUEST); break; } checkpoint(State.READ_CMD_HEADER); @@ -57,14 +55,14 @@ public class SocksCmdRequestDecoder extends ReplayingDecoder { case IPv4: { String host = NetUtil.intToIpAddress(byteBuf.readInt()); int port = byteBuf.readUnsignedShort(); - out.add(new SocksCmdRequest(cmdType, addressType, host, port)); + ctx.fireChannelRead(new SocksCmdRequest(cmdType, addressType, host, port)); break; } case DOMAIN: { int fieldLength = byteBuf.readByte(); String host = SocksCommonUtils.readUsAscii(byteBuf, fieldLength); int port = byteBuf.readUnsignedShort(); - out.add(new SocksCmdRequest(cmdType, addressType, host, port)); + ctx.fireChannelRead(new SocksCmdRequest(cmdType, addressType, host, port)); break; } case IPv6: { @@ -72,11 +70,11 @@ public class SocksCmdRequestDecoder extends ReplayingDecoder { byteBuf.readBytes(bytes); String host = SocksCommonUtils.ipv6toStr(bytes); int port = byteBuf.readUnsignedShort(); - out.add(new SocksCmdRequest(cmdType, addressType, host, port)); + ctx.fireChannelRead(new SocksCmdRequest(cmdType, addressType, host, port)); break; } case UNKNOWN: { - out.add(SocksCommonUtils.UNKNOWN_SOCKS_REQUEST); + ctx.fireChannelRead(SocksCommonUtils.UNKNOWN_SOCKS_REQUEST); break; } default: { diff --git a/codec-socks/src/main/java/io/netty/handler/codec/socks/SocksCmdResponseDecoder.java b/codec-socks/src/main/java/io/netty/handler/codec/socks/SocksCmdResponseDecoder.java index c7edec5598..fdc6b5eb66 100644 --- a/codec-socks/src/main/java/io/netty/handler/codec/socks/SocksCmdResponseDecoder.java +++ b/codec-socks/src/main/java/io/netty/handler/codec/socks/SocksCmdResponseDecoder.java @@ -21,8 +21,6 @@ import io.netty.handler.codec.ReplayingDecoder; import io.netty.handler.codec.socks.SocksCmdResponseDecoder.State; import io.netty.util.NetUtil; -import java.util.List; - /** * Decodes {@link ByteBuf}s into {@link SocksCmdResponse}. * Before returning SocksResponse decoder removes itself from pipeline. @@ -37,11 +35,11 @@ public class SocksCmdResponseDecoder extends ReplayingDecoder { } @Override - protected void decode(ChannelHandlerContext ctx, ByteBuf byteBuf, List out) throws Exception { + protected void decode(ChannelHandlerContext ctx, ByteBuf byteBuf) throws Exception { switch (state()) { case CHECK_PROTOCOL_VERSION: { if (byteBuf.readByte() != SocksProtocolVersion.SOCKS5.byteValue()) { - out.add(SocksCommonUtils.UNKNOWN_SOCKS_RESPONSE); + ctx.fireChannelRead(SocksCommonUtils.UNKNOWN_SOCKS_RESPONSE); break; } checkpoint(State.READ_CMD_HEADER); @@ -57,14 +55,14 @@ public class SocksCmdResponseDecoder extends ReplayingDecoder { case IPv4: { String host = NetUtil.intToIpAddress(byteBuf.readInt()); int port = byteBuf.readUnsignedShort(); - out.add(new SocksCmdResponse(cmdStatus, addressType, host, port)); + ctx.fireChannelRead(new SocksCmdResponse(cmdStatus, addressType, host, port)); break; } case DOMAIN: { int fieldLength = byteBuf.readByte(); String host = SocksCommonUtils.readUsAscii(byteBuf, fieldLength); int port = byteBuf.readUnsignedShort(); - out.add(new SocksCmdResponse(cmdStatus, addressType, host, port)); + ctx.fireChannelRead(new SocksCmdResponse(cmdStatus, addressType, host, port)); break; } case IPv6: { @@ -72,11 +70,11 @@ public class SocksCmdResponseDecoder extends ReplayingDecoder { byteBuf.readBytes(bytes); String host = SocksCommonUtils.ipv6toStr(bytes); int port = byteBuf.readUnsignedShort(); - out.add(new SocksCmdResponse(cmdStatus, addressType, host, port)); + ctx.fireChannelRead(new SocksCmdResponse(cmdStatus, addressType, host, port)); break; } case UNKNOWN: { - out.add(SocksCommonUtils.UNKNOWN_SOCKS_RESPONSE); + ctx.fireChannelRead(SocksCommonUtils.UNKNOWN_SOCKS_RESPONSE); break; } default: { diff --git a/codec-socks/src/main/java/io/netty/handler/codec/socks/SocksInitRequestDecoder.java b/codec-socks/src/main/java/io/netty/handler/codec/socks/SocksInitRequestDecoder.java index aeb8176a8f..ede25324a0 100644 --- a/codec-socks/src/main/java/io/netty/handler/codec/socks/SocksInitRequestDecoder.java +++ b/codec-socks/src/main/java/io/netty/handler/codec/socks/SocksInitRequestDecoder.java @@ -35,11 +35,11 @@ public class SocksInitRequestDecoder extends ReplayingDecoder { } @Override - protected void decode(ChannelHandlerContext ctx, ByteBuf byteBuf, List out) throws Exception { + protected void decode(ChannelHandlerContext ctx, ByteBuf byteBuf) throws Exception { switch (state()) { case CHECK_PROTOCOL_VERSION: { if (byteBuf.readByte() != SocksProtocolVersion.SOCKS5.byteValue()) { - out.add(SocksCommonUtils.UNKNOWN_SOCKS_REQUEST); + ctx.fireChannelRead(SocksCommonUtils.UNKNOWN_SOCKS_REQUEST); break; } checkpoint(State.READ_AUTH_SCHEMES); @@ -55,7 +55,7 @@ public class SocksInitRequestDecoder extends ReplayingDecoder { } else { authSchemes = Collections.emptyList(); } - out.add(new SocksInitRequest(authSchemes)); + ctx.fireChannelRead(new SocksInitRequest(authSchemes)); break; } default: { diff --git a/codec-socks/src/main/java/io/netty/handler/codec/socks/SocksInitResponseDecoder.java b/codec-socks/src/main/java/io/netty/handler/codec/socks/SocksInitResponseDecoder.java index 339732008f..985763f3cc 100644 --- a/codec-socks/src/main/java/io/netty/handler/codec/socks/SocksInitResponseDecoder.java +++ b/codec-socks/src/main/java/io/netty/handler/codec/socks/SocksInitResponseDecoder.java @@ -20,8 +20,6 @@ import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.ReplayingDecoder; import io.netty.handler.codec.socks.SocksInitResponseDecoder.State; -import java.util.List; - /** * Decodes {@link ByteBuf}s into {@link SocksInitResponse}. * Before returning SocksResponse decoder removes itself from pipeline. @@ -33,18 +31,18 @@ public class SocksInitResponseDecoder extends ReplayingDecoder { } @Override - protected void decode(ChannelHandlerContext ctx, ByteBuf byteBuf, List out) throws Exception { + protected void decode(ChannelHandlerContext ctx, ByteBuf byteBuf) throws Exception { switch (state()) { case CHECK_PROTOCOL_VERSION: { if (byteBuf.readByte() != SocksProtocolVersion.SOCKS5.byteValue()) { - out.add(SocksCommonUtils.UNKNOWN_SOCKS_RESPONSE); + ctx.fireChannelRead(SocksCommonUtils.UNKNOWN_SOCKS_RESPONSE); break; } checkpoint(State.READ_PREFERRED_AUTH_TYPE); } case READ_PREFERRED_AUTH_TYPE: { SocksAuthScheme authScheme = SocksAuthScheme.valueOf(byteBuf.readByte()); - out.add(new SocksInitResponse(authScheme)); + ctx.fireChannelRead(new SocksInitResponse(authScheme)); break; } default: { diff --git a/codec-socks/src/main/java/io/netty/handler/codec/socksx/SocksPortUnificationServerHandler.java b/codec-socks/src/main/java/io/netty/handler/codec/socksx/SocksPortUnificationServerHandler.java index 0e0daf2702..1f16beebd4 100644 --- a/codec-socks/src/main/java/io/netty/handler/codec/socksx/SocksPortUnificationServerHandler.java +++ b/codec-socks/src/main/java/io/netty/handler/codec/socksx/SocksPortUnificationServerHandler.java @@ -30,8 +30,6 @@ import io.netty.handler.codec.socksx.v5.Socks5ServerEncoder; import io.netty.util.internal.logging.InternalLogger; import io.netty.util.internal.logging.InternalLoggerFactory; -import java.util.List; - /** * Detects the version of the current SOCKS connection and initializes the pipeline with * {@link Socks4ServerDecoder} or {@link Socks5InitialRequestDecoder}. @@ -61,7 +59,7 @@ public class SocksPortUnificationServerHandler extends ByteToMessageDecoder { } @Override - protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { + protected void decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception { final int readerIndex = in.readerIndex(); if (in.writerIndex() == readerIndex) { return; diff --git a/codec-socks/src/main/java/io/netty/handler/codec/socksx/v4/Socks4ClientDecoder.java b/codec-socks/src/main/java/io/netty/handler/codec/socksx/v4/Socks4ClientDecoder.java index 6f69939762..2cc31fc11c 100755 --- a/codec-socks/src/main/java/io/netty/handler/codec/socksx/v4/Socks4ClientDecoder.java +++ b/codec-socks/src/main/java/io/netty/handler/codec/socksx/v4/Socks4ClientDecoder.java @@ -23,8 +23,6 @@ import io.netty.handler.codec.ReplayingDecoder; import io.netty.handler.codec.socksx.v4.Socks4ClientDecoder.State; import io.netty.util.NetUtil; -import java.util.List; - /** * Decodes a single {@link Socks4CommandResponse} from the inbound {@link ByteBuf}s. * On successful decode, this decoder will forward the received data to the next handler, so that @@ -45,7 +43,7 @@ public class Socks4ClientDecoder extends ReplayingDecoder { } @Override - protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { + protected void decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception { try { switch (state()) { case START: { @@ -58,13 +56,13 @@ public class Socks4ClientDecoder extends ReplayingDecoder { final int dstPort = in.readUnsignedShort(); final String dstAddr = NetUtil.intToIpAddress(in.readInt()); - out.add(new DefaultSocks4CommandResponse(status, dstAddr, dstPort)); + ctx.fireChannelRead(new DefaultSocks4CommandResponse(status, dstAddr, dstPort)); checkpoint(State.SUCCESS); } case SUCCESS: { int readableBytes = actualReadableBytes(); if (readableBytes > 0) { - out.add(in.readRetainedSlice(readableBytes)); + ctx.fireChannelRead(in.readRetainedSlice(readableBytes)); } break; } @@ -74,18 +72,18 @@ public class Socks4ClientDecoder extends ReplayingDecoder { } } } catch (Exception e) { - fail(out, e); + fail(ctx, e); } } - private void fail(List out, Exception cause) { + private void fail(ChannelHandlerContext ctx, Exception cause) { if (!(cause instanceof DecoderException)) { cause = new DecoderException(cause); } Socks4CommandResponse m = new DefaultSocks4CommandResponse(Socks4CommandStatus.REJECTED_OR_FAILED); m.setDecoderResult(DecoderResult.failure(cause)); - out.add(m); + ctx.fireChannelRead(m); checkpoint(State.FAILURE); } diff --git a/codec-socks/src/main/java/io/netty/handler/codec/socksx/v4/Socks4ServerDecoder.java b/codec-socks/src/main/java/io/netty/handler/codec/socksx/v4/Socks4ServerDecoder.java index bcfec54922..70713c06d1 100755 --- a/codec-socks/src/main/java/io/netty/handler/codec/socksx/v4/Socks4ServerDecoder.java +++ b/codec-socks/src/main/java/io/netty/handler/codec/socksx/v4/Socks4ServerDecoder.java @@ -25,8 +25,6 @@ import io.netty.handler.codec.socksx.v4.Socks4ServerDecoder.State; import io.netty.util.CharsetUtil; import io.netty.util.NetUtil; -import java.util.List; - /** * Decodes a single {@link Socks4CommandRequest} from the inbound {@link ByteBuf}s. * On successful decode, this decoder will forward the received data to the next handler, so that @@ -56,7 +54,7 @@ public class Socks4ServerDecoder extends ReplayingDecoder { } @Override - protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { + protected void decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception { try { switch (state()) { case START: { @@ -79,13 +77,13 @@ public class Socks4ServerDecoder extends ReplayingDecoder { if (!"0.0.0.0".equals(dstAddr) && dstAddr.startsWith("0.0.0.")) { dstAddr = readString("dstAddr", in); } - out.add(new DefaultSocks4CommandRequest(type, dstAddr, dstPort, userId)); + ctx.fireChannelRead(new DefaultSocks4CommandRequest(type, dstAddr, dstPort, userId)); checkpoint(State.SUCCESS); } case SUCCESS: { int readableBytes = actualReadableBytes(); if (readableBytes > 0) { - out.add(in.readRetainedSlice(readableBytes)); + ctx.fireChannelRead(in.readRetainedSlice(readableBytes)); } break; } @@ -95,11 +93,11 @@ public class Socks4ServerDecoder extends ReplayingDecoder { } } } catch (Exception e) { - fail(out, e); + fail(ctx, e); } } - private void fail(List out, Exception cause) { + private void fail(ChannelHandlerContext ctx, Exception cause) { if (!(cause instanceof DecoderException)) { cause = new DecoderException(cause); } @@ -111,7 +109,7 @@ public class Socks4ServerDecoder extends ReplayingDecoder { userId != null? userId : ""); m.setDecoderResult(DecoderResult.failure(cause)); - out.add(m); + ctx.fireChannelRead(m); checkpoint(State.FAILURE); } diff --git a/codec-socks/src/main/java/io/netty/handler/codec/socksx/v5/Socks5CommandRequestDecoder.java b/codec-socks/src/main/java/io/netty/handler/codec/socksx/v5/Socks5CommandRequestDecoder.java index ef909b8964..b4b89f00f3 100644 --- a/codec-socks/src/main/java/io/netty/handler/codec/socksx/v5/Socks5CommandRequestDecoder.java +++ b/codec-socks/src/main/java/io/netty/handler/codec/socksx/v5/Socks5CommandRequestDecoder.java @@ -26,8 +26,6 @@ import io.netty.handler.codec.ReplayingDecoder; import io.netty.handler.codec.socksx.SocksVersion; import io.netty.handler.codec.socksx.v5.Socks5CommandRequestDecoder.State; -import java.util.List; - /** * Decodes a single {@link Socks5CommandRequest} from the inbound {@link ByteBuf}s. * On successful decode, this decoder will forward the received data to the next handler, so that @@ -56,7 +54,7 @@ public class Socks5CommandRequestDecoder extends ReplayingDecoder { } @Override - protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { + protected void decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception { try { switch (state()) { case INIT: { @@ -72,13 +70,13 @@ public class Socks5CommandRequestDecoder extends ReplayingDecoder { final String dstAddr = addressDecoder.decodeAddress(dstAddrType, in); final int dstPort = in.readUnsignedShort(); - out.add(new DefaultSocks5CommandRequest(type, dstAddrType, dstAddr, dstPort)); + ctx.fireChannelRead(new DefaultSocks5CommandRequest(type, dstAddrType, dstAddr, dstPort)); checkpoint(State.SUCCESS); } case SUCCESS: { int readableBytes = actualReadableBytes(); if (readableBytes > 0) { - out.add(in.readRetainedSlice(readableBytes)); + ctx.fireChannelRead(in.readRetainedSlice(readableBytes)); } break; } @@ -88,11 +86,11 @@ public class Socks5CommandRequestDecoder extends ReplayingDecoder { } } } catch (Exception e) { - fail(out, e); + fail(ctx, e); } } - private void fail(List out, Exception cause) { + private void fail(ChannelHandlerContext ctx, Exception cause) { if (!(cause instanceof DecoderException)) { cause = new DecoderException(cause); } @@ -102,6 +100,6 @@ public class Socks5CommandRequestDecoder extends ReplayingDecoder { Socks5Message m = new DefaultSocks5CommandRequest( Socks5CommandType.CONNECT, Socks5AddressType.IPv4, "0.0.0.0", 1); m.setDecoderResult(DecoderResult.failure(cause)); - out.add(m); + ctx.fireChannelRead(m); } } diff --git a/codec-socks/src/main/java/io/netty/handler/codec/socksx/v5/Socks5CommandResponseDecoder.java b/codec-socks/src/main/java/io/netty/handler/codec/socksx/v5/Socks5CommandResponseDecoder.java index af04e41b80..0d0a4e5e8f 100644 --- a/codec-socks/src/main/java/io/netty/handler/codec/socksx/v5/Socks5CommandResponseDecoder.java +++ b/codec-socks/src/main/java/io/netty/handler/codec/socksx/v5/Socks5CommandResponseDecoder.java @@ -26,8 +26,6 @@ import io.netty.handler.codec.ReplayingDecoder; import io.netty.handler.codec.socksx.SocksVersion; import io.netty.handler.codec.socksx.v5.Socks5CommandResponseDecoder.State; -import java.util.List; - /** * Decodes a single {@link Socks5CommandResponse} from the inbound {@link ByteBuf}s. * On successful decode, this decoder will forward the received data to the next handler, so that @@ -56,7 +54,7 @@ public class Socks5CommandResponseDecoder extends ReplayingDecoder { } @Override - protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { + protected void decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception { try { switch (state()) { case INIT: { @@ -71,13 +69,13 @@ public class Socks5CommandResponseDecoder extends ReplayingDecoder { final String addr = addressDecoder.decodeAddress(addrType, in); final int port = in.readUnsignedShort(); - out.add(new DefaultSocks5CommandResponse(status, addrType, addr, port)); + ctx.fireChannelRead(new DefaultSocks5CommandResponse(status, addrType, addr, port)); checkpoint(State.SUCCESS); } case SUCCESS: { int readableBytes = actualReadableBytes(); if (readableBytes > 0) { - out.add(in.readRetainedSlice(readableBytes)); + ctx.fireChannelRead(in.readRetainedSlice(readableBytes)); } break; } @@ -87,11 +85,11 @@ public class Socks5CommandResponseDecoder extends ReplayingDecoder { } } } catch (Exception e) { - fail(out, e); + fail(ctx, e); } } - private void fail(List out, Exception cause) { + private void fail(ChannelHandlerContext ctx, Exception cause) { if (!(cause instanceof DecoderException)) { cause = new DecoderException(cause); } @@ -101,6 +99,6 @@ public class Socks5CommandResponseDecoder extends ReplayingDecoder { Socks5Message m = new DefaultSocks5CommandResponse( Socks5CommandStatus.FAILURE, Socks5AddressType.IPv4, null, 0); m.setDecoderResult(DecoderResult.failure(cause)); - out.add(m); + ctx.fireChannelRead(m); } } diff --git a/codec-socks/src/main/java/io/netty/handler/codec/socksx/v5/Socks5InitialRequestDecoder.java b/codec-socks/src/main/java/io/netty/handler/codec/socksx/v5/Socks5InitialRequestDecoder.java index 45682faf41..a9cd9d2a6f 100644 --- a/codec-socks/src/main/java/io/netty/handler/codec/socksx/v5/Socks5InitialRequestDecoder.java +++ b/codec-socks/src/main/java/io/netty/handler/codec/socksx/v5/Socks5InitialRequestDecoder.java @@ -24,8 +24,6 @@ import io.netty.handler.codec.ReplayingDecoder; import io.netty.handler.codec.socksx.SocksVersion; import io.netty.handler.codec.socksx.v5.Socks5InitialRequestDecoder.State; -import java.util.List; - /** * Decodes a single {@link Socks5InitialRequest} from the inbound {@link ByteBuf}s. * On successful decode, this decoder will forward the received data to the next handler, so that @@ -45,7 +43,7 @@ public class Socks5InitialRequestDecoder extends ReplayingDecoder { } @Override - protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { + protected void decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception { try { switch (state()) { case INIT: { @@ -62,13 +60,13 @@ public class Socks5InitialRequestDecoder extends ReplayingDecoder { authMethods[i] = Socks5AuthMethod.valueOf(in.readByte()); } - out.add(new DefaultSocks5InitialRequest(authMethods)); + ctx.fireChannelRead(new DefaultSocks5InitialRequest(authMethods)); checkpoint(State.SUCCESS); } case SUCCESS: { int readableBytes = actualReadableBytes(); if (readableBytes > 0) { - out.add(in.readRetainedSlice(readableBytes)); + ctx.fireChannelRead(in.readRetainedSlice(readableBytes)); } break; } @@ -78,11 +76,11 @@ public class Socks5InitialRequestDecoder extends ReplayingDecoder { } } } catch (Exception e) { - fail(out, e); + fail(ctx, e); } } - private void fail(List out, Exception cause) { + private void fail(ChannelHandlerContext ctx, Exception cause) { if (!(cause instanceof DecoderException)) { cause = new DecoderException(cause); } @@ -91,6 +89,6 @@ public class Socks5InitialRequestDecoder extends ReplayingDecoder { Socks5Message m = new DefaultSocks5InitialRequest(Socks5AuthMethod.NO_AUTH); m.setDecoderResult(DecoderResult.failure(cause)); - out.add(m); + ctx.fireChannelRead(m); } } diff --git a/codec-socks/src/main/java/io/netty/handler/codec/socksx/v5/Socks5InitialResponseDecoder.java b/codec-socks/src/main/java/io/netty/handler/codec/socksx/v5/Socks5InitialResponseDecoder.java index 8eb429c634..a096e9e0a3 100644 --- a/codec-socks/src/main/java/io/netty/handler/codec/socksx/v5/Socks5InitialResponseDecoder.java +++ b/codec-socks/src/main/java/io/netty/handler/codec/socksx/v5/Socks5InitialResponseDecoder.java @@ -24,8 +24,6 @@ import io.netty.handler.codec.ReplayingDecoder; import io.netty.handler.codec.socksx.SocksVersion; import io.netty.handler.codec.socksx.v5.Socks5InitialResponseDecoder.State; -import java.util.List; - /** * Decodes a single {@link Socks5InitialResponse} from the inbound {@link ByteBuf}s. * On successful decode, this decoder will forward the received data to the next handler, so that @@ -45,7 +43,7 @@ public class Socks5InitialResponseDecoder extends ReplayingDecoder { } @Override - protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { + protected void decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception { try { switch (state()) { case INIT: { @@ -56,13 +54,13 @@ public class Socks5InitialResponseDecoder extends ReplayingDecoder { } final Socks5AuthMethod authMethod = Socks5AuthMethod.valueOf(in.readByte()); - out.add(new DefaultSocks5InitialResponse(authMethod)); + ctx.fireChannelRead(new DefaultSocks5InitialResponse(authMethod)); checkpoint(State.SUCCESS); } case SUCCESS: { int readableBytes = actualReadableBytes(); if (readableBytes > 0) { - out.add(in.readRetainedSlice(readableBytes)); + ctx.fireChannelRead(in.readRetainedSlice(readableBytes)); } break; } @@ -72,11 +70,11 @@ public class Socks5InitialResponseDecoder extends ReplayingDecoder { } } } catch (Exception e) { - fail(out, e); + fail(ctx, e); } } - private void fail(List out, Exception cause) { + private void fail(ChannelHandlerContext ctx, Exception cause) { if (!(cause instanceof DecoderException)) { cause = new DecoderException(cause); } @@ -85,6 +83,6 @@ public class Socks5InitialResponseDecoder extends ReplayingDecoder { Socks5Message m = new DefaultSocks5InitialResponse(Socks5AuthMethod.UNACCEPTED); m.setDecoderResult(DecoderResult.failure(cause)); - out.add(m); + ctx.fireChannelRead(m); } } diff --git a/codec-socks/src/main/java/io/netty/handler/codec/socksx/v5/Socks5PasswordAuthRequestDecoder.java b/codec-socks/src/main/java/io/netty/handler/codec/socksx/v5/Socks5PasswordAuthRequestDecoder.java index 896c5f5ea3..6e3dcc8428 100644 --- a/codec-socks/src/main/java/io/netty/handler/codec/socksx/v5/Socks5PasswordAuthRequestDecoder.java +++ b/codec-socks/src/main/java/io/netty/handler/codec/socksx/v5/Socks5PasswordAuthRequestDecoder.java @@ -24,8 +24,6 @@ import io.netty.handler.codec.ReplayingDecoder; import io.netty.handler.codec.socksx.v5.Socks5PasswordAuthRequestDecoder.State; import io.netty.util.CharsetUtil; -import java.util.List; - /** * Decodes a single {@link Socks5PasswordAuthRequest} from the inbound {@link ByteBuf}s. * On successful decode, this decoder will forward the received data to the next handler, so that @@ -45,7 +43,7 @@ public class Socks5PasswordAuthRequestDecoder extends ReplayingDecoder { } @Override - protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { + protected void decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception { try { switch (state()) { case INIT: { @@ -60,7 +58,7 @@ public class Socks5PasswordAuthRequestDecoder extends ReplayingDecoder { final int totalLength = usernameLength + passwordLength + 3; in.skipBytes(totalLength); - out.add(new DefaultSocks5PasswordAuthRequest( + ctx.fireChannelRead(new DefaultSocks5PasswordAuthRequest( in.toString(startOffset + 2, usernameLength, CharsetUtil.US_ASCII), in.toString(startOffset + 3 + usernameLength, passwordLength, CharsetUtil.US_ASCII))); @@ -69,7 +67,7 @@ public class Socks5PasswordAuthRequestDecoder extends ReplayingDecoder { case SUCCESS: { int readableBytes = actualReadableBytes(); if (readableBytes > 0) { - out.add(in.readRetainedSlice(readableBytes)); + ctx.fireChannelRead(in.readRetainedSlice(readableBytes)); } break; } @@ -79,11 +77,11 @@ public class Socks5PasswordAuthRequestDecoder extends ReplayingDecoder { } } } catch (Exception e) { - fail(out, e); + fail(ctx, e); } } - private void fail(List out, Exception cause) { + private void fail(ChannelHandlerContext ctx, Exception cause) { if (!(cause instanceof DecoderException)) { cause = new DecoderException(cause); } @@ -92,6 +90,6 @@ public class Socks5PasswordAuthRequestDecoder extends ReplayingDecoder { Socks5Message m = new DefaultSocks5PasswordAuthRequest("", ""); m.setDecoderResult(DecoderResult.failure(cause)); - out.add(m); + ctx.fireChannelRead(m); } } diff --git a/codec-socks/src/main/java/io/netty/handler/codec/socksx/v5/Socks5PasswordAuthResponseDecoder.java b/codec-socks/src/main/java/io/netty/handler/codec/socksx/v5/Socks5PasswordAuthResponseDecoder.java index d338bd7009..016bab14ca 100644 --- a/codec-socks/src/main/java/io/netty/handler/codec/socksx/v5/Socks5PasswordAuthResponseDecoder.java +++ b/codec-socks/src/main/java/io/netty/handler/codec/socksx/v5/Socks5PasswordAuthResponseDecoder.java @@ -23,8 +23,6 @@ import io.netty.handler.codec.DecoderResult; import io.netty.handler.codec.ReplayingDecoder; import io.netty.handler.codec.socksx.v5.Socks5PasswordAuthResponseDecoder.State; -import java.util.List; - /** * Decodes a single {@link Socks5PasswordAuthResponse} from the inbound {@link ByteBuf}s. * On successful decode, this decoder will forward the received data to the next handler, so that @@ -44,7 +42,7 @@ public class Socks5PasswordAuthResponseDecoder extends ReplayingDecoder { } @Override - protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { + protected void decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception { try { switch (state()) { case INIT: { @@ -53,13 +51,14 @@ public class Socks5PasswordAuthResponseDecoder extends ReplayingDecoder { throw new DecoderException("unsupported subnegotiation version: " + version + " (expected: 1)"); } - out.add(new DefaultSocks5PasswordAuthResponse(Socks5PasswordAuthStatus.valueOf(in.readByte()))); + ctx.fireChannelRead( + new DefaultSocks5PasswordAuthResponse(Socks5PasswordAuthStatus.valueOf(in.readByte()))); checkpoint(State.SUCCESS); } case SUCCESS: { int readableBytes = actualReadableBytes(); if (readableBytes > 0) { - out.add(in.readRetainedSlice(readableBytes)); + ctx.fireChannelRead(in.readRetainedSlice(readableBytes)); } break; } @@ -69,11 +68,11 @@ public class Socks5PasswordAuthResponseDecoder extends ReplayingDecoder { } } } catch (Exception e) { - fail(out, e); + fail(ctx, e); } } - private void fail(List out, Exception cause) { + private void fail(ChannelHandlerContext ctx, Exception cause) { if (!(cause instanceof DecoderException)) { cause = new DecoderException(cause); } @@ -82,6 +81,6 @@ public class Socks5PasswordAuthResponseDecoder extends ReplayingDecoder { Socks5Message m = new DefaultSocks5PasswordAuthResponse(Socks5PasswordAuthStatus.FAILURE); m.setDecoderResult(DecoderResult.failure(cause)); - out.add(m); + ctx.fireChannelRead(m); } } diff --git a/codec-stomp/src/main/java/io/netty/handler/codec/stomp/StompSubframeDecoder.java b/codec-stomp/src/main/java/io/netty/handler/codec/stomp/StompSubframeDecoder.java index fe95e7c755..8c1ef1b9c6 100644 --- a/codec-stomp/src/main/java/io/netty/handler/codec/stomp/StompSubframeDecoder.java +++ b/codec-stomp/src/main/java/io/netty/handler/codec/stomp/StompSubframeDecoder.java @@ -15,6 +15,7 @@ */ package io.netty.handler.codec.stomp; + import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelHandlerContext; @@ -28,7 +29,6 @@ import io.netty.util.internal.AppendableCharSequence; import io.netty.util.internal.ObjectUtil; import io.netty.util.internal.StringUtil; -import java.util.List; import java.util.Objects; import static io.netty.buffer.ByteBufUtil.*; @@ -94,7 +94,7 @@ public class StompSubframeDecoder extends ReplayingDecoder { } @Override - protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { + protected void decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception { switch (state()) { case SKIP_CONTROL_CHARACTERS: skipControlCharacters(in); @@ -107,13 +107,13 @@ public class StompSubframeDecoder extends ReplayingDecoder { command = readCommand(in); frame = new DefaultStompHeadersSubframe(command); checkpoint(readHeaders(in, frame.headers())); - out.add(frame); + ctx.fireChannelRead(frame); } catch (Exception e) { if (frame == null) { frame = new DefaultStompHeadersSubframe(command); } frame.setDecoderResult(DecoderResult.failure(e)); - out.add(frame); + ctx.fireChannelRead(frame); checkpoint(State.BAD_FRAME); return; } @@ -142,7 +142,7 @@ public class StompSubframeDecoder extends ReplayingDecoder { lastContent = new DefaultLastStompContentSubframe(chunkBuffer); checkpoint(State.FINALIZE_FRAME_READ); } else { - out.add(new DefaultStompContentSubframe(chunkBuffer)); + ctx.fireChannelRead(new DefaultStompContentSubframe(chunkBuffer)); return; } } else { @@ -161,7 +161,7 @@ public class StompSubframeDecoder extends ReplayingDecoder { lastContent = new DefaultLastStompContentSubframe(chunkBuffer); checkpoint(State.FINALIZE_FRAME_READ); } else { - out.add(new DefaultStompContentSubframe(chunkBuffer)); + ctx.fireChannelRead(new DefaultStompContentSubframe(chunkBuffer)); return; } } @@ -172,13 +172,13 @@ public class StompSubframeDecoder extends ReplayingDecoder { if (lastContent == null) { lastContent = LastStompContentSubframe.EMPTY_LAST_CONTENT; } - out.add(lastContent); + ctx.fireChannelRead(lastContent); resetDecoder(); } } catch (Exception e) { StompContentSubframe errorContent = new DefaultLastStompContentSubframe(Unpooled.EMPTY_BUFFER); errorContent.setDecoderResult(DecoderResult.failure(e)); - out.add(errorContent); + ctx.fireChannelRead(errorContent); checkpoint(State.BAD_FRAME); } } diff --git a/codec-xml/src/main/java/io/netty/handler/codec/xml/XmlDecoder.java b/codec-xml/src/main/java/io/netty/handler/codec/xml/XmlDecoder.java index e84e5952f8..ecaf7c4eb8 100644 --- a/codec-xml/src/main/java/io/netty/handler/codec/xml/XmlDecoder.java +++ b/codec-xml/src/main/java/io/netty/handler/codec/xml/XmlDecoder.java @@ -25,7 +25,6 @@ import io.netty.handler.codec.ByteToMessageDecoder; import javax.xml.stream.XMLStreamConstants; import javax.xml.stream.XMLStreamException; -import java.util.List; /** * Async XML decoder based on Aalto XML parser. @@ -42,7 +41,7 @@ public class XmlDecoder extends ByteToMessageDecoder { private final AsyncByteArrayFeeder streamFeeder = streamReader.getInputFeeder(); @Override - protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { + protected void decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception { byte[] buffer = new byte[in.readableBytes()]; in.readBytes(buffer); try { @@ -56,11 +55,11 @@ public class XmlDecoder extends ByteToMessageDecoder { int type = streamReader.next(); switch (type) { case XMLStreamConstants.START_DOCUMENT: - out.add(new XmlDocumentStart(streamReader.getEncoding(), streamReader.getVersion(), + ctx.fireChannelRead(new XmlDocumentStart(streamReader.getEncoding(), streamReader.getVersion(), streamReader.isStandalone(), streamReader.getCharacterEncodingScheme())); break; case XMLStreamConstants.END_DOCUMENT: - out.add(XML_DOCUMENT_END); + ctx.fireChannelRead(XML_DOCUMENT_END); break; case XMLStreamConstants.START_ELEMENT: XmlElementStart elementStart = new XmlElementStart(streamReader.getLocalName(), @@ -76,7 +75,7 @@ public class XmlDecoder extends ByteToMessageDecoder { streamReader.getNamespaceURI(x)); elementStart.namespaces().add(namespace); } - out.add(elementStart); + ctx.fireChannelRead(elementStart); break; case XMLStreamConstants.END_ELEMENT: XmlElementEnd elementEnd = new XmlElementEnd(streamReader.getLocalName(), @@ -86,28 +85,29 @@ public class XmlDecoder extends ByteToMessageDecoder { streamReader.getNamespaceURI(x)); elementEnd.namespaces().add(namespace); } - out.add(elementEnd); + ctx.fireChannelRead(elementEnd); break; case XMLStreamConstants.PROCESSING_INSTRUCTION: - out.add(new XmlProcessingInstruction(streamReader.getPIData(), streamReader.getPITarget())); + ctx.fireChannelRead( + new XmlProcessingInstruction(streamReader.getPIData(), streamReader.getPITarget())); break; case XMLStreamConstants.CHARACTERS: - out.add(new XmlCharacters(streamReader.getText())); + ctx.fireChannelRead(new XmlCharacters(streamReader.getText())); break; case XMLStreamConstants.COMMENT: - out.add(new XmlComment(streamReader.getText())); + ctx.fireChannelRead(new XmlComment(streamReader.getText())); break; case XMLStreamConstants.SPACE: - out.add(new XmlSpace(streamReader.getText())); + ctx.fireChannelRead(new XmlSpace(streamReader.getText())); break; case XMLStreamConstants.ENTITY_REFERENCE: - out.add(new XmlEntityReference(streamReader.getLocalName(), streamReader.getText())); + ctx.fireChannelRead(new XmlEntityReference(streamReader.getLocalName(), streamReader.getText())); break; case XMLStreamConstants.DTD: - out.add(new XmlDTD(streamReader.getText())); + ctx.fireChannelRead(new XmlDTD(streamReader.getText())); break; case XMLStreamConstants.CDATA: - out.add(new XmlCdata(streamReader.getText())); + ctx.fireChannelRead(new XmlCdata(streamReader.getText())); break; } } diff --git a/codec/src/main/java/io/netty/handler/codec/ByteToMessageCodec.java b/codec/src/main/java/io/netty/handler/codec/ByteToMessageCodec.java index 0176ee4d9f..b48beceeeb 100644 --- a/codec/src/main/java/io/netty/handler/codec/ByteToMessageCodec.java +++ b/codec/src/main/java/io/netty/handler/codec/ByteToMessageCodec.java @@ -21,8 +21,6 @@ import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelPromise; import io.netty.util.internal.TypeParameterMatcher; -import java.util.List; - /** * A Codec for on-the-fly encoding/decoding of bytes to messages and vise-versa. * @@ -38,13 +36,13 @@ public abstract class ByteToMessageCodec extends ChannelHandlerAdapter { private final ByteToMessageDecoder decoder = new ByteToMessageDecoder() { @Override - public void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { - ByteToMessageCodec.this.decode(ctx, in, out); + public void decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception { + ByteToMessageCodec.this.decode(ctx, in); } @Override - protected void decodeLast(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { - ByteToMessageCodec.this.decodeLast(ctx, in, out); + protected void decodeLast(ChannelHandlerContext ctx, ByteBuf in) throws Exception { + ByteToMessageCodec.this.decodeLast(ctx, in); } }; @@ -142,18 +140,18 @@ public abstract class ByteToMessageCodec extends ChannelHandlerAdapter { protected abstract void encode(ChannelHandlerContext ctx, I msg, ByteBuf out) throws Exception; /** - * @see ByteToMessageDecoder#decode(ChannelHandlerContext, ByteBuf, List) + * @see ByteToMessageDecoder#decode(ChannelHandlerContext, ByteBuf) */ - protected abstract void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception; + protected abstract void decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception; /** - * @see ByteToMessageDecoder#decodeLast(ChannelHandlerContext, ByteBuf, List) + * @see ByteToMessageDecoder#decodeLast(ChannelHandlerContext, ByteBuf) */ - protected void decodeLast(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { + protected void decodeLast(ChannelHandlerContext ctx, ByteBuf in) throws Exception { if (in.isReadable()) { // Only call decode() if there is something left in the buffer to decode. // See https://github.com/netty/netty/issues/4386 - decode(ctx, in, out); + decode(ctx, in); } } diff --git a/codec/src/main/java/io/netty/handler/codec/ByteToMessageDecoder.java b/codec/src/main/java/io/netty/handler/codec/ByteToMessageDecoder.java index c83339bbdb..a51ab57105 100644 --- a/codec/src/main/java/io/netty/handler/codec/ByteToMessageDecoder.java +++ b/codec/src/main/java/io/netty/handler/codec/ByteToMessageDecoder.java @@ -26,10 +26,18 @@ import io.netty.channel.ChannelHandlerAdapter; import io.netty.channel.ChannelConfig; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandler; +import io.netty.channel.Channel; +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelPipeline; +import io.netty.channel.ChannelProgressivePromise; +import io.netty.channel.ChannelPromise; import io.netty.channel.socket.ChannelInputShutdownEvent; +import io.netty.util.Attribute; +import io.netty.util.AttributeKey; +import io.netty.util.concurrent.EventExecutor; import io.netty.util.internal.StringUtil; -import java.util.List; +import java.net.SocketAddress; import static java.lang.Integer.MAX_VALUE; @@ -38,14 +46,15 @@ import static java.lang.Integer.MAX_VALUE; * other Message type. * * For example here is an implementation which reads all readable bytes from - * the input {@link ByteBuf} and create a new {@link ByteBuf}. + * the input {@link ByteBuf}, creates a new {@link ByteBuf} and forward it to the next {@link ChannelHandler} + * in the {@link ChannelPipeline}. * *
  *     public class SquareDecoder extends {@link ByteToMessageDecoder} {
  *         {@code @Override}
- *         public void decode({@link ChannelHandlerContext} ctx, {@link ByteBuf} in, List<Object> out)
+ *         public void decode({@link ChannelHandlerContext} ctx, {@link ByteBuf} in)
  *                 throws {@link Exception} {
- *             out.add(in.readBytes(in.readableBytes()));
+ *             ctx.fireChannelRead(in.readBytes(in.readableBytes()));
  *         }
  *     }
  * 
@@ -71,8 +80,9 @@ import static java.lang.Integer.MAX_VALUE; * annotated with {@link @Sharable}. *

* Some methods such as {@link ByteBuf#readBytes(int)} will cause a memory leak if the returned buffer - * is not released or added to the out {@link List}. Use derived buffers like {@link ByteBuf#readSlice(int)} - * to avoid leaking memory. + * is not released or fired through the {@link ChannelPipeline} via + * {@link ChannelHandlerContext#fireChannelRead(Object)}. Use derived buffers like {@link ByteBuf#readSlice(int)} to + * avoid leaking memory. */ public abstract class ByteToMessageDecoder extends ChannelHandlerAdapter { @@ -161,6 +171,7 @@ public abstract class ByteToMessageDecoder extends ChannelHandlerAdapter { private byte decodeState = STATE_INIT; private int discardAfterReads = 16; private int numReads; + private ByteToMessageDecoderContext context; protected ByteToMessageDecoder() { ensureNotSharable(); @@ -226,6 +237,15 @@ public abstract class ByteToMessageDecoder extends ChannelHandlerAdapter { } } + @Override + public final void handlerAdded(ChannelHandlerContext ctx) throws Exception { + this.context = new ByteToMessageDecoderContext(ctx); + handlerAdded0(this.context); + } + + protected void handlerAdded0(ChannelHandlerContext ctx) throws Exception { + } + @Override public final void handlerRemoved(ChannelHandlerContext ctx) throws Exception { if (decodeState == STATE_CALLING_CHILD_DECODE) { @@ -245,7 +265,7 @@ public abstract class ByteToMessageDecoder extends ChannelHandlerAdapter { buf.release(); } } - handlerRemoved0(ctx); + handlerRemoved0(this.context); } /** @@ -257,7 +277,6 @@ public abstract class ByteToMessageDecoder extends ChannelHandlerAdapter { @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { if (msg instanceof ByteBuf) { - CodecOutputList out = CodecOutputList.newInstance(); try { ByteBuf data = (ByteBuf) msg; first = cumulation == null; @@ -266,7 +285,9 @@ public abstract class ByteToMessageDecoder extends ChannelHandlerAdapter { } else { cumulation = cumulator.cumulate(ctx.alloc(), cumulation, data); } - callDecode(ctx, cumulation, out); + assert context.ctx == ctx || ctx == context; + + callDecode(context, cumulation); } catch (DecoderException e) { throw e; } catch (Exception e) { @@ -283,38 +304,14 @@ public abstract class ByteToMessageDecoder extends ChannelHandlerAdapter { discardSomeReadBytes(); } - int size = out.size(); - firedChannelRead |= out.insertSinceRecycled(); - fireChannelRead(ctx, out, size); - out.recycle(); + firedChannelRead |= context.fireChannelReadCallCount() > 0; + context.reset(); } } else { ctx.fireChannelRead(msg); } } - /** - * Get {@code numElements} out of the {@link List} and forward these through the pipeline. - */ - static void fireChannelRead(ChannelHandlerContext ctx, List msgs, int numElements) { - if (msgs instanceof CodecOutputList) { - fireChannelRead(ctx, (CodecOutputList) msgs, numElements); - } else { - for (int i = 0; i < numElements; i++) { - ctx.fireChannelRead(msgs.get(i)); - } - } - } - - /** - * Get {@code numElements} out of the {@link CodecOutputList} and forward these through the pipeline. - */ - static void fireChannelRead(ChannelHandlerContext ctx, CodecOutputList msgs, int numElements) { - for (int i = 0; i < numElements; i ++) { - ctx.fireChannelRead(msgs.getUnsafe(i)); - } - } - @Override public void channelReadComplete(ChannelHandlerContext ctx) throws Exception { numReads = 0; @@ -341,7 +338,8 @@ public abstract class ByteToMessageDecoder extends ChannelHandlerAdapter { @Override public void channelInactive(ChannelHandlerContext ctx) throws Exception { - channelInputClosed(ctx, true); + assert context.ctx == ctx || ctx == context; + channelInputClosed(context, true); } @Override @@ -350,37 +348,31 @@ public abstract class ByteToMessageDecoder extends ChannelHandlerAdapter { // The decodeLast method is invoked when a channelInactive event is encountered. // This method is responsible for ending requests in some situations and must be called // when the input has been shutdown. - channelInputClosed(ctx, false); + assert context.ctx == ctx || ctx == context; + channelInputClosed(context, false); } ctx.fireUserEventTriggered(evt); } - private void channelInputClosed(ChannelHandlerContext ctx, boolean callChannelInactive) { - CodecOutputList out = CodecOutputList.newInstance(); + private void channelInputClosed(ByteToMessageDecoderContext ctx, boolean callChannelInactive) { try { - channelInputClosed(ctx, out); + channelInputClosed(ctx); } catch (DecoderException e) { throw e; } catch (Exception e) { throw new DecoderException(e); } finally { - try { - if (cumulation != null) { - cumulation.release(); - cumulation = null; - } - int size = out.size(); - fireChannelRead(ctx, out, size); - if (size > 0) { - // Something was read, call fireChannelReadComplete() - ctx.fireChannelReadComplete(); - } - if (callChannelInactive) { - ctx.fireChannelInactive(); - } - } finally { - // Recycle in all cases - out.recycle(); + if (cumulation != null) { + cumulation.release(); + cumulation = null; + } + if (ctx.fireChannelReadCallCount() > 0) { + ctx.reset(); + // Something was read, call fireChannelReadComplete() + ctx.fireChannelReadComplete(); + } + if (callChannelInactive) { + ctx.fireChannelInactive(); } } } @@ -389,45 +381,29 @@ public abstract class ByteToMessageDecoder extends ChannelHandlerAdapter { * Called when the input of the channel was closed which may be because it changed to inactive or because of * {@link ChannelInputShutdownEvent}. */ - void channelInputClosed(ChannelHandlerContext ctx, List out) throws Exception { + void channelInputClosed(ByteToMessageDecoderContext ctx) throws Exception { if (cumulation != null) { - callDecode(ctx, cumulation, out); - decodeLast(ctx, cumulation, out); + callDecode(ctx, cumulation); + decodeLast(ctx, cumulation); } else { - decodeLast(ctx, Unpooled.EMPTY_BUFFER, out); + decodeLast(ctx, Unpooled.EMPTY_BUFFER); } } /** * Called once data should be decoded from the given {@link ByteBuf}. This method will call - * {@link #decode(ChannelHandlerContext, ByteBuf, List)} as long as decoding should take place. + * {@link #decode(ChannelHandlerContext, ByteBuf)} as long as decoding should take place. * * @param ctx the {@link ChannelHandlerContext} which this {@link ByteToMessageDecoder} belongs to * @param in the {@link ByteBuf} from which to read data - * @param out the {@link List} to which decoded messages should be added */ - protected void callDecode(ChannelHandlerContext ctx, ByteBuf in, List out) { + void callDecode(ByteToMessageDecoderContext ctx, ByteBuf in) { try { - while (in.isReadable()) { - int outSize = out.size(); - - if (outSize > 0) { - fireChannelRead(ctx, out, outSize); - out.clear(); - - // Check if this handler was removed before continuing with decoding. - // If it was removed, it is not safe to continue to operate on the buffer. - // - // See: - // - https://github.com/netty/netty/issues/4635 - if (ctx.isRemoved()) { - break; - } - outSize = 0; - } + while (in.isReadable() && !ctx.isRemoved()) { int oldInputLength = in.readableBytes(); - decodeRemovalReentryProtection(ctx, in, out); + int numReadCalled = ctx.fireChannelReadCallCount(); + decodeRemovalReentryProtection(ctx, in); // Check if this handler was removed before continuing the loop. // If it was removed, it is not safe to continue to operate on the buffer. @@ -437,7 +413,7 @@ public abstract class ByteToMessageDecoder extends ChannelHandlerAdapter { break; } - if (outSize == out.size()) { + if (numReadCalled == ctx.fireChannelReadCallCount()) { if (oldInputLength == in.readableBytes()) { break; } else { @@ -469,10 +445,9 @@ public abstract class ByteToMessageDecoder extends ChannelHandlerAdapter { * * @param ctx the {@link ChannelHandlerContext} which this {@link ByteToMessageDecoder} belongs to * @param in the {@link ByteBuf} from which to read data - * @param out the {@link List} to which decoded messages should be added * @throws Exception is thrown if an error occurs */ - protected abstract void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception; + protected abstract void decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception; /** * Decode the from one {@link ByteBuf} to an other. This method will be called till either the input @@ -481,20 +456,17 @@ public abstract class ByteToMessageDecoder extends ChannelHandlerAdapter { * * @param ctx the {@link ChannelHandlerContext} which this {@link ByteToMessageDecoder} belongs to * @param in the {@link ByteBuf} from which to read data - * @param out the {@link List} to which decoded messages should be added * @throws Exception is thrown if an error occurs */ - final void decodeRemovalReentryProtection(ChannelHandlerContext ctx, ByteBuf in, List out) + final void decodeRemovalReentryProtection(ChannelHandlerContext ctx, ByteBuf in) throws Exception { decodeState = STATE_CALLING_CHILD_DECODE; try { - decode(ctx, in, out); + decode(ctx, in); } finally { boolean removePending = decodeState == STATE_HANDLER_REMOVED_PENDING; decodeState = STATE_INIT; if (removePending) { - fireChannelRead(ctx, out, out.size()); - out.clear(); handlerRemoved(ctx); } } @@ -504,14 +476,14 @@ public abstract class ByteToMessageDecoder extends ChannelHandlerAdapter { * Is called one last time when the {@link ChannelHandlerContext} goes in-active. Which means the * {@link #channelInactive(ChannelHandlerContext)} was triggered. * - * By default this will just call {@link #decode(ChannelHandlerContext, ByteBuf, List)} but sub-classes may + * By default this will just call {@link #decode(ChannelHandlerContext, ByteBuf)} but sub-classes may * override this for some special cleanup operation. */ - protected void decodeLast(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { + protected void decodeLast(ChannelHandlerContext ctx, ByteBuf in) throws Exception { if (in.isReadable()) { // Only call decode() if there is something left in the buffer to decode. // See https://github.com/netty/netty/issues/4386 - decodeRemovalReentryProtection(ctx, in, out); + decodeRemovalReentryProtection(ctx, in); } } @@ -540,4 +512,251 @@ public abstract class ByteToMessageDecoder extends ChannelHandlerAdapter { */ ByteBuf cumulate(ByteBufAllocator alloc, ByteBuf cumulation, ByteBuf in); } + + // Package private so we can also make use of it in ReplayingDecoder. + static final class ByteToMessageDecoderContext implements ChannelHandlerContext { + private final ChannelHandlerContext ctx; + private int fireChannelReadCalled; + + private ByteToMessageDecoderContext(ChannelHandlerContext ctx) { + this.ctx = ctx; + } + + void reset() { + fireChannelReadCalled = 0; + } + + int fireChannelReadCallCount() { + return fireChannelReadCalled; + } + + @Override + public Channel channel() { + return ctx.channel(); + } + + @Override + public EventExecutor executor() { + return ctx.executor(); + } + + @Override + public String name() { + return ctx.name(); + } + + @Override + public ChannelHandler handler() { + return ctx.handler(); + } + + @Override + public boolean isRemoved() { + return ctx.isRemoved(); + } + + @Override + public ChannelHandlerContext fireChannelRegistered() { + ctx.fireChannelRegistered(); + return this; + } + + @Override + public ChannelHandlerContext fireChannelUnregistered() { + ctx.fireChannelUnregistered(); + return this; + } + + @Override + public ChannelHandlerContext fireChannelActive() { + ctx.fireChannelActive(); + return this; + } + + @Override + public ChannelHandlerContext fireChannelInactive() { + ctx.fireChannelInactive(); + return this; + } + + @Override + public ChannelHandlerContext fireExceptionCaught(Throwable cause) { + ctx.fireExceptionCaught(cause); + return this; + } + + @Override + public ChannelHandlerContext fireUserEventTriggered(Object evt) { + ctx.fireUserEventTriggered(evt); + return this; + } + + @Override + public ChannelHandlerContext fireChannelRead(Object msg) { + fireChannelReadCalled ++; + ctx.fireChannelRead(msg); + return this; + } + + @Override + public ChannelHandlerContext fireChannelReadComplete() { + ctx.fireChannelReadComplete(); + return this; + } + + @Override + public ChannelHandlerContext fireChannelWritabilityChanged() { + ctx.fireChannelWritabilityChanged(); + return this; + } + + @Override + public ChannelHandlerContext read() { + ctx.read(); + return this; + } + + @Override + public ChannelHandlerContext flush() { + ctx.flush(); + return this; + } + + @Override + public ChannelPipeline pipeline() { + return ctx.pipeline(); + } + + @Override + public ByteBufAllocator alloc() { + return ctx.alloc(); + } + + @Override + @Deprecated + public Attribute attr(AttributeKey key) { + return ctx.attr(key); + } + + @Override + @Deprecated + public boolean hasAttr(AttributeKey key) { + return ctx.hasAttr(key); + } + + @Override + public ChannelFuture bind(SocketAddress localAddress) { + return ctx.bind(localAddress); + } + + @Override + public ChannelFuture connect(SocketAddress remoteAddress) { + return ctx.connect(remoteAddress); + } + + @Override + public ChannelFuture connect(SocketAddress remoteAddress, SocketAddress localAddress) { + return ctx.connect(remoteAddress, localAddress); + } + + @Override + public ChannelFuture disconnect() { + return ctx.disconnect(); + } + + @Override + public ChannelFuture close() { + return ctx.close(); + } + + @Override + public ChannelFuture deregister() { + return ctx.deregister(); + } + + @Override + public ChannelFuture bind(SocketAddress localAddress, ChannelPromise promise) { + return ctx.bind(localAddress, promise); + } + + @Override + public ChannelFuture connect(SocketAddress remoteAddress, ChannelPromise promise) { + return ctx.connect(remoteAddress, promise); + } + + @Override + public ChannelFuture connect(SocketAddress remoteAddress, SocketAddress localAddress, ChannelPromise promise) { + return ctx.connect(remoteAddress, localAddress, promise); + } + + @Override + public ChannelFuture disconnect(ChannelPromise promise) { + return ctx.disconnect(promise); + } + + @Override + public ChannelFuture close(ChannelPromise promise) { + return ctx.close(promise); + } + + @Override + public ChannelFuture register() { + return ctx.register(); + } + + @Override + public ChannelFuture register(ChannelPromise promise) { + return ctx.register(promise); + } + + @Override + public ChannelFuture deregister(ChannelPromise promise) { + return ctx.deregister(promise); + } + + @Override + public ChannelFuture write(Object msg) { + return ctx.write(msg); + } + + @Override + public ChannelFuture write(Object msg, ChannelPromise promise) { + return ctx.write(msg, promise); + } + + @Override + public ChannelFuture writeAndFlush(Object msg, ChannelPromise promise) { + return ctx.writeAndFlush(msg, promise); + } + + @Override + public ChannelFuture writeAndFlush(Object msg) { + return ctx.writeAndFlush(msg); + } + + @Override + public ChannelPromise newPromise() { + return ctx.newPromise(); + } + + @Override + public ChannelProgressivePromise newProgressivePromise() { + return ctx.newProgressivePromise(); + } + + @Override + public ChannelFuture newSucceededFuture() { + return ctx.newSucceededFuture(); + } + + @Override + public ChannelFuture newFailedFuture(Throwable cause) { + return ctx.newFailedFuture(cause); + } + + @Override + public ChannelPromise voidPromise() { + return ctx.voidPromise(); + } + } } diff --git a/codec/src/main/java/io/netty/handler/codec/DatagramPacketDecoder.java b/codec/src/main/java/io/netty/handler/codec/DatagramPacketDecoder.java index bb8cafe4d2..13f4c6a245 100644 --- a/codec/src/main/java/io/netty/handler/codec/DatagramPacketDecoder.java +++ b/codec/src/main/java/io/netty/handler/codec/DatagramPacketDecoder.java @@ -56,8 +56,8 @@ public class DatagramPacketDecoder extends MessageToMessageDecoder out) throws Exception { - decoder.decode(ctx, msg.content(), out); + protected void decode(ChannelHandlerContext ctx, DatagramPacket msg) throws Exception { + decoder.decode(ctx, msg.content()); } @Override diff --git a/codec/src/main/java/io/netty/handler/codec/DelimiterBasedFrameDecoder.java b/codec/src/main/java/io/netty/handler/codec/DelimiterBasedFrameDecoder.java index 8c06dd85c1..bec802e908 100644 --- a/codec/src/main/java/io/netty/handler/codec/DelimiterBasedFrameDecoder.java +++ b/codec/src/main/java/io/netty/handler/codec/DelimiterBasedFrameDecoder.java @@ -21,8 +21,6 @@ import static java.util.Objects.requireNonNull; import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; -import java.util.List; - /** * A decoder that splits the received {@link ByteBuf}s by one or more * delimiters. It is particularly useful for decoding the frames which ends @@ -213,10 +211,10 @@ public class DelimiterBasedFrameDecoder extends ByteToMessageDecoder { } @Override - protected final void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { - Object decoded = decode(ctx, in); + protected final void decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception { + Object decoded = decode0(ctx, in); if (decoded != null) { - out.add(decoded); + ctx.fireChannelRead(decoded); } } @@ -228,9 +226,9 @@ public class DelimiterBasedFrameDecoder extends ByteToMessageDecoder { * @return frame the {@link ByteBuf} which represent the frame or {@code null} if no frame could * be created. */ - protected Object decode(ChannelHandlerContext ctx, ByteBuf buffer) throws Exception { + protected Object decode0(ChannelHandlerContext ctx, ByteBuf buffer) throws Exception { if (lineBasedDecoder != null) { - return lineBasedDecoder.decode(ctx, buffer); + return lineBasedDecoder.decode0(ctx, buffer); } // Try all delimiters and choose the delimiter which yields the shortest frame. int minFrameLength = Integer.MAX_VALUE; diff --git a/codec/src/main/java/io/netty/handler/codec/FixedLengthFrameDecoder.java b/codec/src/main/java/io/netty/handler/codec/FixedLengthFrameDecoder.java index 9475e5b651..ef3fa7a0d6 100644 --- a/codec/src/main/java/io/netty/handler/codec/FixedLengthFrameDecoder.java +++ b/codec/src/main/java/io/netty/handler/codec/FixedLengthFrameDecoder.java @@ -20,8 +20,6 @@ import static io.netty.util.internal.ObjectUtil.checkPositive; import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; -import java.util.List; - /** * A decoder that splits the received {@link ByteBuf}s by the fixed number * of bytes. For example, if you received the following four fragmented packets: @@ -53,10 +51,10 @@ public class FixedLengthFrameDecoder extends ByteToMessageDecoder { } @Override - protected final void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { - Object decoded = decode(ctx, in); + protected final void decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception { + Object decoded = decode0(ctx, in); if (decoded != null) { - out.add(decoded); + ctx.fireChannelRead(decoded); } } @@ -68,7 +66,7 @@ public class FixedLengthFrameDecoder extends ByteToMessageDecoder { * @return frame the {@link ByteBuf} which represent the frame or {@code null} if no frame could * be created. */ - protected Object decode( + protected Object decode0( @SuppressWarnings("UnusedParameters") ChannelHandlerContext ctx, ByteBuf in) throws Exception { if (in.readableBytes() < frameLength) { return null; diff --git a/codec/src/main/java/io/netty/handler/codec/LengthFieldBasedFrameDecoder.java b/codec/src/main/java/io/netty/handler/codec/LengthFieldBasedFrameDecoder.java index 63aabc6b76..e943a10940 100644 --- a/codec/src/main/java/io/netty/handler/codec/LengthFieldBasedFrameDecoder.java +++ b/codec/src/main/java/io/netty/handler/codec/LengthFieldBasedFrameDecoder.java @@ -20,7 +20,6 @@ import static io.netty.util.internal.ObjectUtil.checkPositiveOrZero; import static java.util.Objects.requireNonNull; import java.nio.ByteOrder; -import java.util.List; import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; @@ -329,10 +328,10 @@ public class LengthFieldBasedFrameDecoder extends ByteToMessageDecoder { } @Override - protected final void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { - Object decoded = decode(ctx, in); + protected final void decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception { + Object decoded = decode0(ctx, in); if (decoded != null) { - out.add(decoded); + ctx.fireChannelRead(decoded); } } @@ -394,7 +393,7 @@ public class LengthFieldBasedFrameDecoder extends ByteToMessageDecoder { * @return frame the {@link ByteBuf} which represent the frame or {@code null} if no frame could * be created. */ - protected Object decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception { + protected Object decode0(ChannelHandlerContext ctx, ByteBuf in) throws Exception { if (discardingTooLongFrame) { discardingTooLongFrame(in); } diff --git a/codec/src/main/java/io/netty/handler/codec/LineBasedFrameDecoder.java b/codec/src/main/java/io/netty/handler/codec/LineBasedFrameDecoder.java index fda45cc401..92cc1aa05f 100644 --- a/codec/src/main/java/io/netty/handler/codec/LineBasedFrameDecoder.java +++ b/codec/src/main/java/io/netty/handler/codec/LineBasedFrameDecoder.java @@ -19,8 +19,6 @@ import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; import io.netty.util.ByteProcessor; -import java.util.List; - /** * A decoder that splits the received {@link ByteBuf}s on line endings. *

@@ -80,10 +78,10 @@ public class LineBasedFrameDecoder extends ByteToMessageDecoder { } @Override - protected final void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { - Object decoded = decode(ctx, in); + protected final void decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception { + Object decoded = decode0(ctx, in); if (decoded != null) { - out.add(decoded); + ctx.fireChannelRead(decoded); } } @@ -95,7 +93,7 @@ public class LineBasedFrameDecoder extends ByteToMessageDecoder { * @return frame the {@link ByteBuf} which represent the frame or {@code null} if no frame could * be created. */ - protected Object decode(ChannelHandlerContext ctx, ByteBuf buffer) throws Exception { + protected Object decode0(ChannelHandlerContext ctx, ByteBuf buffer) throws Exception { final int eol = findEndOfLine(buffer); if (!discarding) { if (eol >= 0) { diff --git a/codec/src/main/java/io/netty/handler/codec/MessageAggregator.java b/codec/src/main/java/io/netty/handler/codec/MessageAggregator.java index 3a498422bf..1f4d9a6f39 100644 --- a/codec/src/main/java/io/netty/handler/codec/MessageAggregator.java +++ b/codec/src/main/java/io/netty/handler/codec/MessageAggregator.java @@ -25,8 +25,6 @@ import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelPipeline; import io.netty.util.ReferenceCountUtil; -import java.util.List; - import static io.netty.buffer.Unpooled.EMPTY_BUFFER; import static io.netty.util.internal.ObjectUtil.checkPositiveOrZero; @@ -205,9 +203,8 @@ public abstract class MessageAggregator out) throws Exception { + protected void decode(final ChannelHandlerContext ctx, I msg) throws Exception { assert aggregating; - if (isStartMessage(msg)) { handlingOversizedMessage = false; if (currentMessage != null) { @@ -259,8 +256,8 @@ public abstract class MessageAggregator extends Cha @Override @SuppressWarnings("unchecked") - protected void decode(ChannelHandlerContext ctx, Object msg, List out) throws Exception { - MessageToMessageCodec.this.decode(ctx, (INBOUND_IN) msg, out); + protected void decode(ChannelHandlerContext ctx, Object msg) throws Exception { + MessageToMessageCodec.this.decode(ctx, (INBOUND_IN) msg); } }; @@ -141,8 +141,8 @@ public abstract class MessageToMessageCodec extends Cha throws Exception; /** - * @see MessageToMessageDecoder#decode(ChannelHandlerContext, Object, List) + * @see MessageToMessageDecoder#decode(ChannelHandlerContext, Object) */ - protected abstract void decode(ChannelHandlerContext ctx, INBOUND_IN msg, List out) + protected abstract void decode(ChannelHandlerContext ctx, INBOUND_IN msg) throws Exception; } diff --git a/codec/src/main/java/io/netty/handler/codec/MessageToMessageDecoder.java b/codec/src/main/java/io/netty/handler/codec/MessageToMessageDecoder.java index 8ca99d46b8..0d42f7759f 100644 --- a/codec/src/main/java/io/netty/handler/codec/MessageToMessageDecoder.java +++ b/codec/src/main/java/io/netty/handler/codec/MessageToMessageDecoder.java @@ -79,29 +79,22 @@ public abstract class MessageToMessageDecoder extends ChannelHandlerAdapter i @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { - CodecOutputList out = CodecOutputList.newInstance(); try { if (acceptInboundMessage(msg)) { @SuppressWarnings("unchecked") I cast = (I) msg; try { - decode(ctx, cast, out); + decode(ctx, cast); } finally { ReferenceCountUtil.release(cast); } } else { - out.add(msg); + ctx.fireChannelRead(msg); } } catch (DecoderException e) { throw e; } catch (Exception e) { throw new DecoderException(e); - } finally { - int size = out.size(); - for (int i = 0; i < size; i ++) { - ctx.fireChannelRead(out.getUnsafe(i)); - } - out.recycle(); } } @@ -111,8 +104,7 @@ public abstract class MessageToMessageDecoder extends ChannelHandlerAdapter i * * @param ctx the {@link ChannelHandlerContext} which this {@link MessageToMessageDecoder} belongs to * @param msg the message to decode to an other one - * @param out the {@link List} to which decoded messages should be added * @throws Exception is thrown if an error occurs */ - protected abstract void decode(ChannelHandlerContext ctx, I msg, List out) throws Exception; + protected abstract void decode(ChannelHandlerContext ctx, I msg) throws Exception; } diff --git a/codec/src/main/java/io/netty/handler/codec/ReplayingDecoder.java b/codec/src/main/java/io/netty/handler/codec/ReplayingDecoder.java index ff37374c4d..9ade582153 100644 --- a/codec/src/main/java/io/netty/handler/codec/ReplayingDecoder.java +++ b/codec/src/main/java/io/netty/handler/codec/ReplayingDecoder.java @@ -23,8 +23,6 @@ import io.netty.channel.ChannelPipeline; import io.netty.util.Signal; import io.netty.util.internal.StringUtil; -import java.util.List; - /** * A specialized variation of {@link ByteToMessageDecoder} which enables implementation * of a non-blocking decoder in the blocking I/O paradigm. @@ -39,8 +37,7 @@ import java.util.List; * public class IntegerHeaderFrameDecoder extends {@link ByteToMessageDecoder} { * * {@code @Override} - * protected void decode({@link ChannelHandlerContext} ctx, - * {@link ByteBuf} buf, List<Object> out) throws Exception { + * protected void decode({@link ChannelHandlerContext} ctx, {@link ByteBuf} buf) throws Exception { * * if (buf.readableBytes() < 4) { * return; @@ -54,7 +51,7 @@ import java.util.List; * return; * } * - * out.add(buf.readBytes(length)); + * ctx.fireChannelRead(buf.readBytes(length)); * } * } * @@ -108,7 +105,7 @@ import java.util.List; * private final Queue<Integer> values = new LinkedList<Integer>(); * * {@code @Override} - * public void decode(.., {@link ByteBuf} buf, List<Object> out) throws Exception { + * public void decode({@link ChannelHandlerContext} ctx, {@link ByteBuf} buf) throws Exception { * * // A message contains 2 integers. * values.offer(buf.readInt()); @@ -117,7 +114,7 @@ import java.util.List; * // This assertion will fail intermittently since values.offer() * // can be called more than two times! * assert values.size() == 2; - * out.add(values.poll() + values.poll()); + * ctx.fireChannelRead(values.poll() + values.poll()); * } * } * The correct implementation looks like the following, and you can also @@ -128,7 +125,7 @@ import java.util.List; * private final Queue<Integer> values = new LinkedList<Integer>(); * * {@code @Override} - * public void decode(.., {@link ByteBuf} buf, List<Object> out) throws Exception { + * public void decode({@link ChannelHandlerContext} ctx, {@link ByteBuf} buf) throws Exception { * * // Revert the state of the variable that might have been changed * // since the last partial decode. @@ -140,7 +137,7 @@ import java.util.List; * * // Now we know this assertion will never fail. * assert values.size() == 2; - * out.add(values.poll() + values.poll()); + * ctx.fireChannelRead(values.poll() + values.poll()); * } * } * @@ -180,8 +177,7 @@ import java.util.List; * } * * {@code @Override} - * protected void decode({@link ChannelHandlerContext} ctx, - * {@link ByteBuf} buf, List<Object> out) throws Exception { + * protected void decode({@link ChannelHandlerContext} ctx, {@link ByteBuf} buf) throws Exception { * switch (state()) { * case READ_LENGTH: * length = buf.readInt(); @@ -189,7 +185,7 @@ import java.util.List; * case READ_CONTENT: * ByteBuf frame = buf.readBytes(length); * checkpoint(MyDecoderState.READ_LENGTH); - * out.add(frame); + * ctx.fireChannelRead(frame); * break; * default: * throw new Error("Shouldn't reach here."); @@ -209,8 +205,7 @@ import java.util.List; * private int length; * * {@code @Override} - * protected void decode({@link ChannelHandlerContext} ctx, - * {@link ByteBuf} buf, List<Object> out) throws Exception { + * protected void decode({@link ChannelHandlerContext} ctx, {@link ByteBuf} buf) throws Exception { * if (!readLength) { * length = buf.readInt(); * readLength = true; @@ -221,7 +216,7 @@ import java.util.List; * ByteBuf frame = buf.readBytes(length); * readLength = false; * checkpoint(); - * out.add(frame); + * ctx.fireChannelRead(frame); * } * } * } @@ -240,8 +235,7 @@ import java.util.List; * public class FirstDecoder extends {@link ReplayingDecoder}<{@link Void}> { * * {@code @Override} - * protected void decode({@link ChannelHandlerContext} ctx, - * {@link ByteBuf} buf, List<Object> out) { + * protected void decode({@link ChannelHandlerContext} ctx, {@link ByteBuf} buf) { * ... * // Decode the first message * Object firstMessage = ...; @@ -251,11 +245,11 @@ import java.util.List; * * if (buf.isReadable()) { * // Hand off the remaining data to the second decoder - * out.add(firstMessage); - * out.add(buf.readBytes(super.actualReadableBytes())); + * ctx.fireChannelRead(firstMessage); + * ctx.fireChannelRead(buf.readBytes(super.actualReadableBytes())); * } else { * // Nothing to hand off - * out.add(firstMessage); + * ctx.fireChannelRead(firstMessage); * } * // Remove the first decoder (me) * ctx.pipeline().remove(this); @@ -322,15 +316,15 @@ public abstract class ReplayingDecoder extends ByteToMessageDecoder { } @Override - final void channelInputClosed(ChannelHandlerContext ctx, List out) throws Exception { + final void channelInputClosed(ByteToMessageDecoderContext ctx) throws Exception { try { replayable.terminate(); if (cumulation != null) { - callDecode(ctx, internalBuffer(), out); + callDecode(ctx, internalBuffer()); } else { replayable.setCumulation(Unpooled.EMPTY_BUFFER); } - decodeLast(ctx, replayable, out); + decodeLast(ctx, replayable); } catch (Signal replay) { // Ignore replay.expect(REPLAY); @@ -338,32 +332,17 @@ public abstract class ReplayingDecoder extends ByteToMessageDecoder { } @Override - protected void callDecode(ChannelHandlerContext ctx, ByteBuf in, List out) { + protected void callDecode(ByteToMessageDecoderContext ctx, ByteBuf in) { replayable.setCumulation(in); try { while (in.isReadable()) { int oldReaderIndex = checkpoint = in.readerIndex(); - int outSize = out.size(); - - if (outSize > 0) { - fireChannelRead(ctx, out, outSize); - out.clear(); - - // Check if this handler was removed before continuing with decoding. - // If it was removed, it is not safe to continue to operate on the buffer. - // - // See: - // - https://github.com/netty/netty/issues/4635 - if (ctx.isRemoved()) { - break; - } - outSize = 0; - } S oldState = state; int oldInputLength = in.readableBytes(); try { - decodeRemovalReentryProtection(ctx, replayable, out); + int oldNumRead = ctx.fireChannelReadCallCount(); + decodeRemovalReentryProtection(ctx, replayable); // Check if this handler was removed before continuing the loop. // If it was removed, it is not safe to continue to operate on the buffer. @@ -373,7 +352,7 @@ public abstract class ReplayingDecoder extends ByteToMessageDecoder { break; } - if (outSize == out.size()) { + if (oldNumRead == ctx.fireChannelReadCallCount()) { if (oldInputLength == in.readableBytes() && oldState == state) { throw new DecoderException( StringUtil.simpleClassName(getClass()) + ".decode() must consume the inbound " + diff --git a/codec/src/main/java/io/netty/handler/codec/base64/Base64Decoder.java b/codec/src/main/java/io/netty/handler/codec/base64/Base64Decoder.java index 7ad220917b..3ab842559c 100644 --- a/codec/src/main/java/io/netty/handler/codec/base64/Base64Decoder.java +++ b/codec/src/main/java/io/netty/handler/codec/base64/Base64Decoder.java @@ -60,7 +60,7 @@ public class Base64Decoder extends MessageToMessageDecoder { } @Override - protected void decode(ChannelHandlerContext ctx, ByteBuf msg, List out) throws Exception { - out.add(Base64.decode(msg, msg.readerIndex(), msg.readableBytes(), dialect)); + protected void decode(ChannelHandlerContext ctx, ByteBuf msg) throws Exception { + ctx.fireChannelRead(Base64.decode(msg, msg.readerIndex(), msg.readableBytes(), dialect)); } } diff --git a/codec/src/main/java/io/netty/handler/codec/bytes/ByteArrayDecoder.java b/codec/src/main/java/io/netty/handler/codec/bytes/ByteArrayDecoder.java index 21429d1867..c3344d1ca5 100644 --- a/codec/src/main/java/io/netty/handler/codec/bytes/ByteArrayDecoder.java +++ b/codec/src/main/java/io/netty/handler/codec/bytes/ByteArrayDecoder.java @@ -51,8 +51,8 @@ import java.util.List; */ public class ByteArrayDecoder extends MessageToMessageDecoder { @Override - protected void decode(ChannelHandlerContext ctx, ByteBuf msg, List out) throws Exception { + protected void decode(ChannelHandlerContext ctx, ByteBuf msg) throws Exception { // copy the ByteBuf content to a byte array - out.add(ByteBufUtil.getBytes(msg)); + ctx.fireChannelRead(ByteBufUtil.getBytes(msg)); } } diff --git a/codec/src/main/java/io/netty/handler/codec/compression/Bzip2Decoder.java b/codec/src/main/java/io/netty/handler/codec/compression/Bzip2Decoder.java index b66ff5956f..1ec0786e25 100644 --- a/codec/src/main/java/io/netty/handler/codec/compression/Bzip2Decoder.java +++ b/codec/src/main/java/io/netty/handler/codec/compression/Bzip2Decoder.java @@ -19,8 +19,6 @@ import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.ByteToMessageDecoder; -import java.util.List; - import static io.netty.handler.codec.compression.Bzip2Constants.*; /** @@ -77,7 +75,7 @@ public class Bzip2Decoder extends ByteToMessageDecoder { private int streamCRC; @Override - protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { + protected void decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception { if (!in.isReadable()) { return; } @@ -302,7 +300,7 @@ public class Bzip2Decoder extends ByteToMessageDecoder { int currentBlockCRC = blockDecompressor.checkCRC(); streamCRC = (streamCRC << 1 | streamCRC >>> 31) ^ currentBlockCRC; - out.add(uncompressed); + ctx.fireChannelRead(uncompressed); success = true; } finally { if (!success) { diff --git a/codec/src/main/java/io/netty/handler/codec/compression/FastLzFrameDecoder.java b/codec/src/main/java/io/netty/handler/codec/compression/FastLzFrameDecoder.java index 52ce381666..6ae3dde187 100644 --- a/codec/src/main/java/io/netty/handler/codec/compression/FastLzFrameDecoder.java +++ b/codec/src/main/java/io/netty/handler/codec/compression/FastLzFrameDecoder.java @@ -20,7 +20,6 @@ import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.ByteToMessageDecoder; import io.netty.util.internal.EmptyArrays; -import java.util.List; import java.util.zip.Adler32; import java.util.zip.Checksum; @@ -108,7 +107,7 @@ public class FastLzFrameDecoder extends ByteToMessageDecoder { } @Override - protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { + protected void decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception { try { switch (currentState) { case INIT_BLOCK: @@ -199,7 +198,7 @@ public class FastLzFrameDecoder extends ByteToMessageDecoder { if (uncompressed != null) { uncompressed.writerIndex(uncompressed.writerIndex() + originalLength); - out.add(uncompressed); + ctx.fireChannelRead(uncompressed); } in.skipBytes(chunkLength); diff --git a/codec/src/main/java/io/netty/handler/codec/compression/JZlibDecoder.java b/codec/src/main/java/io/netty/handler/codec/compression/JZlibDecoder.java index 12012820f5..27abb27038 100644 --- a/codec/src/main/java/io/netty/handler/codec/compression/JZlibDecoder.java +++ b/codec/src/main/java/io/netty/handler/codec/compression/JZlibDecoder.java @@ -22,8 +22,6 @@ import com.jcraft.jzlib.JZlib; import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; -import java.util.List; - public class JZlibDecoder extends ZlibDecoder { private final Inflater z = new Inflater(); @@ -81,7 +79,7 @@ public class JZlibDecoder extends ZlibDecoder { } @Override - protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { + protected void decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception { if (finished) { // Skip data received after finished. in.skipBytes(in.readableBytes()); @@ -154,7 +152,7 @@ public class JZlibDecoder extends ZlibDecoder { } finally { in.skipBytes(z.next_in_index - oldNextInIndex); if (decompressed.isReadable()) { - out.add(decompressed); + ctx.fireChannelRead(decompressed); } else { decompressed.release(); } diff --git a/codec/src/main/java/io/netty/handler/codec/compression/JdkZlibDecoder.java b/codec/src/main/java/io/netty/handler/codec/compression/JdkZlibDecoder.java index 0fa295ae14..6e5edf4323 100644 --- a/codec/src/main/java/io/netty/handler/codec/compression/JdkZlibDecoder.java +++ b/codec/src/main/java/io/netty/handler/codec/compression/JdkZlibDecoder.java @@ -20,7 +20,6 @@ import static java.util.Objects.requireNonNull; import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; -import java.util.List; import java.util.zip.CRC32; import java.util.zip.DataFormatException; import java.util.zip.Deflater; @@ -128,7 +127,7 @@ public class JdkZlibDecoder extends ZlibDecoder { } @Override - protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { + protected void decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception { if (finished) { // Skip data received after finished. in.skipBytes(in.readableBytes()); @@ -231,7 +230,7 @@ public class JdkZlibDecoder extends ZlibDecoder { } finally { if (decompressed.isReadable()) { - out.add(decompressed); + ctx.fireChannelRead(decompressed); } else { decompressed.release(); } diff --git a/codec/src/main/java/io/netty/handler/codec/compression/Lz4FrameDecoder.java b/codec/src/main/java/io/netty/handler/codec/compression/Lz4FrameDecoder.java index 790a30695b..715bced0b5 100644 --- a/codec/src/main/java/io/netty/handler/codec/compression/Lz4FrameDecoder.java +++ b/codec/src/main/java/io/netty/handler/codec/compression/Lz4FrameDecoder.java @@ -22,7 +22,6 @@ import net.jpountz.lz4.LZ4Exception; import net.jpountz.lz4.LZ4Factory; import net.jpountz.lz4.LZ4FastDecompressor; -import java.util.List; import java.util.zip.Checksum; import static io.netty.handler.codec.compression.Lz4Constants.*; @@ -143,7 +142,7 @@ public class Lz4FrameDecoder extends ByteToMessageDecoder { } @Override - protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { + protected void decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception { try { switch (currentState) { case INIT_BLOCK: @@ -238,7 +237,7 @@ public class Lz4FrameDecoder extends ByteToMessageDecoder { if (checksum != null) { CompressionUtil.checkChecksum(checksum, uncompressed, currentChecksum); } - out.add(uncompressed); + ctx.fireChannelRead(uncompressed); uncompressed = null; currentState = State.INIT_BLOCK; } catch (LZ4Exception e) { diff --git a/codec/src/main/java/io/netty/handler/codec/compression/LzfDecoder.java b/codec/src/main/java/io/netty/handler/codec/compression/LzfDecoder.java index 61a5f0edbb..28c83e5ea7 100644 --- a/codec/src/main/java/io/netty/handler/codec/compression/LzfDecoder.java +++ b/codec/src/main/java/io/netty/handler/codec/compression/LzfDecoder.java @@ -22,8 +22,6 @@ import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.ByteToMessageDecoder; -import java.util.List; - import static com.ning.compress.lzf.LZFChunk.BLOCK_TYPE_COMPRESSED; import static com.ning.compress.lzf.LZFChunk.BLOCK_TYPE_NON_COMPRESSED; import static com.ning.compress.lzf.LZFChunk.BYTE_V; @@ -108,7 +106,7 @@ public class LzfDecoder extends ByteToMessageDecoder { } @Override - protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { + protected void decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception { try { switch (currentState) { case INIT_BLOCK: @@ -178,7 +176,7 @@ public class LzfDecoder extends ByteToMessageDecoder { try { decoder.decodeChunk(inputArray, inPos, outputArray, outPos, outPos + originalLength); uncompressed.writerIndex(uncompressed.writerIndex() + originalLength); - out.add(uncompressed); + ctx.fireChannelRead(uncompressed); in.skipBytes(chunkLength); success = true; } finally { @@ -191,7 +189,7 @@ public class LzfDecoder extends ByteToMessageDecoder { recycler.releaseInputBuffer(inputArray); } } else if (chunkLength > 0) { - out.add(in.readRetainedSlice(chunkLength)); + ctx.fireChannelRead(in.readRetainedSlice(chunkLength)); } currentState = State.INIT_BLOCK; diff --git a/codec/src/main/java/io/netty/handler/codec/compression/SnappyFrameDecoder.java b/codec/src/main/java/io/netty/handler/codec/compression/SnappyFrameDecoder.java index 4762e72b15..a6b8831c76 100644 --- a/codec/src/main/java/io/netty/handler/codec/compression/SnappyFrameDecoder.java +++ b/codec/src/main/java/io/netty/handler/codec/compression/SnappyFrameDecoder.java @@ -19,8 +19,6 @@ import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.ByteToMessageDecoder; -import java.util.List; - import static io.netty.handler.codec.compression.Snappy.validateChecksum; /** @@ -76,7 +74,7 @@ public class SnappyFrameDecoder extends ByteToMessageDecoder { } @Override - protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { + protected void decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception { if (corrupted) { in.skipBytes(in.readableBytes()); return; @@ -155,7 +153,7 @@ public class SnappyFrameDecoder extends ByteToMessageDecoder { } else { in.skipBytes(4); } - out.add(in.readRetainedSlice(chunkLength - 4)); + ctx.fireChannelRead(in.readRetainedSlice(chunkLength - 4)); break; case COMPRESSED_DATA: if (!started) { @@ -182,7 +180,7 @@ public class SnappyFrameDecoder extends ByteToMessageDecoder { } else { snappy.decode(in.readSlice(chunkLength - 4), uncompressed); } - out.add(uncompressed); + ctx.fireChannelRead(uncompressed); uncompressed = null; } finally { if (uncompressed != null) { diff --git a/codec/src/main/java/io/netty/handler/codec/json/JsonObjectDecoder.java b/codec/src/main/java/io/netty/handler/codec/json/JsonObjectDecoder.java index 2508ff6c09..3d31aab31f 100644 --- a/codec/src/main/java/io/netty/handler/codec/json/JsonObjectDecoder.java +++ b/codec/src/main/java/io/netty/handler/codec/json/JsonObjectDecoder.java @@ -25,8 +25,6 @@ import io.netty.handler.codec.CorruptedFrameException; import io.netty.handler.codec.TooLongFrameException; import io.netty.channel.ChannelPipeline; -import java.util.List; - /** * Splits a byte stream of JSON objects and arrays into individual objects/arrays and passes them up the * {@link ChannelPipeline}. @@ -89,7 +87,7 @@ public class JsonObjectDecoder extends ByteToMessageDecoder { } @Override - protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { + protected void decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception { if (state == ST_CORRUPTED) { in.skipBytes(in.readableBytes()); return; @@ -121,7 +119,7 @@ public class JsonObjectDecoder extends ByteToMessageDecoder { if (openBraces == 0) { ByteBuf json = extractObject(ctx, in, in.readerIndex(), idx + 1 - in.readerIndex()); if (json != null) { - out.add(json); + ctx.fireChannelRead(json); } // The JSON object/array was extracted => discard the bytes from @@ -149,7 +147,7 @@ public class JsonObjectDecoder extends ByteToMessageDecoder { ByteBuf json = extractObject(ctx, in, in.readerIndex(), idxNoSpaces + 1 - in.readerIndex()); if (json != null) { - out.add(json); + ctx.fireChannelRead(json); } in.readerIndex(idx + 1); diff --git a/codec/src/main/java/io/netty/handler/codec/marshalling/CompatibleMarshallingDecoder.java b/codec/src/main/java/io/netty/handler/codec/marshalling/CompatibleMarshallingDecoder.java index 324ba1a5ad..93519d32e6 100644 --- a/codec/src/main/java/io/netty/handler/codec/marshalling/CompatibleMarshallingDecoder.java +++ b/codec/src/main/java/io/netty/handler/codec/marshalling/CompatibleMarshallingDecoder.java @@ -24,7 +24,6 @@ import org.jboss.marshalling.ByteInput; import org.jboss.marshalling.Unmarshaller; import java.io.ObjectStreamConstants; -import java.util.List; /** * {@link ReplayingDecoder} which use an {@link Unmarshaller} to read the Object out of the {@link ByteBuf}. @@ -55,7 +54,7 @@ public class CompatibleMarshallingDecoder extends ReplayingDecoder { } @Override - protected void decode(ChannelHandlerContext ctx, ByteBuf buffer, List out) throws Exception { + protected void decode(ChannelHandlerContext ctx, ByteBuf buffer) throws Exception { if (discardingTooLongFrame) { buffer.skipBytes(actualReadableBytes()); checkpoint(); @@ -72,7 +71,7 @@ public class CompatibleMarshallingDecoder extends ReplayingDecoder { unmarshaller.start(input); Object obj = unmarshaller.readObject(); unmarshaller.finish(); - out.add(obj); + ctx.fireChannelRead(obj); } catch (LimitingByteInput.TooBigObjectException ignored) { discardingTooLongFrame = true; throw new TooLongFrameException(); @@ -80,7 +79,7 @@ public class CompatibleMarshallingDecoder extends ReplayingDecoder { } @Override - protected void decodeLast(ChannelHandlerContext ctx, ByteBuf buffer, List out) throws Exception { + protected void decodeLast(ChannelHandlerContext ctx, ByteBuf buffer) throws Exception { switch (buffer.readableBytes()) { case 0: return; @@ -92,7 +91,7 @@ public class CompatibleMarshallingDecoder extends ReplayingDecoder { } } - decode(ctx, buffer, out); + decode(ctx, buffer); } @Override diff --git a/codec/src/main/java/io/netty/handler/codec/marshalling/MarshallingDecoder.java b/codec/src/main/java/io/netty/handler/codec/marshalling/MarshallingDecoder.java index af6b9307eb..bc67e2f7f3 100644 --- a/codec/src/main/java/io/netty/handler/codec/marshalling/MarshallingDecoder.java +++ b/codec/src/main/java/io/netty/handler/codec/marshalling/MarshallingDecoder.java @@ -59,8 +59,8 @@ public class MarshallingDecoder extends LengthFieldBasedFrameDecoder { } @Override - protected Object decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception { - ByteBuf frame = (ByteBuf) super.decode(ctx, in); + protected Object decode0(ChannelHandlerContext ctx, ByteBuf in) throws Exception { + ByteBuf frame = (ByteBuf) super.decode0(ctx, in); if (frame == null) { return null; } diff --git a/codec/src/main/java/io/netty/handler/codec/protobuf/ProtobufDecoder.java b/codec/src/main/java/io/netty/handler/codec/protobuf/ProtobufDecoder.java index 3710d3275d..fda50a8d9b 100644 --- a/codec/src/main/java/io/netty/handler/codec/protobuf/ProtobufDecoder.java +++ b/codec/src/main/java/io/netty/handler/codec/protobuf/ProtobufDecoder.java @@ -31,8 +31,6 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import io.netty.handler.codec.LengthFieldPrepender; import io.netty.handler.codec.MessageToMessageDecoder; -import java.util.List; - /** * Decodes a received {@link ByteBuf} into a * Google Protocol Buffers @@ -103,7 +101,7 @@ public class ProtobufDecoder extends MessageToMessageDecoder { } @Override - protected void decode(ChannelHandlerContext ctx, ByteBuf msg, List out) throws Exception { + protected void decode(ChannelHandlerContext ctx, ByteBuf msg) throws Exception { final byte[] array; final int offset; final int length = msg.readableBytes(); @@ -117,16 +115,16 @@ public class ProtobufDecoder extends MessageToMessageDecoder { if (extensionRegistry == null) { if (HAS_PARSER) { - out.add(prototype.getParserForType().parseFrom(array, offset, length)); + ctx.fireChannelRead(prototype.getParserForType().parseFrom(array, offset, length)); } else { - out.add(prototype.newBuilderForType().mergeFrom(array, offset, length).build()); + ctx.fireChannelRead(prototype.newBuilderForType().mergeFrom(array, offset, length).build()); } } else { if (HAS_PARSER) { - out.add(prototype.getParserForType().parseFrom( + ctx.fireChannelRead(prototype.getParserForType().parseFrom( array, offset, length, extensionRegistry)); } else { - out.add(prototype.newBuilderForType().mergeFrom( + ctx.fireChannelRead(prototype.newBuilderForType().mergeFrom( array, offset, length, extensionRegistry).build()); } } diff --git a/codec/src/main/java/io/netty/handler/codec/protobuf/ProtobufDecoderNano.java b/codec/src/main/java/io/netty/handler/codec/protobuf/ProtobufDecoderNano.java index 9fc3f4d4ff..63daeeb397 100644 --- a/codec/src/main/java/io/netty/handler/codec/protobuf/ProtobufDecoderNano.java +++ b/codec/src/main/java/io/netty/handler/codec/protobuf/ProtobufDecoderNano.java @@ -71,8 +71,7 @@ public class ProtobufDecoderNano extends MessageToMessageDecoder { } @Override - protected void decode(ChannelHandlerContext ctx, ByteBuf msg, List out) - throws Exception { + protected void decode(ChannelHandlerContext ctx, ByteBuf msg) throws Exception { final byte[] array; final int offset; final int length = msg.readableBytes(); @@ -84,6 +83,6 @@ public class ProtobufDecoderNano extends MessageToMessageDecoder { offset = 0; } MessageNano prototype = clazz.getConstructor().newInstance(); - out.add(MessageNano.mergeFrom(prototype, array, offset, length)); + ctx.fireChannelRead(MessageNano.mergeFrom(prototype, array, offset, length)); } } diff --git a/codec/src/main/java/io/netty/handler/codec/protobuf/ProtobufVarint32FrameDecoder.java b/codec/src/main/java/io/netty/handler/codec/protobuf/ProtobufVarint32FrameDecoder.java index 994d6b338e..5f40d47fd6 100644 --- a/codec/src/main/java/io/netty/handler/codec/protobuf/ProtobufVarint32FrameDecoder.java +++ b/codec/src/main/java/io/netty/handler/codec/protobuf/ProtobufVarint32FrameDecoder.java @@ -22,8 +22,6 @@ import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.ByteToMessageDecoder; import io.netty.handler.codec.CorruptedFrameException; -import java.util.List; - /** * A decoder that splits the received {@link ByteBuf}s dynamically by the * value of the Google Protocol Buffers @@ -46,7 +44,7 @@ public class ProtobufVarint32FrameDecoder extends ByteToMessageDecoder { // (just like LengthFieldBasedFrameDecoder) @Override - protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) + protected void decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception { int readerIndex = in.readerIndex(); int preIndex = in.readerIndex(); @@ -61,7 +59,7 @@ public class ProtobufVarint32FrameDecoder extends ByteToMessageDecoder { if (in.readableBytes() < length) { in.readerIndex(readerIndex); } else { - out.add(in.readRetainedSlice(length)); + ctx.fireChannelRead(in.readRetainedSlice(length)); } } diff --git a/codec/src/main/java/io/netty/handler/codec/serialization/ObjectDecoder.java b/codec/src/main/java/io/netty/handler/codec/serialization/ObjectDecoder.java index ec8792739a..58612da873 100644 --- a/codec/src/main/java/io/netty/handler/codec/serialization/ObjectDecoder.java +++ b/codec/src/main/java/io/netty/handler/codec/serialization/ObjectDecoder.java @@ -65,8 +65,8 @@ public class ObjectDecoder extends LengthFieldBasedFrameDecoder { } @Override - protected Object decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception { - ByteBuf frame = (ByteBuf) super.decode(ctx, in); + protected Object decode0(ChannelHandlerContext ctx, ByteBuf in) throws Exception { + ByteBuf frame = (ByteBuf) super.decode0(ctx, in); if (frame == null) { return null; } diff --git a/codec/src/main/java/io/netty/handler/codec/string/StringDecoder.java b/codec/src/main/java/io/netty/handler/codec/string/StringDecoder.java index 0efa75c2cc..90983c74f2 100644 --- a/codec/src/main/java/io/netty/handler/codec/string/StringDecoder.java +++ b/codec/src/main/java/io/netty/handler/codec/string/StringDecoder.java @@ -27,7 +27,6 @@ import io.netty.handler.codec.LineBasedFrameDecoder; import io.netty.handler.codec.MessageToMessageDecoder; import java.nio.charset.Charset; -import java.util.List; /** * Decodes a received {@link ByteBuf} into a {@link String}. Please @@ -75,7 +74,7 @@ public class StringDecoder extends MessageToMessageDecoder { } @Override - protected void decode(ChannelHandlerContext ctx, ByteBuf msg, List out) throws Exception { - out.add(msg.toString(charset)); + protected void decode(ChannelHandlerContext ctx, ByteBuf msg) throws Exception { + ctx.fireChannelRead(msg.toString(charset)); } } diff --git a/codec/src/main/java/io/netty/handler/codec/xml/XmlFrameDecoder.java b/codec/src/main/java/io/netty/handler/codec/xml/XmlFrameDecoder.java index 480f0be1c5..641cc23885 100644 --- a/codec/src/main/java/io/netty/handler/codec/xml/XmlFrameDecoder.java +++ b/codec/src/main/java/io/netty/handler/codec/xml/XmlFrameDecoder.java @@ -21,8 +21,6 @@ import io.netty.handler.codec.ByteToMessageDecoder; import io.netty.handler.codec.CorruptedFrameException; import io.netty.handler.codec.TooLongFrameException; -import java.util.List; - /** * A frame decoder for single separate XML based message streams. *

@@ -85,7 +83,7 @@ public class XmlFrameDecoder extends ByteToMessageDecoder { } @Override - protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { + protected void decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception { boolean openingBracketFound = false; boolean atLeastOneXmlElementFound = false; boolean inCDATASection = false; @@ -189,7 +187,7 @@ public class XmlFrameDecoder extends ByteToMessageDecoder { final ByteBuf frame = extractFrame(in, readerIndex + leadingWhiteSpaceCount, xmlElementLength - leadingWhiteSpaceCount); in.skipBytes(xmlElementLength); - out.add(frame); + ctx.fireChannelRead(frame); } } diff --git a/codec/src/test/java/io/netty/handler/codec/ByteToMessageCodecTest.java b/codec/src/test/java/io/netty/handler/codec/ByteToMessageCodecTest.java index 9078fe734b..cf83bd6d44 100644 --- a/codec/src/test/java/io/netty/handler/codec/ByteToMessageCodecTest.java +++ b/codec/src/test/java/io/netty/handler/codec/ByteToMessageCodecTest.java @@ -22,8 +22,6 @@ import io.netty.channel.ChannelHandlerContext; import io.netty.channel.embedded.EmbeddedChannel; import org.junit.Test; -import java.util.List; - import static org.junit.Assert.*; public class ByteToMessageCodecTest { @@ -47,9 +45,9 @@ public class ByteToMessageCodecTest { } @Override - protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { + protected void decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception { if (in.readableBytes() >= 4) { - out.add(in.readInt()); + ctx.fireChannelRead(in.readInt()); } } }; @@ -81,7 +79,7 @@ public class ByteToMessageCodecTest { protected void encode(ChannelHandlerContext ctx, Integer msg, ByteBuf out) throws Exception { } @Override - protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { } + protected void decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception { } } @ChannelHandler.Sharable @@ -94,6 +92,6 @@ public class ByteToMessageCodecTest { protected void encode(ChannelHandlerContext ctx, Integer msg, ByteBuf out) throws Exception { } @Override - protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { } + protected void decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception { } } } diff --git a/codec/src/test/java/io/netty/handler/codec/ByteToMessageDecoderTest.java b/codec/src/test/java/io/netty/handler/codec/ByteToMessageDecoderTest.java index 7814ffe6e1..eda48af9a8 100644 --- a/codec/src/test/java/io/netty/handler/codec/ByteToMessageDecoderTest.java +++ b/codec/src/test/java/io/netty/handler/codec/ByteToMessageDecoderTest.java @@ -26,9 +26,9 @@ import io.netty.channel.ChannelHandler; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelOutboundHandlerAdapter; import io.netty.channel.embedded.EmbeddedChannel; +import org.junit.Ignore; import org.junit.Test; -import java.util.List; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingDeque; import java.util.concurrent.ThreadLocalRandom; @@ -49,7 +49,7 @@ public class ByteToMessageDecoderTest { private boolean removed; @Override - protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) { + protected void decode(ChannelHandlerContext ctx, ByteBuf in) { assertFalse(removed); in.readByte(); ctx.pipeline().remove(this); @@ -72,7 +72,7 @@ public class ByteToMessageDecoderTest { private boolean removed; @Override - protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) { + protected void decode(ChannelHandlerContext ctx, ByteBuf in) { assertFalse(removed); in.readByte(); ctx.pipeline().remove(this); @@ -125,7 +125,7 @@ public class ByteToMessageDecoderTest { private EmbeddedChannel newInternalBufferTestChannel() { return new EmbeddedChannel(new ByteToMessageDecoder() { @Override - protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) { + protected void decode(ChannelHandlerContext ctx, ByteBuf in) { ByteBuf byteBuf = internalBuffer(); assertEquals(1, byteBuf.refCnt()); in.readByte(); @@ -144,7 +144,7 @@ public class ByteToMessageDecoderTest { public void handlerRemovedWillNotReleaseBufferIfDecodeInProgress() { EmbeddedChannel channel = new EmbeddedChannel(new ByteToMessageDecoder() { @Override - protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) { + protected void decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception { ctx.pipeline().remove(this); assertTrue(in.refCnt() != 0); } @@ -172,16 +172,16 @@ public class ByteToMessageDecoderTest { final ByteBuf buf = Unpooled.buffer().writeBytes(new byte[] {'a', 'b'}); EmbeddedChannel channel = new EmbeddedChannel(new ByteToMessageDecoder() { @Override - protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) { + protected void decode(ChannelHandlerContext ctx, ByteBuf in) { int readable = in.readableBytes(); assertTrue(readable > 0); in.skipBytes(readable); } @Override - protected void decodeLast(ChannelHandlerContext ctx, ByteBuf in, List out) { + protected void decodeLast(ChannelHandlerContext ctx, ByteBuf in) { assertFalse(in.isReadable()); - out.add("data"); + ctx.fireChannelRead("data"); } }, new ChannelHandler() { @Override @@ -215,9 +215,9 @@ public class ByteToMessageDecoderTest { final Object upgradeMessage = new Object(); final ByteToMessageDecoder decoder = new ByteToMessageDecoder() { @Override - protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) { + protected void decode(ChannelHandlerContext ctx, ByteBuf in) { assertEquals('a', in.readByte()); - out.add(upgradeMessage); + ctx.fireChannelRead(upgradeMessage); } }; @@ -245,10 +245,10 @@ public class ByteToMessageDecoderTest { public void testDecodeLastEmptyBuffer() { EmbeddedChannel channel = new EmbeddedChannel(new ByteToMessageDecoder() { @Override - protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) { + protected void decode(ChannelHandlerContext ctx, ByteBuf in) { int readable = in.readableBytes(); assertTrue(readable > 0); - out.add(in.readBytes(readable)); + ctx.fireChannelRead(in.readBytes(readable)); } }); byte[] bytes = new byte[1024]; @@ -267,20 +267,20 @@ public class ByteToMessageDecoderTest { private boolean decodeLast; @Override - protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) { + protected void decode(ChannelHandlerContext ctx, ByteBuf in) { int readable = in.readableBytes(); assertTrue(readable > 0); if (!decodeLast && readable == 1) { return; } - out.add(in.readBytes(decodeLast ? readable : readable - 1)); + ctx.fireChannelRead(in.readBytes(decodeLast ? readable : readable - 1)); } @Override - protected void decodeLast(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { + protected void decodeLast(ChannelHandlerContext ctx, ByteBuf in) throws Exception { assertFalse(decodeLast); decodeLast = true; - super.decodeLast(ctx, in, out); + super.decodeLast(ctx, in); } }); byte[] bytes = new byte[1024]; @@ -307,8 +307,7 @@ public class ByteToMessageDecoderTest { public void testReadOnlyBuffer() { EmbeddedChannel channel = new EmbeddedChannel(new ByteToMessageDecoder() { @Override - protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) { - } + protected void decode(ChannelHandlerContext ctx, ByteBuf in) { } }); assertFalse(channel.writeInbound(Unpooled.buffer(8).writeByte(1).asReadOnly())); assertFalse(channel.writeInbound(Unpooled.wrappedBuffer(new byte[] { (byte) 2 }))); @@ -486,8 +485,8 @@ public class ByteToMessageDecoderTest { //read 4 byte then remove this decoder @Override - protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) { - out.add(in.readByte()); + protected void decode(ChannelHandlerContext ctx, ByteBuf in) { + ctx.fireChannelRead(in.readByte()); if (++count >= 4) { ctx.pipeline().remove(this); } diff --git a/codec/src/test/java/io/netty/handler/codec/DatagramPacketDecoderTest.java b/codec/src/test/java/io/netty/handler/codec/DatagramPacketDecoderTest.java index 25edd89be2..53c72c1951 100644 --- a/codec/src/test/java/io/netty/handler/codec/DatagramPacketDecoderTest.java +++ b/codec/src/test/java/io/netty/handler/codec/DatagramPacketDecoderTest.java @@ -84,7 +84,7 @@ public class DatagramPacketDecoderTest { } @Override - protected void decode(ChannelHandlerContext ctx, ByteBuf msg, List out) throws Exception { + protected void decode(ChannelHandlerContext ctx, ByteBuf msg) throws Exception { // NOOP } diff --git a/codec/src/test/java/io/netty/handler/codec/ReplayingDecoderTest.java b/codec/src/test/java/io/netty/handler/codec/ReplayingDecoderTest.java index 8adac1e13c..dfbba2f948 100644 --- a/codec/src/test/java/io/netty/handler/codec/ReplayingDecoderTest.java +++ b/codec/src/test/java/io/netty/handler/codec/ReplayingDecoderTest.java @@ -23,7 +23,6 @@ import io.netty.channel.embedded.EmbeddedChannel; import io.netty.channel.socket.ChannelInputShutdownEvent; import org.junit.Test; -import java.util.List; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingDeque; import java.util.concurrent.ThreadLocalRandom; @@ -67,10 +66,10 @@ public class ReplayingDecoderTest { } @Override - protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) { + protected void decode(ChannelHandlerContext ctx, ByteBuf in) { ByteBuf msg = in.readBytes(in.bytesBefore((byte) '\n')); - out.add(msg); in.skipBytes(1); + ctx.fireChannelRead(msg); } } @@ -141,7 +140,7 @@ public class ReplayingDecoderTest { private boolean removed; @Override - protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { + protected void decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception { assertFalse(removed); in.readByte(); ctx.pipeline().remove(this); @@ -163,7 +162,7 @@ public class ReplayingDecoderTest { private boolean removed; @Override - protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { + protected void decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception { assertFalse(removed); ctx.pipeline().remove(this); @@ -189,7 +188,7 @@ public class ReplayingDecoderTest { private boolean removed; @Override - protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { + protected void decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception { assertFalse(removed); in.readByte(); ctx.pipeline().remove(this); @@ -214,17 +213,17 @@ public class ReplayingDecoderTest { EmbeddedChannel channel = new EmbeddedChannel(new ReplayingDecoder() { @Override - protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { + protected void decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception { int readable = in.readableBytes(); assertTrue(readable > 0); in.skipBytes(readable); - out.add("data"); + ctx.fireChannelRead("data"); } @Override - protected void decodeLast(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { + protected void decodeLast(ChannelHandlerContext ctx, ByteBuf in) throws Exception { assertFalse(in.isReadable()); - out.add("data"); + ctx.fireChannelRead("data"); } }, new ChannelHandler() { @Override @@ -261,7 +260,7 @@ public class ReplayingDecoderTest { private boolean decoded; @Override - protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { + protected void decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception { if (!(in instanceof ReplayingDecoderByteBuf)) { error.set(new AssertionError("in must be of type " + ReplayingDecoderByteBuf.class + " but was " + in.getClass())); @@ -292,7 +291,7 @@ public class ReplayingDecoderTest { public void handlerRemovedWillNotReleaseBufferIfDecodeInProgress() { EmbeddedChannel channel = new EmbeddedChannel(new ReplayingDecoder() { @Override - protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { + protected void decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception { ctx.pipeline().remove(this); assertTrue(in.refCnt() != 0); } diff --git a/example/src/main/java/io/netty/example/factorial/BigIntegerDecoder.java b/example/src/main/java/io/netty/example/factorial/BigIntegerDecoder.java index 4d564725cc..8ace0527d8 100644 --- a/example/src/main/java/io/netty/example/factorial/BigIntegerDecoder.java +++ b/example/src/main/java/io/netty/example/factorial/BigIntegerDecoder.java @@ -21,7 +21,6 @@ import io.netty.handler.codec.ByteToMessageDecoder; import io.netty.handler.codec.CorruptedFrameException; import java.math.BigInteger; -import java.util.List; /** * Decodes the binary representation of a {@link BigInteger} prepended @@ -32,7 +31,7 @@ import java.util.List; public class BigIntegerDecoder extends ByteToMessageDecoder { @Override - protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) { + protected void decode(ChannelHandlerContext ctx, ByteBuf in) { // Wait until the length prefix is available. if (in.readableBytes() < 5) { return; @@ -58,6 +57,6 @@ public class BigIntegerDecoder extends ByteToMessageDecoder { byte[] decoded = new byte[dataLength]; in.readBytes(decoded); - out.add(new BigInteger(decoded)); + ctx.fireChannelRead(new BigInteger(decoded)); } } diff --git a/example/src/main/java/io/netty/example/portunification/PortUnificationServerHandler.java b/example/src/main/java/io/netty/example/portunification/PortUnificationServerHandler.java index dae32b0356..5e060675ea 100644 --- a/example/src/main/java/io/netty/example/portunification/PortUnificationServerHandler.java +++ b/example/src/main/java/io/netty/example/portunification/PortUnificationServerHandler.java @@ -31,8 +31,6 @@ import io.netty.handler.codec.http.HttpResponseEncoder; import io.netty.handler.ssl.SslContext; import io.netty.handler.ssl.SslHandler; -import java.util.List; - /** * Manipulates the current pipeline dynamically to switch protocols or enable * SSL or GZIP. @@ -54,7 +52,7 @@ public class PortUnificationServerHandler extends ByteToMessageDecoder { } @Override - protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { + protected void decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception { // Will use the first five bytes to detect a protocol. if (in.readableBytes() < 5) { return; diff --git a/handler/src/main/java/io/netty/handler/ssl/AbstractSniHandler.java b/handler/src/main/java/io/netty/handler/ssl/AbstractSniHandler.java index b06389ce38..9e22252c1e 100644 --- a/handler/src/main/java/io/netty/handler/ssl/AbstractSniHandler.java +++ b/handler/src/main/java/io/netty/handler/ssl/AbstractSniHandler.java @@ -28,7 +28,6 @@ import io.netty.util.internal.logging.InternalLogger; import io.netty.util.internal.logging.InternalLoggerFactory; import java.net.SocketAddress; -import java.util.List; import java.util.Locale; /** @@ -49,7 +48,7 @@ public abstract class AbstractSniHandler extends ByteToMessageDecoder { private ByteBuf handshakeBuffer; @Override - protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { + protected void decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception { if (!suppressRead && !handshakeFailed) { try { int readerIndex = in.readerIndex(); diff --git a/handler/src/main/java/io/netty/handler/ssl/OptionalSslHandler.java b/handler/src/main/java/io/netty/handler/ssl/OptionalSslHandler.java index 32d1f1bddd..093cce543e 100644 --- a/handler/src/main/java/io/netty/handler/ssl/OptionalSslHandler.java +++ b/handler/src/main/java/io/netty/handler/ssl/OptionalSslHandler.java @@ -26,7 +26,6 @@ import io.netty.util.ReferenceCountUtil; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLParameters; -import java.util.List; /** * {@link OptionalSslHandler} is a utility decoder to support both SSL and non-SSL handlers @@ -41,7 +40,7 @@ public class OptionalSslHandler extends ByteToMessageDecoder { } @Override - protected void decode(ChannelHandlerContext context, ByteBuf in, List out) throws Exception { + protected void decode(ChannelHandlerContext context, ByteBuf in) throws Exception { if (in.readableBytes() < SslUtils.SSL_RECORD_HEADER_LENGTH) { return; } diff --git a/handler/src/main/java/io/netty/handler/ssl/SslHandler.java b/handler/src/main/java/io/netty/handler/ssl/SslHandler.java index f1fd5d0505..528c65f055 100644 --- a/handler/src/main/java/io/netty/handler/ssl/SslHandler.java +++ b/handler/src/main/java/io/netty/handler/ssl/SslHandler.java @@ -55,7 +55,6 @@ import java.nio.ByteBuffer; import java.nio.channels.ClosedChannelException; import java.nio.channels.DatagramChannel; import java.nio.channels.SocketChannel; -import java.util.List; import java.util.concurrent.Executor; import java.util.concurrent.RejectedExecutionException; import java.util.concurrent.ScheduledFuture; @@ -1260,7 +1259,7 @@ public class SslHandler extends ByteToMessageDecoder { } @Override - protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws SSLException { + protected void decode(ChannelHandlerContext ctx, ByteBuf in) throws SSLException { if (processTask) { return; } @@ -1868,7 +1867,7 @@ public class SslHandler extends ByteToMessageDecoder { } @Override - public void handlerAdded(final ChannelHandlerContext ctx) throws Exception { + public void handlerAdded0(final ChannelHandlerContext ctx) throws Exception { this.ctx = ctx; pendingUnencryptedWrites = new SslHandlerCoalescingBufferQueue(ctx.channel(), 16); diff --git a/handler/src/test/java/io/netty/handler/flow/FlowControlHandlerTest.java b/handler/src/test/java/io/netty/handler/flow/FlowControlHandlerTest.java index ce901c546e..ee90ea3a3d 100644 --- a/handler/src/test/java/io/netty/handler/flow/FlowControlHandlerTest.java +++ b/handler/src/test/java/io/netty/handler/flow/FlowControlHandlerTest.java @@ -41,7 +41,6 @@ import org.junit.BeforeClass; import org.junit.Test; import java.net.SocketAddress; -import java.util.List; import java.util.Queue; import java.util.concurrent.CountDownLatch; import java.util.concurrent.Exchanger; @@ -484,11 +483,11 @@ public class FlowControlHandlerTest { */ private static final class OneByteToThreeStringsDecoder extends ByteToMessageDecoder { @Override - protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) { + protected void decode(ChannelHandlerContext ctx, ByteBuf in) { for (int i = 0; i < in.readableBytes(); i++) { - out.add("1"); - out.add("2"); - out.add("3"); + ctx.fireChannelRead("1"); + ctx.fireChannelRead("2"); + ctx.fireChannelRead("3"); } in.readerIndex(in.readableBytes()); } diff --git a/handler/src/test/java/io/netty/handler/ssl/OptionalSslHandlerTest.java b/handler/src/test/java/io/netty/handler/ssl/OptionalSslHandlerTest.java index 8705cf2e9c..f1a58150e5 100644 --- a/handler/src/test/java/io/netty/handler/ssl/OptionalSslHandlerTest.java +++ b/handler/src/test/java/io/netty/handler/ssl/OptionalSslHandlerTest.java @@ -54,7 +54,7 @@ public class OptionalSslHandlerTest { OptionalSslHandler handler = new OptionalSslHandler(sslContext); final ByteBuf payload = Unpooled.copiedBuffer("plaintext".getBytes()); try { - handler.decode(context, payload, null); + handler.decode(context, payload); verify(pipeline).remove(handler); } finally { payload.release(); @@ -77,7 +77,7 @@ public class OptionalSslHandlerTest { }; final ByteBuf payload = Unpooled.copiedBuffer("plaintext".getBytes()); try { - handler.decode(context, payload, null); + handler.decode(context, payload); verify(pipeline).replace(handler, HANDLER_NAME, nonSslHandler); } finally { payload.release(); @@ -100,7 +100,7 @@ public class OptionalSslHandlerTest { }; final ByteBuf payload = Unpooled.wrappedBuffer(new byte[] { 22, 3, 1, 0, 5 }); try { - handler.decode(context, payload, null); + handler.decode(context, payload); verify(pipeline).replace(handler, SSL_HANDLER_NAME, sslHandler); } finally { payload.release(); @@ -112,7 +112,7 @@ public class OptionalSslHandlerTest { OptionalSslHandler handler = new OptionalSslHandler(sslContext); final ByteBuf payload = Unpooled.wrappedBuffer(new byte[] { 22, 3 }); try { - handler.decode(context, payload, null); + handler.decode(context, payload); verifyZeroInteractions(pipeline); } finally { payload.release(); diff --git a/handler/src/test/java/io/netty/handler/ssl/SslHandlerTest.java b/handler/src/test/java/io/netty/handler/ssl/SslHandlerTest.java index bc5d4fc3a9..be8009749b 100644 --- a/handler/src/test/java/io/netty/handler/ssl/SslHandlerTest.java +++ b/handler/src/test/java/io/netty/handler/ssl/SslHandlerTest.java @@ -165,11 +165,11 @@ public class SslHandlerTest { } }, new SslHandler(engine) { @Override - public void handlerAdded(ChannelHandlerContext ctx) throws Exception { + public void handlerAdded0(ChannelHandlerContext ctx) throws Exception { // We want to override what Channel.isActive() will return as otherwise it will // return true and so trigger an handshake. inActive.set(true); - super.handlerAdded(ctx); + super.handlerAdded0(ctx); inActive.set(false); } }, new ChannelHandler() { diff --git a/transport-sctp/src/main/java/io/netty/handler/codec/sctp/SctpInboundByteStreamHandler.java b/transport-sctp/src/main/java/io/netty/handler/codec/sctp/SctpInboundByteStreamHandler.java index 7a9a618d91..cb7eab75ad 100644 --- a/transport-sctp/src/main/java/io/netty/handler/codec/sctp/SctpInboundByteStreamHandler.java +++ b/transport-sctp/src/main/java/io/netty/handler/codec/sctp/SctpInboundByteStreamHandler.java @@ -22,8 +22,6 @@ import io.netty.channel.sctp.SctpMessage; import io.netty.handler.codec.CodecException; import io.netty.handler.codec.MessageToMessageDecoder; -import java.util.List; - /** * A ChannelHandler which receives {@link SctpMessage}s which belong to a application protocol form a specific * SCTP Stream and decode it as {@link ByteBuf}. @@ -54,11 +52,11 @@ public class SctpInboundByteStreamHandler extends MessageToMessageDecoder out) throws Exception { + protected void decode(ChannelHandlerContext ctx, SctpMessage msg) throws Exception { if (!msg.isComplete()) { throw new CodecException(String.format("Received SctpMessage is not complete, please add %s in the " + "pipeline before this handler", SctpMessageCompletionHandler.class.getSimpleName())); } - out.add(msg.content().retain()); + ctx.fireChannelRead(msg.content().retain()); } } diff --git a/transport-sctp/src/main/java/io/netty/handler/codec/sctp/SctpMessageCompletionHandler.java b/transport-sctp/src/main/java/io/netty/handler/codec/sctp/SctpMessageCompletionHandler.java index 567bb2cff8..01a88ebabd 100644 --- a/transport-sctp/src/main/java/io/netty/handler/codec/sctp/SctpMessageCompletionHandler.java +++ b/transport-sctp/src/main/java/io/netty/handler/codec/sctp/SctpMessageCompletionHandler.java @@ -24,7 +24,6 @@ import io.netty.channel.sctp.SctpMessage; import io.netty.handler.codec.MessageToMessageDecoder; import java.util.HashMap; -import java.util.List; import java.util.Map; /** @@ -36,7 +35,7 @@ public class SctpMessageCompletionHandler extends MessageToMessageDecoder fragments = new HashMap<>(); @Override - protected void decode(ChannelHandlerContext ctx, SctpMessage msg, List out) throws Exception { + protected void decode(ChannelHandlerContext ctx, SctpMessage msg) throws Exception { final ByteBuf byteBuf = msg.content(); final int protocolIdentifier = msg.protocolIdentifier(); final int streamIdentifier = msg.streamIdentifier(); @@ -50,23 +49,22 @@ public class SctpMessageCompletionHandler extends MessageToMessageDecoder