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