Remove the intermediate List from ByteToMessageDecoder (and sub-class… (#8626)

Motivation:

ByteToMessageDecoder requires using an intermediate List to put results into. This intermediate list adds overhead (memory/CPU) which grows as the number of objects increases. This overhead can be avoided by directly propagating events through the ChannelPipeline via ctx.fireChannelRead(...). This also makes the semantics more clear and allows us to keep track if we need to call ctx.read() in all cases.

Modifications:

- Remove List from the method signature of ByteToMessageDecoder.decode(...) and decodeLast(...)
- Adjust all sub-classes
- Adjust unit tests
- Fix javadocs.

Result:

Adjust ByteToMessageDecoder as noted in https://github.com/netty/netty/issues/8525.
This commit is contained in:
Norman Maurer 2019-12-16 21:00:32 +01:00 committed by GitHub
parent 33d576dbed
commit 0e4c073bcf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
103 changed files with 1483 additions and 926 deletions

View File

@ -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<DatagramPac
}
@Override
protected void decode(ChannelHandlerContext ctx, DatagramPacket packet, List<Object> 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<DatagramPac
decodeRecords(query, DnsSection.AUTHORITY, buf, authorityRecordCount);
decodeRecords(query, DnsSection.ADDITIONAL, buf, additionalRecordCount);
out.add(query);
success = true;
DnsQuery q = query;
query = null;
ctx.fireChannelRead(q);
} finally {
if (!success) {
if (query != null) {
query.release();
}
}

View File

@ -22,7 +22,6 @@ import io.netty.handler.codec.MessageToMessageDecoder;
import io.netty.util.internal.UnstableApi;
import java.net.InetSocketAddress;
import java.util.List;
/**
* Decodes a {@link DatagramPacket} into a {@link DatagramDnsResponse}.
@ -54,8 +53,9 @@ public class DatagramDnsResponseDecoder extends MessageToMessageDecoder<Datagram
}
@Override
protected void decode(ChannelHandlerContext ctx, DatagramPacket packet, List<Object> 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 {

View File

@ -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;
}

View File

@ -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<Object> 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);

View File

@ -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 <T> Attribute<T> attr(AttributeKey<T> key) {
return ctx.attr(key);
}
@Deprecated
public <T> boolean hasAttr(AttributeKey<T> 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();
}
}

View File

@ -177,6 +177,9 @@ public final class HttpClientCodec extends CombinedChannelDuplexHandler<HttpResp
}
private final class Decoder extends HttpResponseDecoder {
private ChannelHandlerContext context;
Decoder(int maxInitialLineLength, int maxHeaderSize, boolean validateHeaders) {
super(maxInitialLineLength, maxHeaderSize, validateHeaders);
}
@ -187,8 +190,24 @@ public final class HttpClientCodec extends CombinedChannelDuplexHandler<HttpResp
}
@Override
protected void decode(
ChannelHandlerContext ctx, ByteBuf buffer, List<Object> 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<HttpResp
// https://github.com/netty/netty/issues/1159
return;
}
out.add(buffer.readBytes(readable));
ctx.fireChannelRead(buffer.readBytes(readable));
} else {
int oldSize = out.size();
super.decode(ctx, buffer, out);
if (failOnMissingResponse) {
int size = out.size();
for (int i = oldSize; i < size; i++) {
decrement(out.get(i));
}
}
super.decode(context, buffer);
}
}

View File

@ -21,7 +21,6 @@ import io.netty.util.AsciiString;
import java.net.SocketAddress;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import static io.netty.handler.codec.http.HttpResponseStatus.SWITCHING_PROTOCOLS;
@ -188,7 +187,7 @@ public class HttpClientUpgradeHandler extends HttpObjectAggregator {
}
@Override
protected void decode(ChannelHandlerContext ctx, HttpObject msg, List<Object> 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);

View File

@ -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<HttpObj
private boolean needRead = true;
@Override
protected void decode(ChannelHandlerContext ctx, HttpObject msg, List<Object> 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<Object> 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<HttpObj
}
}
private void decode(ByteBuf in, List<Object> 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<Object> out) {
private void finishDecode(ChannelHandlerContext ctx) {
if (decoder.finish()) {
fetchDecoderOutput(out);
fetchDecoderOutput(ctx);
}
decoder = null;
}
private void fetchDecoderOutput(List<Object> out) {
private void fetchDecoderOutput(ChannelHandlerContext ctx) {
for (;;) {
ByteBuf buf = decoder.readInbound();
if (buf == null) {
@ -272,7 +265,12 @@ public abstract class HttpContentDecoder extends MessageToMessageDecoder<HttpObj
buf.release();
continue;
}
out.add(new DefaultHttpContent(buf));
ctx.fireChannelRead(new DefaultHttpContent(buf));
}
}
private void fireChannelRead(ChannelHandlerContext ctx, Object msg) {
needRead = false;
ctx.fireChannelRead(msg);
}
}

View File

@ -76,7 +76,7 @@ public abstract class HttpContentEncoder extends MessageToMessageCodec<HttpReque
}
@Override
protected void decode(ChannelHandlerContext ctx, HttpRequest msg, List<Object> out) throws Exception {
protected void decode(ChannelHandlerContext ctx, HttpRequest msg) throws Exception {
CharSequence acceptEncoding;
List<String> acceptEncodingHeaders = msg.headers().getAll(ACCEPT_ENCODING);
switch (acceptEncodingHeaders.size()) {
@ -100,7 +100,7 @@ public abstract class HttpContentEncoder extends MessageToMessageCodec<HttpReque
}
acceptEncodingQueue.add(acceptEncoding);
out.add(ReferenceCountUtil.retain(msg));
ctx.fireChannelRead(ReferenceCountUtil.retain(msg));
}
@Override

View File

@ -179,7 +179,7 @@ public abstract class HttpObjectDecoder extends ByteToMessageDecoder {
}
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf buffer, List<Object> 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<Object> 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();
}

View File

@ -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<HttpRequ
}
private final class HttpServerRequestDecoder extends HttpRequestDecoder {
private ChannelHandlerContext context;
HttpServerRequestDecoder(int maxInitialLineLength, int maxHeaderSize) {
super(maxInitialLineLength, maxHeaderSize);
}
@ -96,16 +98,23 @@ public final class HttpServerCodec extends CombinedChannelDuplexHandler<HttpRequ
}
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf buffer, List<Object> 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;
}
}
};
}
}

View File

@ -206,45 +206,42 @@ public class HttpServerUpgradeHandler extends HttpObjectAggregator {
}
@Override
protected void decode(ChannelHandlerContext ctx, HttpObject msg, List<Object> 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.
}
/**

View File

@ -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<Void> implements W
}
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> 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<Void> implements W
}
if (frame != null) {
out.add(frame);
ctx.fireChannelRead(frame);
}
}

View File

@ -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<Object> 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: "

View File

@ -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<Object> 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

View File

@ -44,7 +44,7 @@ abstract class WebSocketProtocolHandler extends MessageToMessageDecoder<WebSocke
}
@Override
protected void decode(ChannelHandlerContext ctx, WebSocketFrame frame, List<Object> 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<WebSocke
return;
}
out.add(frame.retain());
ctx.fireChannelRead(frame.retain());
}
private static void readIfNeeded(ChannelHandlerContext ctx) {

View File

@ -29,7 +29,6 @@ import io.netty.handler.codec.http.HttpHeaders;
import io.netty.handler.codec.http.HttpResponseStatus;
import io.netty.util.AttributeKey;
import java.util.List;
import java.util.Objects;
import static io.netty.handler.codec.http.HttpVersion.*;
@ -235,7 +234,7 @@ public class WebSocketServerProtocolHandler extends WebSocketProtocolHandler {
}
@Override
protected void decode(ChannelHandlerContext ctx, WebSocketFrame frame, List<Object> 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

View File

@ -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<Object> 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

View File

@ -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<Object> 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;

View File

@ -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();
}

View File

@ -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<Object> 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);
}
}

View File

@ -97,8 +97,7 @@ public final class WebSocketExtensionTestUtil {
static class DummyDecoder extends WebSocketExtensionDecoder {
@Override
protected void decode(ChannelHandlerContext ctx, WebSocketFrame msg,
List<Object> 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<Object> out) throws Exception {
protected void decode(ChannelHandlerContext ctx, WebSocketFrame msg) throws Exception {
// unused
}
}

View File

@ -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<Object> out) throws Exception {
protected void decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception {
int prefaceLength = CONNECTION_PREFACE.readableBytes();
int bytesRead = Math.min(in.readableBytes(), prefaceLength);

View File

@ -59,8 +59,8 @@ public class DecoratingHttp2ConnectionDecoder implements Http2ConnectionDecoder
}
@Override
public void decodeFrame(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Http2Exception {
delegate.decodeFrame(ctx, in, out);
public void decodeFrame(ChannelHandlerContext ctx, ByteBuf in) throws Http2Exception {
delegate.decodeFrame(ctx, in);
}
@Override

View File

@ -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<Object> out) throws Http2Exception {
public void decodeFrame(ChannelHandlerContext ctx, ByteBuf in) throws Http2Exception {
frameReader.readFrame(ctx, in, internalFrameListener);
}

View File

@ -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<Object> out) throws Http2Exception;
void decodeFrame(ChannelHandlerContext ctx, ByteBuf in) throws Http2Exception;
/**
* Gets the local settings for this endpoint of the HTTP/2 connection.

View File

@ -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<Object> 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<Object> 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<Object> 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<Object> out) throws Exception {
byteDecoder.decode(ctx, in, out);
protected void decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception {
byteDecoder.decode(ctx, in);
}
@Override

View File

@ -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).

View File

@ -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

View File

@ -82,7 +82,7 @@ public class Http2StreamFrameToHttpObjectCodec extends MessageToMessageCodec<Htt
}
@Override
protected void decode(ChannelHandlerContext ctx, Http2StreamFrame frame, List<Object> 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<Htt
// but we need to decode it as a FullHttpResponse to play nice with HttpObjectAggregator.
if (null != status && HttpResponseStatus.CONTINUE.codeAsText().contentEquals(status)) {
final FullHttpMessage fullMsg = newFullMessage(id, headers, ctx.alloc());
out.add(fullMsg);
ctx.fireChannelRead(fullMsg);
return;
}
@ -104,24 +104,24 @@ public class Http2StreamFrameToHttpObjectCodec extends MessageToMessageCodec<Htt
LastHttpContent last = new DefaultLastHttpContent(Unpooled.EMPTY_BUFFER, validateHeaders);
HttpConversionUtil.addHttp2ToHttpHeaders(id, headers, last.trailingHeaders(),
HttpVersion.HTTP_1_1, true, true);
out.add(last);
ctx.fireChannelRead(last);
} else {
FullHttpMessage full = newFullMessage(id, headers, ctx.alloc());
out.add(full);
ctx.fireChannelRead(full);
}
} else {
HttpMessage req = newMessage(id, headers);
if (!HttpUtil.isContentLengthSet(req)) {
req.headers().add(HttpHeaderNames.TRANSFER_ENCODING, HttpHeaderValues.CHUNKED);
}
out.add(req);
ctx.fireChannelRead(req);
}
} else if (frame instanceof Http2DataFrame) {
Http2DataFrame dataFrame = (Http2DataFrame) frame;
if (dataFrame.isEndStream()) {
out.add(new DefaultLastHttpContent(dataFrame.content().retain(), validateHeaders));
ctx.fireChannelRead(new DefaultLastHttpContent(dataFrame.content().retain(), validateHeaders));
} else {
out.add(new DefaultHttpContent(dataFrame.content().retain()));
ctx.fireChannelRead(new DefaultHttpContent(dataFrame.content().retain()));
}
}
}

View File

@ -821,7 +821,7 @@ public class DefaultHttp2ConnectionDecoderTest {
private Http2FrameListener decode() throws Exception {
ArgumentCaptor<Http2FrameListener> 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();
}

View File

@ -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<ByteBuf> 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<ByteBuf> 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<ByteBuf> 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")

View File

@ -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<ByteBuf> 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);
}
}

View File

@ -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<C extends Http2FrameCodec> {
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<C extends Http2FrameCodec> {
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<C extends Http2FrameCodec> {
});
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<C extends Http2FrameCodec> {
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<ChannelFuture>() {
@ -453,8 +448,8 @@ public abstract class Http2MultiplexTest<C extends Http2FrameCodec> {
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<C extends Http2FrameCodec> {
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<C extends Http2FrameCodec> {
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<C extends Http2FrameCodec> {
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<C extends Http2FrameCodec> {
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<C extends Http2FrameCodec> {
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);

View File

@ -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<Object> 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,

View File

@ -165,8 +165,8 @@ public class StreamBufferingEncoderTest {
writeVerifyWriteHeaders(times(2), 3);
// Contiguous data writes are coalesced
ArgumentCaptor<ByteBuf> 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());
}

View File

@ -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}.
* <p/>
@ -67,7 +65,7 @@ public abstract class AbstractBinaryMemcacheDecoder<M extends BinaryMemcacheMess
}
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> 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<M extends BinaryMemcacheMess
state = State.READ_EXTRAS;
} catch (Exception e) {
resetDecoder();
out.add(invalidMessage(e));
ctx.fireChannelRead(invalidMessage(e));
return;
}
case READ_EXTRAS: try {
@ -95,7 +93,7 @@ public abstract class AbstractBinaryMemcacheDecoder<M extends BinaryMemcacheMess
state = State.READ_KEY;
} catch (Exception e) {
resetDecoder();
out.add(invalidMessage(e));
ctx.fireChannelRead(invalidMessage(e));
return;
}
case READ_KEY: try {
@ -107,11 +105,11 @@ public abstract class AbstractBinaryMemcacheDecoder<M extends BinaryMemcacheMess
currentMessage.setKey(in.readRetainedSlice(keyLength));
}
out.add(currentMessage.retain());
ctx.fireChannelRead(currentMessage.retain());
state = State.READ_CONTENT;
} catch (Exception e) {
resetDecoder();
out.add(invalidMessage(e));
ctx.fireChannelRead(invalidMessage(e));
return;
}
case READ_CONTENT: try {
@ -142,12 +140,12 @@ public abstract class AbstractBinaryMemcacheDecoder<M extends BinaryMemcacheMess
chunk = new DefaultMemcacheContent(chunkBuffer);
}
out.add(chunk);
ctx.fireChannelRead(chunk);
if (alreadyReadChunkSize < valueLength) {
return;
}
} else {
out.add(LastMemcacheContent.EMPTY_LAST_CONTENT);
ctx.fireChannelRead(LastMemcacheContent.EMPTY_LAST_CONTENT);
}
resetDecoder();
@ -155,7 +153,7 @@ public abstract class AbstractBinaryMemcacheDecoder<M extends BinaryMemcacheMess
return;
} catch (Exception e) {
resetDecoder();
out.add(invalidChunk(e));
ctx.fireChannelRead(invalidChunk(e));
return;
}
case BAD_MESSAGE:

View File

@ -16,12 +16,23 @@
package io.netty.handler.codec.memcache.binary;
import io.netty.buffer.ByteBuf;
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.channel.CombinedChannelDuplexHandler;
import io.netty.handler.codec.PrematureChannelClosureException;
import io.netty.handler.codec.memcache.LastMemcacheContent;
import io.netty.util.Attribute;
import io.netty.util.AttributeKey;
import io.netty.util.concurrent.EventExecutor;
import io.netty.util.internal.UnstableApi;
import java.net.SocketAddress;
import java.util.List;
import java.util.concurrent.atomic.AtomicLong;
@ -84,24 +95,212 @@ public final class BinaryMemcacheClientCodec extends
private final class Decoder extends BinaryMemcacheResponseDecoder {
private ChannelHandlerContext context;
Decoder(int chunkSize) {
super(chunkSize);
}
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> 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 <T> Attribute<T> attr(AttributeKey<T> key) {
return ctx.attr(key);
}
@Deprecated
public <T> boolean hasAttr(AttributeKey<T> 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

View File

@ -69,7 +69,7 @@ public final class MqttDecoder extends ReplayingDecoder<DecoderState> {
}
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf buffer, List<Object> 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<DecoderState> {
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<DecoderState> {
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<DecoderState> {
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;
}

View File

@ -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<Object> out = new LinkedList<>();
mqttDecoder.decode(ctx, byteBuf, out);
ArgumentCaptor<MqttConnectMessage> 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<Object> out = new LinkedList<>();
mqttDecoder.decode(ctx, byteBuf, out);
ArgumentCaptor<MqttConnectMessage> 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<Object> out = new LinkedList<>();
mqttDecoder.decode(ctx, byteBuf, out);
assertEquals("Expected one object but got " + out.size(), 1, out.size());
ArgumentCaptor<MqttMessage> 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<Object> out = new LinkedList<>();
mqttDecoder.decode(ctx, byteBuf, out);
ArgumentCaptor<MqttConnAckMessage> 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<Object> out = new LinkedList<>();
mqttDecoder.decode(ctx, byteBuf, out);
ArgumentCaptor<MqttPublishMessage> 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<Object> out = new LinkedList<>();
mqttDecoder.decode(ctx, byteBuf, out);
ArgumentCaptor<MqttSubscribeMessage> 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<Object> out = new LinkedList<>();
mqttDecoder.decode(ctx, byteBuf, out);
ArgumentCaptor<MqttSubAckMessage> 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<Object> out = new LinkedList<>();
mqttDecoder.decode(ctx, byteBuf, out);
ArgumentCaptor<MqttSubAckMessage> 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<Object> out = new LinkedList<>();
mqttDecoder.decode(ctx, byteBuf, out);
ArgumentCaptor<MqttUnsubscribeMessage> 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<Object> out = new LinkedList<>();
mqttDecoder.decode(ctx, byteBuf, out);
assertEquals("Expected one object but got " + out.size(), 1, out.size());
ArgumentCaptor<MqttMessage> 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<Object> out = new LinkedList<>();
mqttDecoderLimitedMessageSize.decode(ctx, byteBuf, out);
ArgumentCaptor<MqttMessage> 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<Object> out = new LinkedList<>();
mqttDecoderLimitedMessageSize.decode(ctx, byteBuf, out);
ArgumentCaptor<MqttMessage> 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<Object> out = new LinkedList<>();
mqttDecoderLimitedMessageSize.decode(ctx, byteBuf, out);
ArgumentCaptor<MqttMessage> 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<Object> out = new LinkedList<>();
mqttDecoderLimitedMessageSize.decode(ctx, byteBuf, out);
ArgumentCaptor<MqttMessage> 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<Object> out = new LinkedList<>();
mqttDecoderLimitedMessageSize.decode(ctx, byteBuf, out);
ArgumentCaptor<MqttMessage> 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<Object> out = new LinkedList<>();
mqttDecoderLimitedMessageSize.decode(ctx, byteBuf, out);
ArgumentCaptor<MqttMessage> 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<Object> out = new LinkedList<>();
mqttDecoderLimitedMessageSize.decode(ctx, byteBuf, out);
ArgumentCaptor<MqttMessage> 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<Object> out = new LinkedList<>();
mqttDecoder.decode(ctx, byteBuf, out);
ArgumentCaptor<MqttMessage> 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<Object> out = new LinkedList<>();
mqttDecoder.decode(ctx, byteBuf, out);
ArgumentCaptor<MqttMessage> 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(),

View File

@ -36,7 +36,7 @@ public final class RedisArrayAggregator extends MessageToMessageDecoder<RedisMes
private final Deque<AggregateState> depths = new ArrayDeque<>(4);
@Override
protected void decode(ChannelHandlerContext ctx, RedisMessage msg, List<Object> 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 MessageToMessageDecoder<RedisMes
}
}
out.add(msg);
ctx.fireChannelRead(msg);
}
private RedisMessage decodeRedisArrayHeader(ArrayHeaderRedisMessage header) {

View File

@ -22,8 +22,6 @@ import io.netty.util.ByteProcessor;
import io.netty.util.CharsetUtil;
import io.netty.util.internal.UnstableApi;
import java.util.List;
/**
* Decodes the Redis protocol into {@link RedisMessage} objects following
* <a href="http://redis.io/topics/protocol">RESP (REdis Serialization Protocol)</a>.
@ -95,7 +93,7 @@ public final class RedisDecoder extends ByteToMessageDecoder {
}
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> 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<Object> 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<Object> 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<Object> 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 <here> \r\n
private boolean decodeBulkStringEndOfLine(ByteBuf in, List<Object> 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 <here> {data...}\r\n
private boolean decodeBulkStringContent(ByteBuf in, List<Object> 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;
}

View File

@ -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;

View File

@ -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<State> {
}
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf byteBuf, List<Object> 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<State> {
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: {

View File

@ -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<State> {
}
@Override
protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf, List<Object> 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 {

View File

@ -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<State> {
}
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf byteBuf, List<Object> 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<State> {
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<State> {
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: {

View File

@ -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<State> {
}
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf byteBuf, List<Object> 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<State> {
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<State> {
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: {

View File

@ -35,11 +35,11 @@ public class SocksInitRequestDecoder extends ReplayingDecoder<State> {
}
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf byteBuf, List<Object> 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<State> {
} else {
authSchemes = Collections.emptyList();
}
out.add(new SocksInitRequest(authSchemes));
ctx.fireChannelRead(new SocksInitRequest(authSchemes));
break;
}
default: {

View File

@ -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<State> {
}
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf byteBuf, List<Object> 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: {

View File

@ -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<Object> out) throws Exception {
protected void decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception {
final int readerIndex = in.readerIndex();
if (in.writerIndex() == readerIndex) {
return;

View File

@ -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<State> {
}
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> 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<State> {
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<State> {
}
}
} catch (Exception e) {
fail(out, e);
fail(ctx, e);
}
}
private void fail(List<Object> 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);
}

View File

@ -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<State> {
}
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> 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<State> {
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<State> {
}
}
} catch (Exception e) {
fail(out, e);
fail(ctx, e);
}
}
private void fail(List<Object> 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<State> {
userId != null? userId : "");
m.setDecoderResult(DecoderResult.failure(cause));
out.add(m);
ctx.fireChannelRead(m);
checkpoint(State.FAILURE);
}

View File

@ -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<State> {
}
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> 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<State> {
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<State> {
}
}
} catch (Exception e) {
fail(out, e);
fail(ctx, e);
}
}
private void fail(List<Object> 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<State> {
Socks5Message m = new DefaultSocks5CommandRequest(
Socks5CommandType.CONNECT, Socks5AddressType.IPv4, "0.0.0.0", 1);
m.setDecoderResult(DecoderResult.failure(cause));
out.add(m);
ctx.fireChannelRead(m);
}
}

View File

@ -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<State> {
}
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> 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<State> {
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<State> {
}
}
} catch (Exception e) {
fail(out, e);
fail(ctx, e);
}
}
private void fail(List<Object> 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<State> {
Socks5Message m = new DefaultSocks5CommandResponse(
Socks5CommandStatus.FAILURE, Socks5AddressType.IPv4, null, 0);
m.setDecoderResult(DecoderResult.failure(cause));
out.add(m);
ctx.fireChannelRead(m);
}
}

View File

@ -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<State> {
}
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> 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<State> {
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<State> {
}
}
} catch (Exception e) {
fail(out, e);
fail(ctx, e);
}
}
private void fail(List<Object> 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<State> {
Socks5Message m = new DefaultSocks5InitialRequest(Socks5AuthMethod.NO_AUTH);
m.setDecoderResult(DecoderResult.failure(cause));
out.add(m);
ctx.fireChannelRead(m);
}
}

View File

@ -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<State> {
}
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> 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<State> {
}
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<State> {
}
}
} catch (Exception e) {
fail(out, e);
fail(ctx, e);
}
}
private void fail(List<Object> 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<State> {
Socks5Message m = new DefaultSocks5InitialResponse(Socks5AuthMethod.UNACCEPTED);
m.setDecoderResult(DecoderResult.failure(cause));
out.add(m);
ctx.fireChannelRead(m);
}
}

View File

@ -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<State> {
}
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> 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<State> {
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<State> {
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<State> {
}
}
} catch (Exception e) {
fail(out, e);
fail(ctx, e);
}
}
private void fail(List<Object> 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<State> {
Socks5Message m = new DefaultSocks5PasswordAuthRequest("", "");
m.setDecoderResult(DecoderResult.failure(cause));
out.add(m);
ctx.fireChannelRead(m);
}
}

View File

@ -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<State> {
}
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> 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<State> {
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<State> {
}
}
} catch (Exception e) {
fail(out, e);
fail(ctx, e);
}
}
private void fail(List<Object> 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<State> {
Socks5Message m = new DefaultSocks5PasswordAuthResponse(Socks5PasswordAuthStatus.FAILURE);
m.setDecoderResult(DecoderResult.failure(cause));
out.add(m);
ctx.fireChannelRead(m);
}
}

View File

@ -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<State> {
}
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> 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<State> {
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<State> {
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<State> {
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<State> {
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);
}
}

View File

@ -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 <a href="https://github.com/FasterXML/aalto-xml">Aalto XML parser</a>.
@ -42,7 +41,7 @@ public class XmlDecoder extends ByteToMessageDecoder {
private final AsyncByteArrayFeeder streamFeeder = streamReader.getInputFeeder();
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> 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;
}
}

View File

@ -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<I> extends ChannelHandlerAdapter {
private final ByteToMessageDecoder decoder = new ByteToMessageDecoder() {
@Override
public void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> 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<Object> 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<I> 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<Object> 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<Object> 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);
}
}

View File

@ -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}.
*
* <pre>
* public class SquareDecoder extends {@link ByteToMessageDecoder} {
* {@code @Override}
* public void decode({@link ChannelHandlerContext} ctx, {@link ByteBuf} in, List&lt;Object&gt; 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()));
* }
* }
* </pre>
@ -71,8 +80,9 @@ import static java.lang.Integer.MAX_VALUE;
* annotated with {@link @Sharable}.
* <p>
* Some methods such as {@link ByteBuf#readBytes(int)} will cause a memory leak if the returned buffer
* is not released or added to the <tt>out</tt> {@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<Object> 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<Object> 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<Object> 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<Object> 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<Object> 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<Object> 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 <T> Attribute<T> attr(AttributeKey<T> key) {
return ctx.attr(key);
}
@Override
@Deprecated
public <T> boolean hasAttr(AttributeKey<T> 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();
}
}
}

View File

@ -56,8 +56,8 @@ public class DatagramPacketDecoder extends MessageToMessageDecoder<DatagramPacke
}
@Override
protected void decode(ChannelHandlerContext ctx, DatagramPacket msg, List<Object> out) throws Exception {
decoder.decode(ctx, msg.content(), out);
protected void decode(ChannelHandlerContext ctx, DatagramPacket msg) throws Exception {
decoder.decode(ctx, msg.content());
}
@Override

View File

@ -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<Object> 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;

View File

@ -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<Object> 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;

View File

@ -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<Object> 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);
}

View File

@ -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.
* <p>
@ -80,10 +78,10 @@ public class LineBasedFrameDecoder extends ByteToMessageDecoder {
}
@Override
protected final void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> 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) {

View File

@ -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<I, S, C extends ByteBufHolder, O extends
}
@Override
protected void decode(final ChannelHandlerContext ctx, I msg, List<Object> 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<I, S, C extends ByteBufHolder, O extends
} else {
aggregated = beginAggregation(m, EMPTY_BUFFER);
}
finishAggregation0(aggregated);
out.add(aggregated);
finishAggregation(aggregated);
ctx.fireChannelRead(aggregated);
return;
}
@ -317,8 +314,9 @@ public abstract class MessageAggregator<I, S, C extends ByteBufHolder, O extends
finishAggregation0(currentMessage);
// All done
out.add(currentMessage);
O message = currentMessage;
currentMessage = null;
ctx.fireChannelRead(message);
}
} else {
throw new MessageAggregationException();

View File

@ -77,8 +77,8 @@ public abstract class MessageToMessageCodec<INBOUND_IN, OUTBOUND_IN> extends Cha
@Override
@SuppressWarnings("unchecked")
protected void decode(ChannelHandlerContext ctx, Object msg, List<Object> 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<INBOUND_IN, OUTBOUND_IN> 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<Object> out)
protected abstract void decode(ChannelHandlerContext ctx, INBOUND_IN msg)
throws Exception;
}

View File

@ -79,29 +79,22 @@ public abstract class MessageToMessageDecoder<I> 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<I> 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<Object> out) throws Exception;
protected abstract void decode(ChannelHandlerContext ctx, I msg) throws Exception;
}

View File

@ -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&lt;Object&gt; out) throws Exception {
* protected void decode({@link ChannelHandlerContext} ctx, {@link ByteBuf} buf) throws Exception {
*
* if (buf.readableBytes() &lt; 4) {
* return;
@ -54,7 +51,7 @@ import java.util.List;
* return;
* }
*
* out.add(buf.readBytes(length));
* ctx.fireChannelRead(buf.readBytes(length));
* }
* }
* </pre>
@ -108,7 +105,7 @@ import java.util.List;
* private final Queue&lt;Integer&gt; values = new LinkedList&lt;Integer&gt;();
*
* {@code @Override}
* public void decode(.., {@link ByteBuf} buf, List&lt;Object&gt; 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());
* }
* }</pre>
* The correct implementation looks like the following, and you can also
@ -128,7 +125,7 @@ import java.util.List;
* private final Queue&lt;Integer&gt; values = new LinkedList&lt;Integer&gt;();
*
* {@code @Override}
* public void decode(.., {@link ByteBuf} buf, List&lt;Object&gt; 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());
* }
* }</pre>
* </li>
@ -180,8 +177,7 @@ import java.util.List;
* }
*
* {@code @Override}
* protected void decode({@link ChannelHandlerContext} ctx,
* {@link ByteBuf} buf, List&lt;Object&gt; 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);
* <strong>checkpoint(MyDecoderState.READ_LENGTH);</strong>
* 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&lt;Object&gt; out) throws Exception {
* protected void decode({@link ChannelHandlerContext} ctx, {@link ByteBuf} buf) throws Exception {
* if (!readLength) {
* length = buf.readInt();
* <strong>readLength = true;</strong>
@ -221,7 +216,7 @@ import java.util.List;
* ByteBuf frame = buf.readBytes(length);
* <strong>readLength = false;</strong>
* <strong>checkpoint();</strong>
* out.add(frame);
* ctx.fireChannelRead(frame);
* }
* }
* }
@ -240,8 +235,7 @@ import java.util.List;
* public class FirstDecoder extends {@link ReplayingDecoder}&lt;{@link Void}&gt; {
*
* {@code @Override}
* protected void decode({@link ChannelHandlerContext} ctx,
* {@link ByteBuf} buf, List&lt;Object&gt; 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(<b>super.actualReadableBytes()</b>));
* ctx.fireChannelRead(firstMessage);
* ctx.fireChannelRead(buf.readBytes(<b>super.actualReadableBytes()</b>));
* } 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<S> extends ByteToMessageDecoder {
}
@Override
final void channelInputClosed(ChannelHandlerContext ctx, List<Object> 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<S> extends ByteToMessageDecoder {
}
@Override
protected void callDecode(ChannelHandlerContext ctx, ByteBuf in, List<Object> 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<S> 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 " +

View File

@ -60,7 +60,7 @@ public class Base64Decoder extends MessageToMessageDecoder<ByteBuf> {
}
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf msg, List<Object> 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));
}
}

View File

@ -51,8 +51,8 @@ import java.util.List;
*/
public class ByteArrayDecoder extends MessageToMessageDecoder<ByteBuf> {
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf msg, List<Object> 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));
}
}

View File

@ -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<Object> 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) {

View File

@ -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<Object> 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);

View File

@ -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<Object> 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();
}

View File

@ -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<Object> 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();
}

View File

@ -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<Object> 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) {

View File

@ -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<Object> 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;

View File

@ -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<Object> 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) {

View File

@ -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<Object> 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);

View File

@ -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<Void> {
}
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf buffer, List<Object> 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<Void> {
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<Void> {
}
@Override
protected void decodeLast(ChannelHandlerContext ctx, ByteBuf buffer, List<Object> 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<Void> {
}
}
decode(ctx, buffer, out);
decode(ctx, buffer);
}
@Override

View File

@ -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;
}

View File

@ -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
* <a href="https://github.com/google/protobuf">Google Protocol Buffers</a>
@ -103,7 +101,7 @@ public class ProtobufDecoder extends MessageToMessageDecoder<ByteBuf> {
}
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf msg, List<Object> 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<ByteBuf> {
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());
}
}

View File

@ -71,8 +71,7 @@ public class ProtobufDecoderNano extends MessageToMessageDecoder<ByteBuf> {
}
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf msg, List<Object> 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<ByteBuf> {
offset = 0;
}
MessageNano prototype = clazz.getConstructor().newInstance();
out.add(MessageNano.mergeFrom(prototype, array, offset, length));
ctx.fireChannelRead(MessageNano.mergeFrom(prototype, array, offset, length));
}
}

View File

@ -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<Object> 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));
}
}

View File

@ -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;
}

View File

@ -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<ByteBuf> {
}
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf msg, List<Object> out) throws Exception {
out.add(msg.toString(charset));
protected void decode(ChannelHandlerContext ctx, ByteBuf msg) throws Exception {
ctx.fireChannelRead(msg.toString(charset));
}
}

View File

@ -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.
* <p/>
@ -85,7 +83,7 @@ public class XmlFrameDecoder extends ByteToMessageDecoder {
}
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> 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);
}
}

View File

@ -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<Object> 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<Object> 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<Object> out) throws Exception { }
protected void decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception { }
}
}

View File

@ -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<Object> 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<Object> 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<Object> 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<Object> 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<Object> 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<Object> 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<Object> 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<Object> 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<Object> 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<Object> 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<Object> 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<Object> out) {
out.add(in.readByte());
protected void decode(ChannelHandlerContext ctx, ByteBuf in) {
ctx.fireChannelRead(in.readByte());
if (++count >= 4) {
ctx.pipeline().remove(this);
}

View File

@ -84,7 +84,7 @@ public class DatagramPacketDecoderTest {
}
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf msg, List<Object> out) throws Exception {
protected void decode(ChannelHandlerContext ctx, ByteBuf msg) throws Exception {
// NOOP
}

View File

@ -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<Object> 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<Object> 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<Object> 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<Object> 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<Integer>() {
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> 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<Object> 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<Object> 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<Integer>() {
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
protected void decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception {
ctx.pipeline().remove(this);
assertTrue(in.refCnt() != 0);
}

View File

@ -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<Object> 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));
}
}

View File

@ -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<Object> 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;

View File

@ -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<T> extends ByteToMessageDecoder {
private ByteBuf handshakeBuffer;
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
protected void decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception {
if (!suppressRead && !handshakeFailed) {
try {
int readerIndex = in.readerIndex();

View File

@ -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<Object> out) throws Exception {
protected void decode(ChannelHandlerContext context, ByteBuf in) throws Exception {
if (in.readableBytes() < SslUtils.SSL_RECORD_HEADER_LENGTH) {
return;
}

View File

@ -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<Object> 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);

View File

@ -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<Object> 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());
}

View File

@ -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();

Some files were not shown because too many files have changed in this diff Show More