Remove MessageList from public API and change ChannelInbound/OutboundHandler accordingly

I must admit MesageList was pain in the ass.  Instead of forcing a
handler always loop over the list of messages, this commit splits
messageReceived(ctx, list) into two event handlers:

- messageReceived(ctx, msg)
- mmessageReceivedLast(ctx)

When Netty reads one or more messages, messageReceived(ctx, msg) event
is triggered for each message.  Once the current read operation is
finished, messageReceivedLast() is triggered to tell the handler that
the last messageReceived() was the last message in the current batch.

Similarly, for outbound, write(ctx, list) has been split into two:

- write(ctx, msg)
- flush(ctx, promise)

Instead of writing a list of message with a promise, a user is now
supposed to call write(msg) multiple times and then call flush() to
actually flush the buffered messages.

Please note that write() doesn't have a promise with it.  You must call
flush() to get notified on completion. (or you can use writeAndFlush())

Other changes:

- Because MessageList is completely hidden, codec framework uses
  List<Object> instead of MessageList as an output parameter.
This commit is contained in:
Trustin Lee 2013-07-08 19:03:40 +09:00
parent 1d196c5b59
commit cbd8817905
198 changed files with 1791 additions and 1808 deletions

View File

@ -19,10 +19,10 @@ import io.netty.buffer.ByteBuf;
import io.netty.channel.Channel; import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.CombinedChannelDuplexHandler; import io.netty.channel.CombinedChannelDuplexHandler;
import io.netty.channel.MessageList;
import io.netty.handler.codec.PrematureChannelClosureException; import io.netty.handler.codec.PrematureChannelClosureException;
import java.util.ArrayDeque; import java.util.ArrayDeque;
import java.util.List;
import java.util.Queue; import java.util.Queue;
import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicLong;
@ -86,7 +86,7 @@ public final class HttpClientCodec
@Override @Override
protected void encode( protected void encode(
ChannelHandlerContext ctx, HttpObject msg, MessageList<Object> out) throws Exception { ChannelHandlerContext ctx, HttpObject msg, List<Object> out) throws Exception {
if (msg instanceof HttpRequest && !done) { if (msg instanceof HttpRequest && !done) {
queue.offer(((HttpRequest) msg).getMethod()); queue.offer(((HttpRequest) msg).getMethod());
} }
@ -110,7 +110,7 @@ public final class HttpClientCodec
@Override @Override
protected void decode( protected void decode(
ChannelHandlerContext ctx, ByteBuf buffer, MessageList<Object> out) throws Exception { ChannelHandlerContext ctx, ByteBuf buffer, List<Object> out) throws Exception {
if (done) { if (done) {
int readable = actualReadableBytes(); int readable = actualReadableBytes();
if (readable == 0) { if (readable == 0) {

View File

@ -19,11 +19,12 @@ import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufHolder; import io.netty.buffer.ByteBufHolder;
import io.netty.buffer.Unpooled; import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.MessageList;
import io.netty.channel.embedded.EmbeddedChannel; import io.netty.channel.embedded.EmbeddedChannel;
import io.netty.handler.codec.MessageToMessageDecoder; import io.netty.handler.codec.MessageToMessageDecoder;
import io.netty.util.ReferenceCountUtil; import io.netty.util.ReferenceCountUtil;
import java.util.List;
/** /**
* Decodes the content of the received {@link HttpRequest} and {@link HttpContent}. * Decodes the content of the received {@link HttpRequest} and {@link HttpContent}.
* The original content is replaced with the new content decoded by the * The original content is replaced with the new content decoded by the
@ -51,7 +52,7 @@ public abstract class HttpContentDecoder extends MessageToMessageDecoder<HttpObj
private boolean continueResponse; private boolean continueResponse;
@Override @Override
protected void decode(ChannelHandlerContext ctx, HttpObject msg, MessageList<Object> out) throws Exception { protected void decode(ChannelHandlerContext ctx, HttpObject msg, List<Object> out) throws Exception {
if (msg instanceof HttpResponse && ((HttpResponse) msg).getStatus().code() == 100) { if (msg instanceof HttpResponse && ((HttpResponse) msg).getStatus().code() == 100) {
if (!(msg instanceof LastHttpContent)) { if (!(msg instanceof LastHttpContent)) {

View File

@ -18,7 +18,6 @@ package io.netty.handler.codec.http;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufHolder; import io.netty.buffer.ByteBufHolder;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.MessageList;
import io.netty.channel.embedded.EmbeddedChannel; import io.netty.channel.embedded.EmbeddedChannel;
import io.netty.handler.codec.MessageToMessageCodec; import io.netty.handler.codec.MessageToMessageCodec;
import io.netty.handler.codec.http.HttpHeaders.Names; import io.netty.handler.codec.http.HttpHeaders.Names;
@ -26,6 +25,7 @@ import io.netty.handler.codec.http.HttpHeaders.Values;
import io.netty.util.ReferenceCountUtil; import io.netty.util.ReferenceCountUtil;
import java.util.ArrayDeque; import java.util.ArrayDeque;
import java.util.List;
import java.util.Queue; import java.util.Queue;
/** /**
@ -69,7 +69,7 @@ public abstract class HttpContentEncoder extends MessageToMessageCodec<HttpReque
} }
@Override @Override
protected void decode(ChannelHandlerContext ctx, HttpRequest msg, MessageList<Object> out) protected void decode(ChannelHandlerContext ctx, HttpRequest msg, List<Object> out)
throws Exception { throws Exception {
String acceptedEncoding = msg.headers().get(HttpHeaders.Names.ACCEPT_ENCODING); String acceptedEncoding = msg.headers().get(HttpHeaders.Names.ACCEPT_ENCODING);
if (acceptedEncoding == null) { if (acceptedEncoding == null) {
@ -80,7 +80,7 @@ public abstract class HttpContentEncoder extends MessageToMessageCodec<HttpReque
} }
@Override @Override
protected void encode(ChannelHandlerContext ctx, HttpObject msg, MessageList<Object> out) throws Exception { protected void encode(ChannelHandlerContext ctx, HttpObject msg, List<Object> out) throws Exception {
final boolean isFull = msg instanceof HttpResponse && msg instanceof LastHttpContent; final boolean isFull = msg instanceof HttpResponse && msg instanceof LastHttpContent;
switch (state) { switch (state) {
case AWAIT_HEADERS: { case AWAIT_HEADERS: {
@ -163,7 +163,7 @@ public abstract class HttpContentEncoder extends MessageToMessageCodec<HttpReque
case AWAIT_CONTENT: { case AWAIT_CONTENT: {
ensureContent(msg); ensureContent(msg);
encodeContent((HttpContent) msg, out); encodeContent((HttpContent) msg, out);
if (out.last() instanceof LastHttpContent) { if (msg instanceof LastHttpContent) {
state = State.AWAIT_HEADERS; state = State.AWAIT_HEADERS;
} }
break; break;
@ -196,7 +196,7 @@ public abstract class HttpContentEncoder extends MessageToMessageCodec<HttpReque
} }
} }
private void encodeContent(HttpContent c, MessageList<Object> out) { private void encodeContent(HttpContent c, List<Object> out) {
ByteBuf content = c.content(); ByteBuf content = c.content();
encode(content, out); encode(content, out);
@ -256,20 +256,20 @@ public abstract class HttpContentEncoder extends MessageToMessageCodec<HttpReque
} }
} }
private void encode(ByteBuf in, MessageList<Object> out) { private void encode(ByteBuf in, List<Object> out) {
// call retain here as it will call release after its written to the channel // call retain here as it will call release after its written to the channel
encoder.writeOutbound(in.retain()); encoder.writeOutbound(in.retain());
fetchEncoderOutput(out); fetchEncoderOutput(out);
} }
private void finishEncode(MessageList<Object> out) { private void finishEncode(List<Object> out) {
if (encoder.finish()) { if (encoder.finish()) {
fetchEncoderOutput(out); fetchEncoderOutput(out);
} }
encoder = null; encoder = null;
} }
private void fetchEncoderOutput(MessageList<Object> out) { private void fetchEncoderOutput(List<Object> out) {
for (;;) { for (;;) {
ByteBuf buf = (ByteBuf) encoder.readOutbound(); ByteBuf buf = (ByteBuf) encoder.readOutbound();
if (buf == null) { if (buf == null) {

View File

@ -15,20 +15,21 @@
*/ */
package io.netty.handler.codec.http; package io.netty.handler.codec.http;
import static io.netty.handler.codec.http.HttpHeaders.is100ContinueExpected;
import static io.netty.handler.codec.http.HttpHeaders.removeTransferEncodingChunked;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.buffer.CompositeByteBuf; import io.netty.buffer.CompositeByteBuf;
import io.netty.buffer.Unpooled; import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandler; import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelPipeline; import io.netty.channel.ChannelPipeline;
import io.netty.channel.MessageList;
import io.netty.handler.codec.DecoderResult; import io.netty.handler.codec.DecoderResult;
import io.netty.handler.codec.MessageToMessageDecoder; import io.netty.handler.codec.MessageToMessageDecoder;
import io.netty.handler.codec.TooLongFrameException; import io.netty.handler.codec.TooLongFrameException;
import io.netty.util.CharsetUtil; import io.netty.util.CharsetUtil;
import io.netty.util.ReferenceCountUtil; import io.netty.util.ReferenceCountUtil;
import static io.netty.handler.codec.http.HttpHeaders.*; import java.util.List;
/** /**
* A {@link ChannelHandler} that aggregates an {@link HttpMessage} * A {@link ChannelHandler} that aggregates an {@link HttpMessage}
@ -108,7 +109,7 @@ public class HttpObjectAggregator extends MessageToMessageDecoder<HttpObject> {
} }
@Override @Override
protected void decode(ChannelHandlerContext ctx, HttpObject msg, MessageList<Object> out) throws Exception { protected void decode(ChannelHandlerContext ctx, HttpObject msg, List<Object> out) throws Exception {
FullHttpMessage currentMessage = this.currentMessage; FullHttpMessage currentMessage = this.currentMessage;
if (msg instanceof HttpMessage) { if (msg instanceof HttpMessage) {

View File

@ -19,7 +19,6 @@ import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled; import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelPipeline; import io.netty.channel.ChannelPipeline;
import io.netty.channel.MessageList;
import io.netty.handler.codec.DecoderResult; import io.netty.handler.codec.DecoderResult;
import io.netty.handler.codec.ReplayingDecoder; import io.netty.handler.codec.ReplayingDecoder;
import io.netty.handler.codec.TooLongFrameException; import io.netty.handler.codec.TooLongFrameException;
@ -168,7 +167,7 @@ public abstract class HttpObjectDecoder extends ReplayingDecoder<HttpObjectDecod
} }
@Override @Override
protected void decode(ChannelHandlerContext ctx, ByteBuf buffer, MessageList<Object> out) throws Exception { protected void decode(ChannelHandlerContext ctx, ByteBuf buffer, List<Object> out) throws Exception {
switch (state()) { switch (state()) {
case SKIP_CONTROL_CHARS: { case SKIP_CONTROL_CHARS: {
try { try {
@ -421,7 +420,7 @@ public abstract class HttpObjectDecoder extends ReplayingDecoder<HttpObjectDecod
} }
@Override @Override
protected void decodeLast(ChannelHandlerContext ctx, ByteBuf in, MessageList<Object> out) throws Exception { protected void decodeLast(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
decode(ctx, in, out); decode(ctx, in, out);
// Handle the last unfinished message. // Handle the last unfinished message.
@ -488,7 +487,7 @@ public abstract class HttpObjectDecoder extends ReplayingDecoder<HttpObjectDecod
reset(null); reset(null);
} }
private void reset(MessageList<Object> out) { private void reset(List<Object> out) {
if (out != null) { if (out != null) {
HttpMessage message = this.message; HttpMessage message = this.message;
ByteBuf content = this.content; ByteBuf content = this.content;
@ -539,7 +538,7 @@ public abstract class HttpObjectDecoder extends ReplayingDecoder<HttpObjectDecod
} }
} }
private void readFixedLengthContent(ByteBuf buffer, MessageList<Object> out) { private void readFixedLengthContent(ByteBuf buffer, List<Object> out) {
//we have a content-length so we just read the correct number of bytes //we have a content-length so we just read the correct number of bytes
long length = HttpHeaders.getContentLength(message, -1); long length = HttpHeaders.getContentLength(message, -1);
assert length <= Integer.MAX_VALUE; assert length <= Integer.MAX_VALUE;

View File

@ -15,16 +15,18 @@
*/ */
package io.netty.handler.codec.http; package io.netty.handler.codec.http;
import static io.netty.handler.codec.http.HttpConstants.COLON;
import static io.netty.handler.codec.http.HttpConstants.CR;
import static io.netty.handler.codec.http.HttpConstants.LF;
import static io.netty.handler.codec.http.HttpConstants.SP;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.MessageList;
import io.netty.handler.codec.MessageToMessageEncoder; import io.netty.handler.codec.MessageToMessageEncoder;
import io.netty.util.CharsetUtil; import io.netty.util.CharsetUtil;
import java.util.List;
import java.util.Map; import java.util.Map;
import static io.netty.handler.codec.http.HttpConstants.*;
/** /**
* Encodes an {@link HttpMessage} or an {@link HttpContent} into * Encodes an {@link HttpMessage} or an {@link HttpContent} into
* a {@link ByteBuf}. * a {@link ByteBuf}.
@ -52,7 +54,7 @@ public abstract class HttpObjectEncoder<H extends HttpMessage> extends MessageTo
private int state = ST_INIT; private int state = ST_INIT;
@Override @Override
protected void encode(ChannelHandlerContext ctx, HttpObject msg, MessageList<Object> out) throws Exception { protected void encode(ChannelHandlerContext ctx, HttpObject msg, List<Object> out) throws Exception {
if (msg instanceof HttpMessage) { if (msg instanceof HttpMessage) {
if (state != ST_INIT) { if (state != ST_INIT) {
throw new IllegalStateException("unexpected message type: " + msg.getClass().getSimpleName()); throw new IllegalStateException("unexpected message type: " + msg.getClass().getSimpleName());

View File

@ -15,8 +15,9 @@
*/ */
package io.netty.handler.codec.http.multipart; package io.netty.handler.codec.http.multipart;
import static io.netty.buffer.Unpooled.wrappedBuffer;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.channel.MessageList; import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.DecoderResult; import io.netty.handler.codec.DecoderResult;
import io.netty.handler.codec.http.DefaultFullHttpRequest; import io.netty.handler.codec.http.DefaultFullHttpRequest;
import io.netty.handler.codec.http.DefaultHttpContent; import io.netty.handler.codec.http.DefaultHttpContent;
@ -28,7 +29,7 @@ import io.netty.handler.codec.http.HttpMethod;
import io.netty.handler.codec.http.HttpRequest; import io.netty.handler.codec.http.HttpRequest;
import io.netty.handler.codec.http.HttpVersion; import io.netty.handler.codec.http.HttpVersion;
import io.netty.handler.codec.http.LastHttpContent; import io.netty.handler.codec.http.LastHttpContent;
import io.netty.handler.stream.ChunkedMessageInput; import io.netty.handler.stream.ChunkedInput;
import io.netty.util.internal.ThreadLocalRandom; import io.netty.util.internal.ThreadLocalRandom;
import java.io.File; import java.io.File;
@ -43,12 +44,10 @@ import java.util.ListIterator;
import java.util.Map; import java.util.Map;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import static io.netty.buffer.Unpooled.*;
/** /**
* This encoder will help to encode Request for a FORM as POST. * This encoder will help to encode Request for a FORM as POST.
*/ */
public class HttpPostRequestEncoder implements ChunkedMessageInput<HttpContent> { public class HttpPostRequestEncoder implements ChunkedInput<HttpContent> {
/** /**
* Different modes to use to encode form data. * Different modes to use to encode form data.
@ -942,12 +941,11 @@ public class HttpPostRequestEncoder implements ChunkedMessageInput<HttpContent>
* if the encoding is in error * if the encoding is in error
*/ */
@Override @Override
public boolean readChunk(MessageList<HttpContent> buffer) throws ErrorDataEncoderException { public HttpContent readChunk(ChannelHandlerContext ctx) throws Exception {
if (isLastChunkSent) { if (isLastChunkSent) {
return false; return null;
} else { } else {
buffer.add(nextChunk()); return nextChunk();
return true;
} }
} }

View File

@ -17,10 +17,11 @@ package io.netty.handler.codec.http.websocketx;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.MessageList;
import io.netty.handler.codec.ReplayingDecoder; import io.netty.handler.codec.ReplayingDecoder;
import io.netty.handler.codec.TooLongFrameException; import io.netty.handler.codec.TooLongFrameException;
import java.util.List;
/** /**
* Decodes {@link ByteBuf}s into {@link WebSocketFrame}s. * Decodes {@link ByteBuf}s into {@link WebSocketFrame}s.
* <p> * <p>
@ -50,7 +51,7 @@ public class WebSocket00FrameDecoder extends ReplayingDecoder<Void> implements W
} }
@Override @Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, MessageList<Object> out) throws Exception { protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
// Discard all data received if closing handshake was received before. // Discard all data received if closing handshake was received before.
if (receivedClosingHandshake) { if (receivedClosingHandshake) {
in.skipBytes(actualReadableBytes()); in.skipBytes(actualReadableBytes());

View File

@ -54,16 +54,16 @@
package io.netty.handler.codec.http.websocketx; package io.netty.handler.codec.http.websocketx;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.MessageList;
import io.netty.handler.codec.CorruptedFrameException; import io.netty.handler.codec.CorruptedFrameException;
import io.netty.handler.codec.ReplayingDecoder; import io.netty.handler.codec.ReplayingDecoder;
import io.netty.handler.codec.TooLongFrameException; import io.netty.handler.codec.TooLongFrameException;
import io.netty.util.internal.logging.InternalLogger; import io.netty.util.internal.logging.InternalLogger;
import io.netty.util.internal.logging.InternalLoggerFactory; import io.netty.util.internal.logging.InternalLoggerFactory;
import java.util.List;
/** /**
* Decodes a web socket frame from wire protocol version 8 format. This code was forked from <a * Decodes a web socket frame from wire protocol version 8 format. This code was forked from <a
* href="https://github.com/joewalnes/webbit">webbit</a> and modified. * href="https://github.com/joewalnes/webbit">webbit</a> and modified.
@ -121,7 +121,7 @@ public class WebSocket08FrameDecoder extends ReplayingDecoder<WebSocket08FrameDe
} }
@Override @Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, MessageList<Object> out) throws Exception { protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
// Discard all data received if closing handshake was received before. // Discard all data received if closing handshake was received before.
if (receivedClosingHandshake) { if (receivedClosingHandshake) {
@ -403,7 +403,7 @@ public class WebSocket08FrameDecoder extends ReplayingDecoder<WebSocket08FrameDe
private void protocolViolation(ChannelHandlerContext ctx, String reason) { private void protocolViolation(ChannelHandlerContext ctx, String reason) {
checkpoint(State.CORRUPT); checkpoint(State.CORRUPT);
if (ctx.channel().isActive()) { if (ctx.channel().isActive()) {
ctx.write(Unpooled.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE); ctx.flush().addListener(ChannelFutureListener.CLOSE);
} }
throw new CorruptedFrameException(reason); throw new CorruptedFrameException(reason);
} }

View File

@ -159,7 +159,7 @@ public abstract class WebSocketClientHandshaker {
} else { } else {
decoder.setSingleDecode(true); decoder.setSingleDecode(true);
} }
channel.write(request).addListener(new ChannelFutureListener() { channel.write(request).flush().addListener(new ChannelFutureListener() {
@Override @Override
public void operationComplete(ChannelFuture future) { public void operationComplete(ChannelFuture future) {
if (future.isSuccess()) { if (future.isSuccess()) {
@ -264,6 +264,6 @@ public abstract class WebSocketClientHandshaker {
if (channel == null) { if (channel == null) {
throw new NullPointerException("channel"); throw new NullPointerException("channel");
} }
return channel.write(frame, promise); return channel.write(frame).flush(promise);
} }
} }

View File

@ -18,10 +18,10 @@ package io.netty.handler.codec.http.websocketx;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandler; import io.netty.channel.ChannelInboundHandler;
import io.netty.channel.ChannelPipeline; import io.netty.channel.ChannelPipeline;
import io.netty.channel.MessageList;
import io.netty.handler.codec.http.HttpHeaders; import io.netty.handler.codec.http.HttpHeaders;
import java.net.URI; import java.net.URI;
import java.util.List;
/** /**
* This handler does all the heavy lifting for you to run a websocket client. * This handler does all the heavy lifting for you to run a websocket client.
@ -129,7 +129,7 @@ public class WebSocketClientProtocolHandler extends WebSocketProtocolHandler {
} }
@Override @Override
protected void decode(ChannelHandlerContext ctx, WebSocketFrame frame, MessageList<Object> out) throws Exception { protected void decode(ChannelHandlerContext ctx, WebSocketFrame frame, List<Object> out) throws Exception {
if (handleCloseFrames && frame instanceof CloseWebSocketFrame) { if (handleCloseFrames && frame instanceof CloseWebSocketFrame) {
ctx.close(); ctx.close();
return; return;

View File

@ -18,10 +18,10 @@ package io.netty.handler.codec.http.websocketx;
import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler; import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.codec.http.FullHttpResponse; import io.netty.handler.codec.http.FullHttpResponse;
class WebSocketClientProtocolHandshakeHandler extends SimpleChannelInboundHandler<FullHttpResponse> { class WebSocketClientProtocolHandshakeHandler extends ChannelInboundHandlerAdapter {
private final WebSocketClientHandshaker handshaker; private final WebSocketClientHandshaker handshaker;
public WebSocketClientProtocolHandshakeHandler(WebSocketClientHandshaker handshaker) { public WebSocketClientProtocolHandshakeHandler(WebSocketClientHandshaker handshaker) {
@ -45,9 +45,14 @@ class WebSocketClientProtocolHandshakeHandler extends SimpleChannelInboundHandle
} }
@Override @Override
protected void messageReceived(ChannelHandlerContext ctx, FullHttpResponse msg) throws Exception { public void messageReceived(ChannelHandlerContext ctx, Object msg) throws Exception {
if (!(msg instanceof FullHttpResponse)) {
ctx.fireMessageReceived(msg);
return;
}
if (!handshaker.isHandshakeComplete()) { if (!handshaker.isHandshakeComplete()) {
handshaker.finishHandshake(ctx.channel(), msg); handshaker.finishHandshake(ctx.channel(), (FullHttpResponse) msg);
ctx.fireUserEventTriggered( ctx.fireUserEventTriggered(
WebSocketClientProtocolHandler.ClientHandshakeStateEvent.HANDSHAKE_COMPLETE); WebSocketClientProtocolHandler.ClientHandshakeStateEvent.HANDSHAKE_COMPLETE);
ctx.pipeline().remove(this); ctx.pipeline().remove(this);

View File

@ -18,10 +18,11 @@ package io.netty.handler.codec.http.websocketx;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.buffer.CompositeByteBuf; import io.netty.buffer.CompositeByteBuf;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.MessageList;
import io.netty.handler.codec.MessageToMessageDecoder; import io.netty.handler.codec.MessageToMessageDecoder;
import io.netty.handler.codec.TooLongFrameException; import io.netty.handler.codec.TooLongFrameException;
import java.util.List;
/** /**
* Handler that aggregate fragmented WebSocketFrame's. * Handler that aggregate fragmented WebSocketFrame's.
* *
@ -47,7 +48,7 @@ public class WebSocketFrameAggregator extends MessageToMessageDecoder<WebSocketF
} }
@Override @Override
protected void decode(ChannelHandlerContext ctx, WebSocketFrame msg, MessageList<Object> out) throws Exception { protected void decode(ChannelHandlerContext ctx, WebSocketFrame msg, List<Object> out) throws Exception {
if (currentFrame == null) { if (currentFrame == null) {
tooLongFrameFound = false; tooLongFrameFound = false;
if (msg.isFinalFragment()) { if (msg.isFinalFragment()) {

View File

@ -17,15 +17,16 @@ package io.netty.handler.codec.http.websocketx;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.MessageList;
import io.netty.handler.codec.MessageToMessageDecoder; import io.netty.handler.codec.MessageToMessageDecoder;
import java.util.List;
abstract class WebSocketProtocolHandler extends MessageToMessageDecoder<WebSocketFrame> { abstract class WebSocketProtocolHandler extends MessageToMessageDecoder<WebSocketFrame> {
@Override @Override
protected void decode(ChannelHandlerContext ctx, WebSocketFrame frame, MessageList<Object> out) throws Exception { protected void decode(ChannelHandlerContext ctx, WebSocketFrame frame, List<Object> out) throws Exception {
if (frame instanceof PingWebSocketFrame) { if (frame instanceof PingWebSocketFrame) {
frame.content().retain(); frame.content().retain();
ctx.channel().write(new PongWebSocketFrame(frame.content())); ctx.channel().write(new PongWebSocketFrame(frame.content())).flush();
return; return;
} }
if (frame instanceof PongWebSocketFrame) { if (frame instanceof PongWebSocketFrame) {

View File

@ -158,7 +158,7 @@ public abstract class WebSocketServerHandshaker {
logger.debug(String.format("%s WS Version %s server handshake", channel, version())); logger.debug(String.format("%s WS Version %s server handshake", channel, version()));
} }
FullHttpResponse response = newHandshakeResponse(req, responseHeaders); FullHttpResponse response = newHandshakeResponse(req, responseHeaders);
channel.write(response).addListener(new ChannelFutureListener() { channel.write(response).flush().addListener(new ChannelFutureListener() {
@Override @Override
public void operationComplete(ChannelFuture future) throws Exception { public void operationComplete(ChannelFuture future) throws Exception {
if (future.isSuccess()) { if (future.isSuccess()) {
@ -225,7 +225,7 @@ public abstract class WebSocketServerHandshaker {
if (channel == null) { if (channel == null) {
throw new NullPointerException("channel"); throw new NullPointerException("channel");
} }
return channel.write(frame, promise).addListener(ChannelFutureListener.CLOSE); return channel.write(frame).flush(promise).addListener(ChannelFutureListener.CLOSE);
} }
/** /**

View File

@ -177,7 +177,7 @@ public class WebSocketServerHandshaker00 extends WebSocketServerHandshaker {
*/ */
@Override @Override
public ChannelFuture close(Channel channel, CloseWebSocketFrame frame, ChannelPromise promise) { public ChannelFuture close(Channel channel, CloseWebSocketFrame frame, ChannelPromise promise) {
return channel.write(frame, promise); return channel.write(frame).flush(promise);
} }
@Override @Override

View File

@ -15,21 +15,21 @@
*/ */
package io.netty.handler.codec.http.websocketx; package io.netty.handler.codec.http.websocketx;
import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1;
import io.netty.buffer.Unpooled; import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandler; import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandler; import io.netty.channel.ChannelInboundHandler;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.ChannelPipeline; import io.netty.channel.ChannelPipeline;
import io.netty.channel.MessageList;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.DefaultFullHttpResponse; import io.netty.handler.codec.http.DefaultFullHttpResponse;
import io.netty.handler.codec.http.FullHttpRequest; import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.FullHttpResponse; import io.netty.handler.codec.http.FullHttpResponse;
import io.netty.handler.codec.http.HttpResponseStatus; import io.netty.handler.codec.http.HttpResponseStatus;
import io.netty.util.AttributeKey; import io.netty.util.AttributeKey;
import static io.netty.handler.codec.http.HttpVersion.*; import java.util.List;
/** /**
* This handler does all the heavy lifting for you to run a websocket server. * This handler does all the heavy lifting for you to run a websocket server.
@ -91,7 +91,7 @@ public class WebSocketServerProtocolHandler extends WebSocketProtocolHandler {
} }
@Override @Override
protected void decode(ChannelHandlerContext ctx, WebSocketFrame frame, MessageList<Object> out) throws Exception { protected void decode(ChannelHandlerContext ctx, WebSocketFrame frame, List<Object> out) throws Exception {
if (frame instanceof CloseWebSocketFrame) { if (frame instanceof CloseWebSocketFrame) {
WebSocketServerHandshaker handshaker = getHandshaker(ctx); WebSocketServerHandshaker handshaker = getHandshaker(ctx);
frame.retain(); frame.retain();
@ -106,7 +106,7 @@ public class WebSocketServerProtocolHandler extends WebSocketProtocolHandler {
if (cause instanceof WebSocketHandshakeException) { if (cause instanceof WebSocketHandshakeException) {
FullHttpResponse response = new DefaultFullHttpResponse( FullHttpResponse response = new DefaultFullHttpResponse(
HTTP_1_1, HttpResponseStatus.BAD_REQUEST, Unpooled.wrappedBuffer(cause.getMessage().getBytes())); HTTP_1_1, HttpResponseStatus.BAD_REQUEST, Unpooled.wrappedBuffer(cause.getMessage().getBytes()));
ctx.channel().write(response).addListener(ChannelFutureListener.CLOSE); ctx.channel().write(response).flush().addListener(ChannelFutureListener.CLOSE);
} else { } else {
ctx.close(); ctx.close();
} }
@ -121,12 +121,16 @@ public class WebSocketServerProtocolHandler extends WebSocketProtocolHandler {
} }
static ChannelHandler forbiddenHttpRequestResponder() { static ChannelHandler forbiddenHttpRequestResponder() {
return new SimpleChannelInboundHandler<FullHttpRequest>() { return new ChannelInboundHandlerAdapter() {
@Override @Override
protected void messageReceived(ChannelHandlerContext ctx, FullHttpRequest msg) throws Exception { public void messageReceived(ChannelHandlerContext ctx, Object msg) throws Exception {
FullHttpResponse response = if (msg instanceof FullHttpRequest) {
new DefaultFullHttpResponse(HTTP_1_1, HttpResponseStatus.FORBIDDEN); FullHttpResponse response =
ctx.channel().write(response); new DefaultFullHttpResponse(HTTP_1_1, HttpResponseStatus.FORBIDDEN);
ctx.channel().write(response).flush();
} else {
ctx.fireMessageReceived(msg);
}
} }
}; };
} }

View File

@ -20,7 +20,6 @@ import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter; import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.ChannelPipeline; import io.netty.channel.ChannelPipeline;
import io.netty.channel.MessageList;
import io.netty.handler.codec.http.DefaultFullHttpResponse; import io.netty.handler.codec.http.DefaultFullHttpResponse;
import io.netty.handler.codec.http.FullHttpRequest; import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.HttpHeaders; import io.netty.handler.codec.http.HttpHeaders;
@ -51,42 +50,39 @@ class WebSocketServerProtocolHandshakeHandler
} }
@Override @Override
public void messageReceived(final ChannelHandlerContext ctx, MessageList<Object> msgs) throws Exception { public void messageReceived(final ChannelHandlerContext ctx, Object msg) throws Exception {
MessageList<FullHttpRequest> requests = msgs.cast(); FullHttpRequest req = (FullHttpRequest) msg;
for (int i = 0; i < requests.size(); i++) { if (req.getMethod() != GET) {
FullHttpRequest req = requests.get(i); sendHttpResponse(ctx, req, new DefaultFullHttpResponse(HTTP_1_1, FORBIDDEN));
if (req.getMethod() != GET) { return;
sendHttpResponse(ctx, req, new DefaultFullHttpResponse(HTTP_1_1, FORBIDDEN)); }
return;
}
final WebSocketServerHandshakerFactory wsFactory = new WebSocketServerHandshakerFactory( final WebSocketServerHandshakerFactory wsFactory = new WebSocketServerHandshakerFactory(
getWebSocketLocation(ctx.pipeline(), req, websocketPath), subprotocols, allowExtensions); getWebSocketLocation(ctx.pipeline(), req, websocketPath), subprotocols, allowExtensions);
final WebSocketServerHandshaker handshaker = wsFactory.newHandshaker(req); final WebSocketServerHandshaker handshaker = wsFactory.newHandshaker(req);
if (handshaker == null) { if (handshaker == null) {
WebSocketServerHandshakerFactory.sendUnsupportedWebSocketVersionResponse(ctx.channel()); WebSocketServerHandshakerFactory.sendUnsupportedWebSocketVersionResponse(ctx.channel());
} else { } else {
final ChannelFuture handshakeFuture = handshaker.handshake(ctx.channel(), req); final ChannelFuture handshakeFuture = handshaker.handshake(ctx.channel(), req);
handshakeFuture.addListener(new ChannelFutureListener() { handshakeFuture.addListener(new ChannelFutureListener() {
@Override @Override
public void operationComplete(ChannelFuture future) throws Exception { public void operationComplete(ChannelFuture future) throws Exception {
if (!future.isSuccess()) { if (!future.isSuccess()) {
ctx.fireExceptionCaught(future.cause()); ctx.fireExceptionCaught(future.cause());
} else { } else {
ctx.fireUserEventTriggered( ctx.fireUserEventTriggered(
WebSocketServerProtocolHandler.ServerHandshakeStateEvent.HANDSHAKE_COMPLETE); WebSocketServerProtocolHandler.ServerHandshakeStateEvent.HANDSHAKE_COMPLETE);
}
} }
}); }
WebSocketServerProtocolHandler.setHandshaker(ctx, handshaker); });
ctx.pipeline().replace(this, "WS403Responder", WebSocketServerProtocolHandler.setHandshaker(ctx, handshaker);
WebSocketServerProtocolHandler.forbiddenHttpRequestResponder()); ctx.pipeline().replace(this, "WS403Responder",
} WebSocketServerProtocolHandler.forbiddenHttpRequestResponder());
} }
} }
private static void sendHttpResponse(ChannelHandlerContext ctx, HttpRequest req, HttpResponse res) { private static void sendHttpResponse(ChannelHandlerContext ctx, HttpRequest req, HttpResponse res) {
ChannelFuture f = ctx.channel().write(res); ChannelFuture f = ctx.channel().write(res).flush();
if (!isKeepAlive(req) || res.getStatus().code() != 200) { if (!isKeepAlive(req) || res.getStatus().code() != 200) {
f.addListener(ChannelFutureListener.CLOSE); f.addListener(ChannelFutureListener.CLOSE);
} }

View File

@ -15,12 +15,34 @@
*/ */
package io.netty.handler.codec.spdy; package io.netty.handler.codec.spdy;
import static io.netty.handler.codec.spdy.SpdyCodecUtil.SPDY_DATA_FLAG_FIN;
import static io.netty.handler.codec.spdy.SpdyCodecUtil.SPDY_DATA_FRAME;
import static io.netty.handler.codec.spdy.SpdyCodecUtil.SPDY_FLAG_FIN;
import static io.netty.handler.codec.spdy.SpdyCodecUtil.SPDY_FLAG_UNIDIRECTIONAL;
import static io.netty.handler.codec.spdy.SpdyCodecUtil.SPDY_GOAWAY_FRAME;
import static io.netty.handler.codec.spdy.SpdyCodecUtil.SPDY_HEADERS_FRAME;
import static io.netty.handler.codec.spdy.SpdyCodecUtil.SPDY_HEADER_FLAGS_OFFSET;
import static io.netty.handler.codec.spdy.SpdyCodecUtil.SPDY_HEADER_LENGTH_OFFSET;
import static io.netty.handler.codec.spdy.SpdyCodecUtil.SPDY_HEADER_SIZE;
import static io.netty.handler.codec.spdy.SpdyCodecUtil.SPDY_HEADER_TYPE_OFFSET;
import static io.netty.handler.codec.spdy.SpdyCodecUtil.SPDY_PING_FRAME;
import static io.netty.handler.codec.spdy.SpdyCodecUtil.SPDY_RST_STREAM_FRAME;
import static io.netty.handler.codec.spdy.SpdyCodecUtil.SPDY_SETTINGS_CLEAR;
import static io.netty.handler.codec.spdy.SpdyCodecUtil.SPDY_SETTINGS_FRAME;
import static io.netty.handler.codec.spdy.SpdyCodecUtil.SPDY_SETTINGS_PERSISTED;
import static io.netty.handler.codec.spdy.SpdyCodecUtil.SPDY_SETTINGS_PERSIST_VALUE;
import static io.netty.handler.codec.spdy.SpdyCodecUtil.SPDY_SYN_REPLY_FRAME;
import static io.netty.handler.codec.spdy.SpdyCodecUtil.SPDY_SYN_STREAM_FRAME;
import static io.netty.handler.codec.spdy.SpdyCodecUtil.SPDY_WINDOW_UPDATE_FRAME;
import static io.netty.handler.codec.spdy.SpdyCodecUtil.getSignedInt;
import static io.netty.handler.codec.spdy.SpdyCodecUtil.getUnsignedInt;
import static io.netty.handler.codec.spdy.SpdyCodecUtil.getUnsignedMedium;
import static io.netty.handler.codec.spdy.SpdyCodecUtil.getUnsignedShort;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.MessageList;
import io.netty.handler.codec.ByteToMessageDecoder; import io.netty.handler.codec.ByteToMessageDecoder;
import static io.netty.handler.codec.spdy.SpdyCodecUtil.*; import java.util.List;
/** /**
* Decodes {@link ByteBuf}s into SPDY Frames. * Decodes {@link ByteBuf}s into SPDY Frames.
@ -89,7 +111,7 @@ public class SpdyFrameDecoder extends ByteToMessageDecoder {
} }
@Override @Override
public void decodeLast(ChannelHandlerContext ctx, ByteBuf in, MessageList<Object> out) throws Exception { public void decodeLast(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
try { try {
decode(ctx, in, out); decode(ctx, in, out);
} finally { } finally {
@ -98,7 +120,7 @@ public class SpdyFrameDecoder extends ByteToMessageDecoder {
} }
@Override @Override
protected void decode(ChannelHandlerContext ctx, ByteBuf buffer, MessageList<Object> out) throws Exception { protected void decode(ChannelHandlerContext ctx, ByteBuf buffer, List<Object> out) throws Exception {
switch(state) { switch(state) {
case READ_COMMON_HEADER: case READ_COMMON_HEADER:
state = readCommonHeader(buffer); state = readCommonHeader(buffer);

View File

@ -17,7 +17,6 @@ package io.netty.handler.codec.spdy;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.MessageList;
import io.netty.handler.codec.MessageToMessageDecoder; import io.netty.handler.codec.MessageToMessageDecoder;
import io.netty.handler.codec.TooLongFrameException; import io.netty.handler.codec.TooLongFrameException;
import io.netty.handler.codec.http.DefaultFullHttpRequest; import io.netty.handler.codec.http.DefaultFullHttpRequest;
@ -31,6 +30,7 @@ import io.netty.handler.codec.http.HttpResponseStatus;
import io.netty.handler.codec.http.HttpVersion; import io.netty.handler.codec.http.HttpVersion;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
/** /**
@ -91,7 +91,7 @@ public class SpdyHttpDecoder extends MessageToMessageDecoder<SpdyFrame> {
} }
@Override @Override
protected void decode(ChannelHandlerContext ctx, SpdyFrame msg, MessageList<Object> out) protected void decode(ChannelHandlerContext ctx, SpdyFrame msg, List<Object> out)
throws Exception { throws Exception {
if (msg instanceof SpdySynStreamFrame) { if (msg instanceof SpdySynStreamFrame) {

View File

@ -16,7 +16,6 @@
package io.netty.handler.codec.spdy; package io.netty.handler.codec.spdy;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.MessageList;
import io.netty.handler.codec.MessageToMessageEncoder; import io.netty.handler.codec.MessageToMessageEncoder;
import io.netty.handler.codec.UnsupportedMessageTypeException; import io.netty.handler.codec.UnsupportedMessageTypeException;
import io.netty.handler.codec.http.FullHttpRequest; import io.netty.handler.codec.http.FullHttpRequest;
@ -139,7 +138,7 @@ public class SpdyHttpEncoder extends MessageToMessageEncoder<HttpObject> {
} }
@Override @Override
protected void encode(ChannelHandlerContext ctx, HttpObject msg, MessageList<Object> out) throws Exception { protected void encode(ChannelHandlerContext ctx, HttpObject msg, List<Object> out) throws Exception {
boolean valid = false; boolean valid = false;

View File

@ -16,12 +16,12 @@
package io.netty.handler.codec.spdy; package io.netty.handler.codec.spdy;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.MessageList;
import io.netty.handler.codec.MessageToMessageCodec; import io.netty.handler.codec.MessageToMessageCodec;
import io.netty.handler.codec.http.HttpMessage; import io.netty.handler.codec.http.HttpMessage;
import io.netty.util.ReferenceCountUtil; import io.netty.util.ReferenceCountUtil;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List;
import java.util.Queue; import java.util.Queue;
/** /**
@ -40,7 +40,7 @@ public class SpdyHttpResponseStreamIdHandler extends
} }
@Override @Override
protected void encode(ChannelHandlerContext ctx, HttpMessage msg, MessageList<Object> out) throws Exception { protected void encode(ChannelHandlerContext ctx, HttpMessage msg, List<Object> out) throws Exception {
Integer id = ids.poll(); Integer id = ids.poll();
if (id != null && id.intValue() != NO_ID && !msg.headers().contains(SpdyHttpHeaders.Names.STREAM_ID)) { if (id != null && id.intValue() != NO_ID && !msg.headers().contains(SpdyHttpHeaders.Names.STREAM_ID)) {
SpdyHttpHeaders.setStreamId(msg, id); SpdyHttpHeaders.setStreamId(msg, id);
@ -50,7 +50,7 @@ public class SpdyHttpResponseStreamIdHandler extends
} }
@Override @Override
protected void decode(ChannelHandlerContext ctx, Object msg, MessageList<Object> out) throws Exception { protected void decode(ChannelHandlerContext ctx, Object msg, List<Object> out) throws Exception {
if (msg instanceof HttpMessage) { if (msg instanceof HttpMessage) {
boolean contains = ((HttpMessage) msg).headers().contains(SpdyHttpHeaders.Names.STREAM_ID); boolean contains = ((HttpMessage) msg).headers().contains(SpdyHttpHeaders.Names.STREAM_ID);
if (!contains) { if (!contains) {

View File

@ -20,7 +20,6 @@ import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandler; import io.netty.channel.ChannelInboundHandler;
import io.netty.channel.ChannelInboundHandlerAdapter; import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.ChannelPipeline; import io.netty.channel.ChannelPipeline;
import io.netty.channel.MessageList;
import io.netty.handler.codec.http.HttpObjectAggregator; import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpRequestDecoder; import io.netty.handler.codec.http.HttpRequestDecoder;
import io.netty.handler.codec.http.HttpResponseEncoder; import io.netty.handler.codec.http.HttpResponseEncoder;
@ -61,13 +60,13 @@ public abstract class SpdyOrHttpChooser extends ChannelInboundHandlerAdapter {
protected abstract SelectedProtocol getProtocol(SSLEngine engine); protected abstract SelectedProtocol getProtocol(SSLEngine engine);
@Override @Override
public void messageReceived(ChannelHandlerContext ctx, MessageList<Object> in) throws Exception { public void messageReceived(ChannelHandlerContext ctx, Object msg) throws Exception {
if (initPipeline(ctx)) { if (initPipeline(ctx)) {
// When we reached here we can remove this handler as its now clear what protocol we want to use // When we reached here we can remove this handler as its now clear what protocol we want to use
// from this point on. // from this point on.
ctx.pipeline().remove(this); ctx.pipeline().remove(this);
ctx.fireMessageReceived(in); ctx.fireMessageReceived(msg);
} }
} }

View File

@ -20,9 +20,10 @@ import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelPromise; import io.netty.channel.ChannelPromise;
import io.netty.channel.MessageList;
import io.netty.util.internal.EmptyArrays; import io.netty.util.internal.EmptyArrays;
import java.util.ArrayDeque;
import java.util.Queue;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
/** /**
@ -54,6 +55,8 @@ public class SpdySessionHandler
private final AtomicInteger pings = new AtomicInteger(); private final AtomicInteger pings = new AtomicInteger();
private final Queue<Object> outboundBuffer = new ArrayDeque<Object>();
private boolean sentGoAwayFrame; private boolean sentGoAwayFrame;
private boolean receivedGoAwayFrame; private boolean receivedGoAwayFrame;
@ -81,34 +84,7 @@ public class SpdySessionHandler
} }
@Override @Override
public void messageReceived(ChannelHandlerContext ctx, MessageList<Object> in) throws Exception { public void messageReceived(ChannelHandlerContext ctx, Object msg) throws Exception {
boolean handled = false;
MessageList<Object> out = MessageList.newInstance();
for (int i = 0 ; i < in.size(); i++) {
Object msg = in.get(i);
if (msg == null) {
break;
}
if (msg instanceof SpdySynStreamFrame) {
// Let the next handlers handle the buffered messages before SYN_STREAM message updates the
// lastGoodStreamId.
if (handled) {
ctx.fireMessageReceived(out);
out = MessageList.newInstance();
}
}
handleInboundMessage(ctx, msg, out);
handled = true;
}
in.recycle();
ctx.fireMessageReceived(out);
}
private void handleInboundMessage(ChannelHandlerContext ctx, Object msg, MessageList<Object> out) throws Exception {
if (msg instanceof SpdyDataFrame) { if (msg instanceof SpdyDataFrame) {
/* /*
@ -133,7 +109,6 @@ public class SpdySessionHandler
* If an endpoint receives a data frame after the stream is closed, it must send * If an endpoint receives a data frame after the stream is closed, it must send
* a RST_STREAM frame with the getStatus PROTOCOL_ERROR. * a RST_STREAM frame with the getStatus PROTOCOL_ERROR.
*/ */
SpdyDataFrame spdyDataFrame = (SpdyDataFrame) msg; SpdyDataFrame spdyDataFrame = (SpdyDataFrame) msg;
int streamId = spdyDataFrame.getStreamId(); int streamId = spdyDataFrame.getStreamId();
@ -141,9 +116,9 @@ public class SpdySessionHandler
if (!spdySession.isActiveStream(streamId)) { if (!spdySession.isActiveStream(streamId)) {
if (streamId <= lastGoodStreamId) { if (streamId <= lastGoodStreamId) {
issueStreamError(ctx, streamId, SpdyStreamStatus.PROTOCOL_ERROR, out); issueStreamError(ctx, streamId, SpdyStreamStatus.PROTOCOL_ERROR);
} else if (!sentGoAwayFrame) { } else if (!sentGoAwayFrame) {
issueStreamError(ctx, streamId, SpdyStreamStatus.INVALID_STREAM, out); issueStreamError(ctx, streamId, SpdyStreamStatus.INVALID_STREAM);
} }
return; return;
} }
@ -151,13 +126,13 @@ public class SpdySessionHandler
// Check if we received a data frame for a stream which is half-closed // Check if we received a data frame for a stream which is half-closed
if (spdySession.isRemoteSideClosed(streamId)) { if (spdySession.isRemoteSideClosed(streamId)) {
issueStreamError(ctx, streamId, SpdyStreamStatus.STREAM_ALREADY_CLOSED, out); issueStreamError(ctx, streamId, SpdyStreamStatus.STREAM_ALREADY_CLOSED);
return; return;
} }
// Check if we received a data frame before receiving a SYN_REPLY // Check if we received a data frame before receiving a SYN_REPLY
if (!isRemoteInitiatedID(streamId) && !spdySession.hasReceivedReply(streamId)) { if (!isRemoteInitiatedID(streamId) && !spdySession.hasReceivedReply(streamId)) {
issueStreamError(ctx, streamId, SpdyStreamStatus.PROTOCOL_ERROR, out); issueStreamError(ctx, streamId, SpdyStreamStatus.PROTOCOL_ERROR);
return; return;
} }
@ -178,7 +153,7 @@ public class SpdySessionHandler
// This difference is stored for the session when writing the SETTINGS frame // This difference is stored for the session when writing the SETTINGS frame
// and is cleared once we send a WINDOW_UPDATE frame. // and is cleared once we send a WINDOW_UPDATE frame.
if (newWindowSize < spdySession.getReceiveWindowSizeLowerBound(streamId)) { if (newWindowSize < spdySession.getReceiveWindowSizeLowerBound(streamId)) {
issueStreamError(ctx, streamId, SpdyStreamStatus.FLOW_CONTROL_ERROR, out); issueStreamError(ctx, streamId, SpdyStreamStatus.FLOW_CONTROL_ERROR);
return; return;
} }
@ -188,7 +163,7 @@ public class SpdySessionHandler
while (spdyDataFrame.content().readableBytes() > initialReceiveWindowSize) { while (spdyDataFrame.content().readableBytes() > initialReceiveWindowSize) {
SpdyDataFrame partialDataFrame = new DefaultSpdyDataFrame(streamId, SpdyDataFrame partialDataFrame = new DefaultSpdyDataFrame(streamId,
spdyDataFrame.content().readSlice(initialReceiveWindowSize).retain()); spdyDataFrame.content().readSlice(initialReceiveWindowSize).retain());
ctx.write(partialDataFrame); ctx.write(partialDataFrame).flush();
} }
} }
@ -198,7 +173,7 @@ public class SpdySessionHandler
spdySession.updateReceiveWindowSize(streamId, deltaWindowSize); spdySession.updateReceiveWindowSize(streamId, deltaWindowSize);
SpdyWindowUpdateFrame spdyWindowUpdateFrame = SpdyWindowUpdateFrame spdyWindowUpdateFrame =
new DefaultSpdyWindowUpdateFrame(streamId, deltaWindowSize); new DefaultSpdyWindowUpdateFrame(streamId, deltaWindowSize);
ctx.write(spdyWindowUpdateFrame); ctx.write(spdyWindowUpdateFrame).flush();
} }
} }
@ -230,7 +205,7 @@ public class SpdySessionHandler
if (spdySynStreamFrame.isInvalid() || if (spdySynStreamFrame.isInvalid() ||
!isRemoteInitiatedID(streamId) || !isRemoteInitiatedID(streamId) ||
spdySession.isActiveStream(streamId)) { spdySession.isActiveStream(streamId)) {
issueStreamError(ctx, streamId, SpdyStreamStatus.PROTOCOL_ERROR, out); issueStreamError(ctx, streamId, SpdyStreamStatus.PROTOCOL_ERROR);
return; return;
} }
@ -245,7 +220,7 @@ public class SpdySessionHandler
boolean remoteSideClosed = spdySynStreamFrame.isLast(); boolean remoteSideClosed = spdySynStreamFrame.isLast();
boolean localSideClosed = spdySynStreamFrame.isUnidirectional(); boolean localSideClosed = spdySynStreamFrame.isUnidirectional();
if (!acceptStream(streamId, priority, remoteSideClosed, localSideClosed)) { if (!acceptStream(streamId, priority, remoteSideClosed, localSideClosed)) {
issueStreamError(ctx, streamId, SpdyStreamStatus.REFUSED_STREAM, out); issueStreamError(ctx, streamId, SpdyStreamStatus.REFUSED_STREAM);
return; return;
} }
@ -265,13 +240,13 @@ public class SpdySessionHandler
if (spdySynReplyFrame.isInvalid() || if (spdySynReplyFrame.isInvalid() ||
isRemoteInitiatedID(streamId) || isRemoteInitiatedID(streamId) ||
spdySession.isRemoteSideClosed(streamId)) { spdySession.isRemoteSideClosed(streamId)) {
issueStreamError(ctx, streamId, SpdyStreamStatus.INVALID_STREAM, out); issueStreamError(ctx, streamId, SpdyStreamStatus.INVALID_STREAM);
return; return;
} }
// Check if we have received multiple frames for the same Stream-ID // Check if we have received multiple frames for the same Stream-ID
if (spdySession.hasReceivedReply(streamId)) { if (spdySession.hasReceivedReply(streamId)) {
issueStreamError(ctx, streamId, SpdyStreamStatus.STREAM_IN_USE, out); issueStreamError(ctx, streamId, SpdyStreamStatus.STREAM_IN_USE);
return; return;
} }
@ -336,7 +311,7 @@ public class SpdySessionHandler
SpdyPingFrame spdyPingFrame = (SpdyPingFrame) msg; SpdyPingFrame spdyPingFrame = (SpdyPingFrame) msg;
if (isRemoteInitiatedID(spdyPingFrame.getId())) { if (isRemoteInitiatedID(spdyPingFrame.getId())) {
ctx.write(spdyPingFrame); ctx.write(spdyPingFrame).flush();
return; return;
} }
@ -357,12 +332,12 @@ public class SpdySessionHandler
// Check if we received a valid HEADERS frame // Check if we received a valid HEADERS frame
if (spdyHeadersFrame.isInvalid()) { if (spdyHeadersFrame.isInvalid()) {
issueStreamError(ctx, streamId, SpdyStreamStatus.PROTOCOL_ERROR, out); issueStreamError(ctx, streamId, SpdyStreamStatus.PROTOCOL_ERROR);
return; return;
} }
if (spdySession.isRemoteSideClosed(streamId)) { if (spdySession.isRemoteSideClosed(streamId)) {
issueStreamError(ctx, streamId, SpdyStreamStatus.INVALID_STREAM, out); issueStreamError(ctx, streamId, SpdyStreamStatus.INVALID_STREAM);
return; return;
} }
@ -395,15 +370,15 @@ public class SpdySessionHandler
// Check for numerical overflow // Check for numerical overflow
if (spdySession.getSendWindowSize(streamId) > Integer.MAX_VALUE - deltaWindowSize) { if (spdySession.getSendWindowSize(streamId) > Integer.MAX_VALUE - deltaWindowSize) {
issueStreamError(ctx, streamId, SpdyStreamStatus.FLOW_CONTROL_ERROR, out); issueStreamError(ctx, streamId, SpdyStreamStatus.FLOW_CONTROL_ERROR);
return; return;
} }
updateSendWindowSize(streamId, deltaWindowSize, out); updateSendWindowSize(ctx, streamId, deltaWindowSize);
} }
} }
out.add(msg); ctx.fireMessageReceived(msg);
} }
@Override @Override
@ -421,43 +396,49 @@ public class SpdySessionHandler
} }
@Override @Override
public void write(ChannelHandlerContext ctx, MessageList<Object> msgs, ChannelPromise promise) throws Exception { public void write(ChannelHandlerContext ctx, Object msg) throws Exception {
MessageList<Object> out = MessageList.newInstance(); outboundBuffer.add(msg);
for (int i = 0; i < msgs.size(); i++) {
Object msg = msgs.get(i);
if (msg == null) {
break;
}
if (msg instanceof SpdyDataFrame ||
msg instanceof SpdySynStreamFrame ||
msg instanceof SpdySynReplyFrame ||
msg instanceof SpdyRstStreamFrame ||
msg instanceof SpdySettingsFrame ||
msg instanceof SpdyPingFrame ||
msg instanceof SpdyGoAwayFrame ||
msg instanceof SpdyHeadersFrame ||
msg instanceof SpdyWindowUpdateFrame) {
try {
handleOutboundMessage(ctx, msg, out);
} catch (SpdyProtocolException e) {
if (e == PROTOCOL_EXCEPTION) {
// on the case of PROTOCOL_EXCEPTION, fail the promise directly
// See #1211
promise.setFailure(PROTOCOL_EXCEPTION);
return;
}
}
} else {
out.add(msg);
}
}
msgs.recycle();
ctx.write(out, promise);
} }
private void handleOutboundMessage(ChannelHandlerContext ctx, Object msg, MessageList<Object> out) @Override
throws Exception { public void flush(ChannelHandlerContext ctx, ChannelPromise promise) throws Exception {
try {
for (;;) {
Object msg = outboundBuffer.poll();
if (msg == null) {
break;
}
if (msg instanceof SpdyDataFrame ||
msg instanceof SpdySynStreamFrame ||
msg instanceof SpdySynReplyFrame ||
msg instanceof SpdyRstStreamFrame ||
msg instanceof SpdySettingsFrame ||
msg instanceof SpdyPingFrame ||
msg instanceof SpdyGoAwayFrame ||
msg instanceof SpdyHeadersFrame ||
msg instanceof SpdyWindowUpdateFrame) {
try {
handleOutboundMessage(ctx, msg);
} catch (SpdyProtocolException e) {
if (e == PROTOCOL_EXCEPTION) {
// On the case of PROTOCOL_EXCEPTION, fail the promise directly
// See #1211
promise.setFailure(PROTOCOL_EXCEPTION);
return;
}
}
} else {
ctx.write(msg);
}
}
ctx.flush(promise);
} finally {
outboundBuffer.clear();
}
}
private void handleOutboundMessage(ChannelHandlerContext ctx, Object msg) throws Exception {
if (msg instanceof SpdyDataFrame) { if (msg instanceof SpdyDataFrame) {
SpdyDataFrame spdyDataFrame = (SpdyDataFrame) msg; SpdyDataFrame spdyDataFrame = (SpdyDataFrame) msg;
@ -647,7 +628,7 @@ public class SpdySessionHandler
throw PROTOCOL_EXCEPTION; throw PROTOCOL_EXCEPTION;
} }
out.add(msg); ctx.write(msg);
} }
/* /*
@ -676,17 +657,14 @@ public class SpdySessionHandler
* *
* Note: this is only called by the worker thread * Note: this is only called by the worker thread
*/ */
private void issueStreamError( private void issueStreamError(ChannelHandlerContext ctx, int streamId, SpdyStreamStatus status) {
ChannelHandlerContext ctx, int streamId, SpdyStreamStatus status, MessageList<Object> in) {
boolean fireMessageReceived = !spdySession.isRemoteSideClosed(streamId); boolean fireMessageReceived = !spdySession.isRemoteSideClosed(streamId);
removeStream(ctx, streamId); removeStream(ctx, streamId);
SpdyRstStreamFrame spdyRstStreamFrame = new DefaultSpdyRstStreamFrame(streamId, status); SpdyRstStreamFrame spdyRstStreamFrame = new DefaultSpdyRstStreamFrame(streamId, status);
ctx.write(spdyRstStreamFrame); ctx.write(spdyRstStreamFrame).flush();
if (fireMessageReceived) { if (fireMessageReceived) {
in.add(spdyRstStreamFrame); ctx.fireMessageReceived(spdyRstStreamFrame);
ctx.fireMessageReceived(in.copy());
in.clear();
} }
} }
@ -783,7 +761,7 @@ public class SpdySessionHandler
} }
} }
private void updateSendWindowSize(final int streamId, int deltaWindowSize, MessageList<Object> out) { private void updateSendWindowSize(ChannelHandlerContext ctx, final int streamId, int deltaWindowSize) {
synchronized (flowControlLock) { synchronized (flowControlLock) {
int newWindowSize = spdySession.updateSendWindowSize(streamId, deltaWindowSize); int newWindowSize = spdySession.updateSendWindowSize(streamId, deltaWindowSize);
@ -822,7 +800,7 @@ public class SpdySessionHandler
halfCloseStream(streamId, false); halfCloseStream(streamId, false);
} }
out.add(spdyDataFrame); ctx.fireMessageReceived(spdyDataFrame);
} else { } else {
// We can send a partial frame // We can send a partial frame
spdySession.updateSendWindowSize(streamId, -1 * newWindowSize); spdySession.updateSendWindowSize(streamId, -1 * newWindowSize);
@ -848,7 +826,7 @@ public class SpdySessionHandler
// } // }
//}); //});
out.add(partialDataFrame); ctx.fireMessageReceived(partialDataFrame);
newWindowSize = 0; newWindowSize = 0;
} }
@ -878,7 +856,7 @@ public class SpdySessionHandler
if (!sentGoAwayFrame) { if (!sentGoAwayFrame) {
sentGoAwayFrame = true; sentGoAwayFrame = true;
SpdyGoAwayFrame spdyGoAwayFrame = new DefaultSpdyGoAwayFrame(lastGoodStreamId, status); SpdyGoAwayFrame spdyGoAwayFrame = new DefaultSpdyGoAwayFrame(lastGoodStreamId, status);
return ctx.write(spdyGoAwayFrame); return ctx.write(spdyGoAwayFrame).flush();
} else { } else {
return ctx.newSucceededFuture(); return ctx.newSucceededFuture();
} }

View File

@ -17,10 +17,9 @@ package io.netty.handler.codec.http.websocketx;
import io.netty.channel.ChannelHandler; import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.ChannelOutboundHandlerAdapter; import io.netty.channel.ChannelOutboundHandlerAdapter;
import io.netty.channel.ChannelPromise; import io.netty.channel.ChannelPromise;
import io.netty.channel.MessageList;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.embedded.EmbeddedChannel; import io.netty.channel.embedded.EmbeddedChannel;
import io.netty.handler.codec.http.DefaultFullHttpRequest; import io.netty.handler.codec.http.DefaultFullHttpRequest;
import io.netty.handler.codec.http.FullHttpRequest; import io.netty.handler.codec.http.FullHttpRequest;
@ -147,22 +146,23 @@ public class WebSocketServerProtocolHandlerTest {
private class MockOutboundHandler extends ChannelOutboundHandlerAdapter { private class MockOutboundHandler extends ChannelOutboundHandlerAdapter {
@Override @Override
public void write(ChannelHandlerContext ctx, MessageList<Object> msgs, ChannelPromise promise) public void write(ChannelHandlerContext ctx, Object msg) throws Exception {
throws Exception { responses.add((FullHttpResponse) msg);
for (int i = 0; i < msgs.size(); i++) { }
responses.add((FullHttpResponse) msgs.get(i));
} @Override
public void flush(ChannelHandlerContext ctx, ChannelPromise promise) throws Exception {
promise.setSuccess(); promise.setSuccess();
} }
} }
private static class CustomTextFrameHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> { private static class CustomTextFrameHandler extends ChannelInboundHandlerAdapter {
private String content; private String content;
@Override @Override
public void messageReceived(ChannelHandlerContext ctx, TextWebSocketFrame msg) throws Exception { public void messageReceived(ChannelHandlerContext ctx, Object msg) throws Exception {
assertNull(content); assertNull(content);
content = "processed: " + msg.text(); content = "processed: " + ((TextWebSocketFrame) msg).text();
} }
String getContent() { String getContent() {

View File

@ -19,9 +19,9 @@ import io.netty.bootstrap.Bootstrap;
import io.netty.bootstrap.ServerBootstrap; import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel; import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup; import io.netty.channel.EventLoopGroup;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel; import io.netty.channel.socket.nio.NioServerSocketChannel;
@ -103,7 +103,7 @@ public class SpdyFrameDecoderTest {
} }
private static void sendAndWaitForFrame(Channel cc, SpdyFrame frame, CaptureHandler handler) { private static void sendAndWaitForFrame(Channel cc, SpdyFrame frame, CaptureHandler handler) {
cc.write(frame); cc.write(frame).flush();
long theFuture = System.currentTimeMillis() + 3000; long theFuture = System.currentTimeMillis() + 3000;
while (handler.message == null && System.currentTimeMillis() < theFuture) { while (handler.message == null && System.currentTimeMillis() < theFuture) {
try { try {
@ -127,7 +127,7 @@ public class SpdyFrameDecoderTest {
frame.headers().add(headerName.toString(), headerValue.toString()); frame.headers().add(headerName.toString(), headerValue.toString());
} }
private static class CaptureHandler extends SimpleChannelInboundHandler<Object> { private static class CaptureHandler extends ChannelInboundHandlerAdapter {
public volatile Object message; public volatile Object message;
@Override @Override

View File

@ -17,8 +17,6 @@ package io.netty.handler.codec.spdy;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter; import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.MessageList;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.embedded.EmbeddedChannel; import io.netty.channel.embedded.EmbeddedChannel;
import io.netty.util.internal.logging.InternalLogger; import io.netty.util.internal.logging.InternalLogger;
import io.netty.util.internal.logging.InternalLoggerFactory; import io.netty.util.internal.logging.InternalLoggerFactory;
@ -274,7 +272,7 @@ public class SpdySessionHandlerTest {
// Echo Handler opens 4 half-closed streams on session connection // Echo Handler opens 4 half-closed streams on session connection
// and then sets the number of concurrent streams to 3 // and then sets the number of concurrent streams to 3
private static class EchoHandler extends SimpleChannelInboundHandler<Object> { private static class EchoHandler extends ChannelInboundHandlerAdapter {
private final int closeSignal; private final int closeSignal;
private final boolean server; private final boolean server;
@ -290,18 +288,18 @@ public class SpdySessionHandlerTest {
SpdySynStreamFrame spdySynStreamFrame = SpdySynStreamFrame spdySynStreamFrame =
new DefaultSpdySynStreamFrame(streamId, 0, (byte) 0); new DefaultSpdySynStreamFrame(streamId, 0, (byte) 0);
spdySynStreamFrame.setLast(true); spdySynStreamFrame.setLast(true);
ctx.write(spdySynStreamFrame); ctx.write(spdySynStreamFrame).flush();
spdySynStreamFrame.setStreamId(spdySynStreamFrame.getStreamId() + 2); spdySynStreamFrame.setStreamId(spdySynStreamFrame.getStreamId() + 2);
ctx.write(spdySynStreamFrame); ctx.write(spdySynStreamFrame).flush();
spdySynStreamFrame.setStreamId(spdySynStreamFrame.getStreamId() + 2); spdySynStreamFrame.setStreamId(spdySynStreamFrame.getStreamId() + 2);
ctx.write(spdySynStreamFrame); ctx.write(spdySynStreamFrame).flush();
spdySynStreamFrame.setStreamId(spdySynStreamFrame.getStreamId() + 2); spdySynStreamFrame.setStreamId(spdySynStreamFrame.getStreamId() + 2);
ctx.write(spdySynStreamFrame); ctx.write(spdySynStreamFrame).flush();
// Limit the number of concurrent streams to 3 // Limit the number of concurrent streams to 3
SpdySettingsFrame spdySettingsFrame = new DefaultSpdySettingsFrame(); SpdySettingsFrame spdySettingsFrame = new DefaultSpdySettingsFrame();
spdySettingsFrame.setValue(SpdySettingsFrame.SETTINGS_MAX_CONCURRENT_STREAMS, 3); spdySettingsFrame.setValue(SpdySettingsFrame.SETTINGS_MAX_CONCURRENT_STREAMS, 3);
ctx.write(spdySettingsFrame); ctx.write(spdySettingsFrame).flush();
} }
@Override @Override
@ -317,7 +315,7 @@ public class SpdySessionHandlerTest {
spdySynReplyFrame.headers().add(entry.getKey(), entry.getValue()); spdySynReplyFrame.headers().add(entry.getKey(), entry.getValue());
} }
ctx.write(spdySynReplyFrame); ctx.write(spdySynReplyFrame).flush();
} }
return; return;
} }
@ -330,7 +328,7 @@ public class SpdySessionHandlerTest {
msg instanceof SpdyPingFrame || msg instanceof SpdyPingFrame ||
msg instanceof SpdyHeadersFrame) { msg instanceof SpdyHeadersFrame) {
ctx.write(msg); ctx.write(msg).flush();
return; return;
} }

View File

@ -17,10 +17,11 @@ package io.netty.handler.codec.socks;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.MessageList;
import io.netty.handler.codec.ReplayingDecoder; import io.netty.handler.codec.ReplayingDecoder;
import io.netty.util.CharsetUtil; import io.netty.util.CharsetUtil;
import java.util.List;
/** /**
* Decodes {@link ByteBuf}s into {@link SocksAuthRequest}. * Decodes {@link ByteBuf}s into {@link SocksAuthRequest}.
* Before returning SocksRequest decoder removes itself from pipeline. * Before returning SocksRequest decoder removes itself from pipeline.
@ -43,7 +44,7 @@ public class SocksAuthRequestDecoder extends ReplayingDecoder<SocksAuthRequestDe
} }
@Override @Override
protected void decode(ChannelHandlerContext ctx, ByteBuf byteBuf, MessageList<Object> out) throws Exception { protected void decode(ChannelHandlerContext ctx, ByteBuf byteBuf, List<Object> out) throws Exception {
switch (state()) { switch (state()) {
case CHECK_PROTOCOL_VERSION: { case CHECK_PROTOCOL_VERSION: {
version = SocksSubnegotiationVersion.fromByte(byteBuf.readByte()); version = SocksSubnegotiationVersion.fromByte(byteBuf.readByte());

View File

@ -17,9 +17,10 @@ package io.netty.handler.codec.socks;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.MessageList;
import io.netty.handler.codec.ReplayingDecoder; import io.netty.handler.codec.ReplayingDecoder;
import java.util.List;
/** /**
* Decodes {@link ByteBuf}s into {@link SocksAuthResponse}. * Decodes {@link ByteBuf}s into {@link SocksAuthResponse}.
* Before returning SocksResponse decoder removes itself from pipeline. * Before returning SocksResponse decoder removes itself from pipeline.
@ -40,7 +41,7 @@ public class SocksAuthResponseDecoder extends ReplayingDecoder<SocksAuthResponse
} }
@Override @Override
protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf, MessageList<Object> out) protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf, List<Object> out)
throws Exception { throws Exception {
switch (state()) { switch (state()) {
case CHECK_PROTOCOL_VERSION: { case CHECK_PROTOCOL_VERSION: {

View File

@ -17,10 +17,11 @@ package io.netty.handler.codec.socks;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.MessageList;
import io.netty.handler.codec.ReplayingDecoder; import io.netty.handler.codec.ReplayingDecoder;
import io.netty.util.CharsetUtil; import io.netty.util.CharsetUtil;
import java.util.List;
/** /**
* Decodes {@link ByteBuf}s into {@link SocksCmdRequest}. * Decodes {@link ByteBuf}s into {@link SocksCmdRequest}.
* Before returning SocksRequest decoder removes itself from pipeline. * Before returning SocksRequest decoder removes itself from pipeline.
@ -46,7 +47,7 @@ public class SocksCmdRequestDecoder extends ReplayingDecoder<SocksCmdRequestDeco
} }
@Override @Override
protected void decode(ChannelHandlerContext ctx, ByteBuf byteBuf, MessageList<Object> out) throws Exception { protected void decode(ChannelHandlerContext ctx, ByteBuf byteBuf, List<Object> out) throws Exception {
switch (state()) { switch (state()) {
case CHECK_PROTOCOL_VERSION: { case CHECK_PROTOCOL_VERSION: {
version = SocksProtocolVersion.fromByte(byteBuf.readByte()); version = SocksProtocolVersion.fromByte(byteBuf.readByte());

View File

@ -17,10 +17,11 @@ package io.netty.handler.codec.socks;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.MessageList;
import io.netty.handler.codec.ReplayingDecoder; import io.netty.handler.codec.ReplayingDecoder;
import io.netty.util.CharsetUtil; import io.netty.util.CharsetUtil;
import java.util.List;
/** /**
* Decodes {@link ByteBuf}s into {@link SocksCmdResponse}. * Decodes {@link ByteBuf}s into {@link SocksCmdResponse}.
* Before returning SocksResponse decoder removes itself from pipeline. * Before returning SocksResponse decoder removes itself from pipeline.
@ -46,7 +47,7 @@ public class SocksCmdResponseDecoder extends ReplayingDecoder<SocksCmdResponseDe
} }
@Override @Override
protected void decode(ChannelHandlerContext ctx, ByteBuf byteBuf, MessageList<Object> out) throws Exception { protected void decode(ChannelHandlerContext ctx, ByteBuf byteBuf, List<Object> out) throws Exception {
switch (state()) { switch (state()) {
case CHECK_PROTOCOL_VERSION: { case CHECK_PROTOCOL_VERSION: {
version = SocksProtocolVersion.fromByte(byteBuf.readByte()); version = SocksProtocolVersion.fromByte(byteBuf.readByte());

View File

@ -17,7 +17,6 @@ package io.netty.handler.codec.socks;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.MessageList;
import io.netty.handler.codec.ReplayingDecoder; import io.netty.handler.codec.ReplayingDecoder;
import java.util.ArrayList; import java.util.ArrayList;
@ -44,7 +43,7 @@ public class SocksInitRequestDecoder extends ReplayingDecoder<SocksInitRequestDe
} }
@Override @Override
protected void decode(ChannelHandlerContext ctx, ByteBuf byteBuf, MessageList<Object> out) throws Exception { protected void decode(ChannelHandlerContext ctx, ByteBuf byteBuf, List<Object> out) throws Exception {
switch (state()) { switch (state()) {
case CHECK_PROTOCOL_VERSION: { case CHECK_PROTOCOL_VERSION: {
version = SocksProtocolVersion.fromByte(byteBuf.readByte()); version = SocksProtocolVersion.fromByte(byteBuf.readByte());

View File

@ -17,9 +17,10 @@ package io.netty.handler.codec.socks;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.MessageList;
import io.netty.handler.codec.ReplayingDecoder; import io.netty.handler.codec.ReplayingDecoder;
import java.util.List;
/** /**
* Decodes {@link ByteBuf}s into {@link SocksInitResponse}. * Decodes {@link ByteBuf}s into {@link SocksInitResponse}.
* Before returning SocksResponse decoder removes itself from pipeline. * Before returning SocksResponse decoder removes itself from pipeline.
@ -41,7 +42,7 @@ public class SocksInitResponseDecoder extends ReplayingDecoder<SocksInitResponse
} }
@Override @Override
protected void decode(ChannelHandlerContext ctx, ByteBuf byteBuf, MessageList<Object> out) throws Exception { protected void decode(ChannelHandlerContext ctx, ByteBuf byteBuf, List<Object> out) throws Exception {
switch (state()) { switch (state()) {
case CHECK_PROTOCOL_VERSION: { case CHECK_PROTOCOL_VERSION: {
version = SocksProtocolVersion.fromByte(byteBuf.readByte()); version = SocksProtocolVersion.fromByte(byteBuf.readByte());

View File

@ -18,10 +18,10 @@ package io.netty.handler.codec;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelDuplexHandler; import io.netty.channel.ChannelDuplexHandler;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelPromise;
import io.netty.channel.MessageList;
import io.netty.util.internal.TypeParameterMatcher; 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. * A Codec for on-the-fly encoding/decoding of bytes to messages and vise-versa.
* *
@ -47,12 +47,12 @@ public abstract class ByteToMessageCodec<I> extends ChannelDuplexHandler {
private final ByteToMessageDecoder decoder = new ByteToMessageDecoder() { private final ByteToMessageDecoder decoder = new ByteToMessageDecoder() {
@Override @Override
public void decode(ChannelHandlerContext ctx, ByteBuf in, MessageList<Object> out) throws Exception { public void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
ByteToMessageCodec.this.decode(ctx, in, out); ByteToMessageCodec.this.decode(ctx, in, out);
} }
@Override @Override
protected void decodeLast(ChannelHandlerContext ctx, ByteBuf in, MessageList<Object> out) throws Exception { protected void decodeLast(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
ByteToMessageCodec.this.decodeLast(ctx, in, out); ByteToMessageCodec.this.decodeLast(ctx, in, out);
} }
}; };
@ -78,13 +78,13 @@ public abstract class ByteToMessageCodec<I> extends ChannelDuplexHandler {
} }
@Override @Override
public void messageReceived(ChannelHandlerContext ctx, MessageList<Object> msgs) throws Exception { public void messageReceived(ChannelHandlerContext ctx, Object msg) throws Exception {
decoder.messageReceived(ctx, msgs); decoder.messageReceived(ctx, msg);
} }
@Override @Override
public void write(ChannelHandlerContext ctx, MessageList<Object> msgs, ChannelPromise promise) throws Exception { public void write(ChannelHandlerContext ctx, Object msg) throws Exception {
encoder.write(ctx, msgs, promise); encoder.write(ctx, msg);
} }
/** /**
@ -93,14 +93,14 @@ public abstract class ByteToMessageCodec<I> extends ChannelDuplexHandler {
protected abstract void encode(ChannelHandlerContext ctx, I msg, ByteBuf out) throws Exception; protected abstract void encode(ChannelHandlerContext ctx, I msg, ByteBuf out) throws Exception;
/** /**
* @see ByteToMessageDecoder#decode(ChannelHandlerContext, ByteBuf, MessageList) * @see ByteToMessageDecoder#decode(ChannelHandlerContext, ByteBuf, List)
*/ */
protected abstract void decode(ChannelHandlerContext ctx, ByteBuf in, MessageList<Object> out) throws Exception; protected abstract void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception;
/** /**
* @see ByteToMessageDecoder#decodeLast(ChannelHandlerContext, ByteBuf, MessageList) * @see ByteToMessageDecoder#decodeLast(ChannelHandlerContext, ByteBuf, List)
*/ */
protected void decodeLast(ChannelHandlerContext ctx, ByteBuf in, MessageList<Object> out) throws Exception { protected void decodeLast(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
decode(ctx, in, out); decode(ctx, in, out);
} }
} }

View File

@ -19,9 +19,10 @@ import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled; import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter; import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.MessageList;
import io.netty.util.internal.StringUtil; import io.netty.util.internal.StringUtil;
import java.util.List;
/** /**
* {@link ChannelInboundHandlerAdapter} which decodes bytes in a stream-like fashion from one {@link ByteBuf} to an * {@link ChannelInboundHandlerAdapter} which decodes bytes in a stream-like fashion from one {@link ByteBuf} to an
* other Message type. * other Message type.
@ -32,7 +33,7 @@ import io.netty.util.internal.StringUtil;
* <pre> * <pre>
* public class SquareDecoder extends {@link ByteToMessageDecoder} { * public class SquareDecoder extends {@link ByteToMessageDecoder} {
* {@code @Override} * {@code @Override}
* public void decode({@link ChannelHandlerContext} ctx, {@link ByteBuf} in, {@link MessageList} out) * public void decode({@link ChannelHandlerContext} ctx, {@link ByteBuf} in, List&lt;Object&gt; out)
* throws {@link Exception} { * throws {@link Exception} {
* out.add(in.readBytes(in.readableBytes())); * out.add(in.readBytes(in.readableBytes()));
* } * }
@ -47,7 +48,6 @@ public abstract class ByteToMessageDecoder extends ChannelInboundHandlerAdapter
protected ByteBuf cumulation; protected ByteBuf cumulation;
private boolean singleDecode; private boolean singleDecode;
private boolean decodeWasNull; private boolean decodeWasNull;
private MessageList<Object> out;
protected ByteToMessageDecoder() { protected ByteToMessageDecoder() {
if (getClass().isAnnotationPresent(Sharable.class)) { if (getClass().isAnnotationPresent(Sharable.class)) {
@ -56,7 +56,7 @@ public abstract class ByteToMessageDecoder extends ChannelInboundHandlerAdapter
} }
/** /**
* If set then only one message is decoded on each {@link #messageReceived(ChannelHandlerContext, MessageList)} * If set then only one message is decoded on each {@link #messageReceived(ChannelHandlerContext, Object)}
* call. This may be useful if you need to do some protocol upgrade and want to make sure nothing is mixed up. * call. This may be useful if you need to do some protocol upgrade and want to make sure nothing is mixed up.
* *
* Default is {@code false} as this has performance impacts. * Default is {@code false} as this has performance impacts.
@ -67,7 +67,7 @@ public abstract class ByteToMessageDecoder extends ChannelInboundHandlerAdapter
/** /**
* If {@code true} then only one message is decoded on each * If {@code true} then only one message is decoded on each
* {@link #messageReceived(ChannelHandlerContext, MessageList)} call. * {@link #messageReceived(ChannelHandlerContext, Object)} call.
* *
* Default is {@code false} as this has performance impacts. * Default is {@code false} as this has performance impacts.
*/ */
@ -102,13 +102,9 @@ public abstract class ByteToMessageDecoder extends ChannelInboundHandlerAdapter
public final void handlerRemoved(ChannelHandlerContext ctx) throws Exception { public final void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
ByteBuf buf = internalBuffer(); ByteBuf buf = internalBuffer();
if (buf.isReadable()) { if (buf.isReadable()) {
if (out == null) { ctx.fireMessageReceived(buf);
ctx.fireMessageReceived(buf);
} else {
out.add(buf.copy());
}
buf.clear();
} }
ctx.fireMessageReceivedLast();
handlerRemoved0(ctx); handlerRemoved0(ctx);
} }
@ -119,72 +115,58 @@ public abstract class ByteToMessageDecoder extends ChannelInboundHandlerAdapter
protected void handlerRemoved0(ChannelHandlerContext ctx) throws Exception { } protected void handlerRemoved0(ChannelHandlerContext ctx) throws Exception { }
@Override @Override
public void messageReceived(ChannelHandlerContext ctx, MessageList<Object> msgs) throws Exception { public void messageReceived(ChannelHandlerContext ctx, Object msg) throws Exception {
out = MessageList.newInstance(); CodecOutput out = CodecOutput.newInstance();
try { try {
int size = msgs.size(); if (msg instanceof ByteBuf) {
for (int i = 0; i < size; i ++) { ByteBuf data = (ByteBuf) msg;
Object m = msgs.get(i); if (cumulation == null) {
// handler was removed in the loop so now copy over all remaining messages cumulation = data;
if (ctx.isRemoved()) { try {
out.add(msgs, i, size - i); callDecode(ctx, data, out);
return; } finally {
} if (!data.isReadable()) {
if (m instanceof ByteBuf) { cumulation = null;
ByteBuf data = (ByteBuf) m;
if (cumulation == null) {
cumulation = data;
try {
callDecode(ctx, data, out);
} finally {
if (!data.isReadable()) {
cumulation = null;
data.release();
}
}
} else {
try {
if (cumulation.writerIndex() > cumulation.maxCapacity() - data.readableBytes()) {
ByteBuf oldCumulation = cumulation;
cumulation = ctx.alloc().buffer(oldCumulation.readableBytes() + data.readableBytes());
cumulation.writeBytes(oldCumulation);
oldCumulation.release();
}
cumulation.writeBytes(data);
callDecode(ctx, cumulation, out);
} finally {
if (!cumulation.isReadable()) {
cumulation.release();
cumulation = null;
} else {
cumulation.discardSomeReadBytes();
}
data.release(); data.release();
} }
} }
} else { } else {
out.add(m); try {
if (cumulation.writerIndex() > cumulation.maxCapacity() - data.readableBytes()) {
ByteBuf oldCumulation = cumulation;
cumulation = ctx.alloc().buffer(oldCumulation.readableBytes() + data.readableBytes());
cumulation.writeBytes(oldCumulation);
oldCumulation.release();
}
cumulation.writeBytes(data);
callDecode(ctx, cumulation, out);
} finally {
if (!cumulation.isReadable()) {
cumulation.release();
cumulation = null;
} else {
cumulation.discardSomeReadBytes();
}
data.release();
}
} }
} else {
out.add(msg);
} }
} catch (DecoderException e) { } catch (DecoderException e) {
throw e; throw e;
} catch (Throwable t) { } catch (Throwable t) {
throw new DecoderException(t); throw new DecoderException(t);
} finally { } finally {
// release the cumulation if the handler was removed while messages are processed
if (ctx.isRemoved()) {
if (cumulation != null) {
cumulation.release();
cumulation = null;
}
}
MessageList<Object> out = this.out;
this.out = null;
if (out.isEmpty()) { if (out.isEmpty()) {
decodeWasNull = true; decodeWasNull = true;
} }
msgs.recycle();
ctx.fireMessageReceived(out); for (int i = 0; i < out.size(); i ++) {
ctx.fireMessageReceived(out.get(i));
}
out.recycle();
} }
} }
@ -201,7 +183,7 @@ public abstract class ByteToMessageDecoder extends ChannelInboundHandlerAdapter
@Override @Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception { public void channelInactive(ChannelHandlerContext ctx) throws Exception {
MessageList<Object> out = MessageList.newInstance(); CodecOutput out = CodecOutput.newInstance();
try { try {
if (cumulation != null) { if (cumulation != null) {
callDecode(ctx, cumulation, out); callDecode(ctx, cumulation, out);
@ -219,12 +201,14 @@ public abstract class ByteToMessageDecoder extends ChannelInboundHandlerAdapter
cumulation = null; cumulation = null;
} }
ctx.fireMessageReceived(out); for (int i = 0; i < out.size(); i ++) {
ctx.fireMessageReceived(out.get(i));
}
ctx.fireChannelInactive(); ctx.fireChannelInactive();
} }
} }
protected void callDecode(ChannelHandlerContext ctx, ByteBuf in, MessageList<Object> out) { protected void callDecode(ChannelHandlerContext ctx, ByteBuf in, CodecOutput out) {
try { try {
while (in.isReadable()) { while (in.isReadable()) {
int outSize = out.size(); int outSize = out.size();
@ -262,20 +246,20 @@ public abstract class ByteToMessageDecoder extends ChannelInboundHandlerAdapter
* *
* @param ctx the {@link ChannelHandlerContext} which this {@link ByteToMessageDecoder} belongs to * @param ctx the {@link ChannelHandlerContext} which this {@link ByteToMessageDecoder} belongs to
* @param in the {@link ByteBuf} from which to read data * @param in the {@link ByteBuf} from which to read data
* @param out the {@link MessageList} to which decoded messages should be added * @param out the {@link CodecOutput} to which decoded messages should be added
* @throws Exception is thrown if an error accour * @throws Exception is thrown if an error accour
*/ */
protected abstract void decode(ChannelHandlerContext ctx, ByteBuf in, MessageList<Object> out) throws Exception; protected abstract void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception;
/** /**
* Is called one last time when the {@link ChannelHandlerContext} goes in-active. Which means the * Is called one last time when the {@link ChannelHandlerContext} goes in-active. Which means the
* {@link #channelInactive(ChannelHandlerContext)} was triggered. * {@link #channelInactive(ChannelHandlerContext)} was triggered.
* *
* By default this will just call {@link #decode(ChannelHandlerContext, ByteBuf, MessageList)} but sub-classes may * By default this will just call {@link #decode(ChannelHandlerContext, ByteBuf, CodecOutput)} but sub-classes may
* override this for some special cleanup operation. * override this for some special cleanup operation.
*/ */
protected void decodeLast(ChannelHandlerContext ctx, ByteBuf in, MessageList<Object> out) throws Exception { protected void decodeLast(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
decode(ctx, in, out); decode(ctx, in, out);
} }
} }

View File

@ -0,0 +1,74 @@
/*
* Copyright 2013 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;
import io.netty.util.Recycler;
import io.netty.util.Recycler.Handle;
import java.util.ArrayList;
/**
* A simple list that holds the output of a codec.
*/
final class CodecOutput extends ArrayList<Object> {
private static final long serialVersionUID = -8605125654176467947L;
private static final int DEFAULT_INITIAL_CAPACITY = 8;
private static final Recycler<CodecOutput> RECYCLER = new Recycler<CodecOutput>() {
@Override
protected CodecOutput newObject(Handle handle) {
return new CodecOutput(handle);
}
};
/**
* Create a new empty {@link CodecOutput} instance
*/
public static CodecOutput newInstance() {
return newInstance(DEFAULT_INITIAL_CAPACITY);
}
/**
* Create a new empty {@link CodecOutput} instance with the given capacity.
*/
public static CodecOutput newInstance(int minCapacity) {
CodecOutput ret = (CodecOutput) RECYCLER.get();
ret.ensureCapacity(minCapacity);
return ret;
}
private final Handle handle;
CodecOutput(Handle handle) {
this(handle, DEFAULT_INITIAL_CAPACITY);
}
CodecOutput(Handle handle, int initialCapacity) {
super(initialCapacity);
this.handle = handle;
}
/**
* Clear and recycle this instance.
*/
boolean recycle() {
clear();
return RECYCLER.recycle(this, handle);
}
}

View File

@ -17,7 +17,8 @@ package io.netty.handler.codec;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.MessageList;
import java.util.List;
/** /**
* A decoder that splits the received {@link ByteBuf}s by one or more * A decoder that splits the received {@link ByteBuf}s by one or more
@ -211,7 +212,7 @@ public class DelimiterBasedFrameDecoder extends ByteToMessageDecoder {
} }
@Override @Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, MessageList<Object> out) throws Exception { protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
Object decoded = decode(ctx, in); Object decoded = decode(ctx, in);
if (decoded != null) { if (decoded != null) {
out.add(decoded); out.add(decoded);

View File

@ -17,7 +17,8 @@ package io.netty.handler.codec;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.MessageList;
import java.util.List;
/** /**
* A decoder that splits the received {@link ByteBuf}s by the fixed number * A decoder that splits the received {@link ByteBuf}s by the fixed number
@ -53,7 +54,7 @@ public class FixedLengthFrameDecoder extends ByteToMessageDecoder {
} }
@Override @Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, MessageList<Object> out) throws Exception { protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
Object decoded = decode(ctx, in); Object decoded = decode(ctx, in);
if (decoded != null) { if (decoded != null) {
out.add(decoded); out.add(decoded);

View File

@ -18,10 +18,10 @@ package io.netty.handler.codec;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled; import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.MessageList;
import io.netty.handler.codec.serialization.ObjectDecoder; import io.netty.handler.codec.serialization.ObjectDecoder;
import java.nio.ByteOrder; import java.nio.ByteOrder;
import java.util.List;
/** /**
* A decoder that splits the received {@link ByteBuf}s dynamically by the * A decoder that splits the received {@link ByteBuf}s dynamically by the
@ -348,7 +348,7 @@ public class LengthFieldBasedFrameDecoder extends ByteToMessageDecoder {
} }
@Override @Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, MessageList<Object> out) throws Exception { protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
Object decoded = decode(ctx, in); Object decoded = decode(ctx, in);
if (decoded != null) { if (decoded != null) {
out.add(decoded); out.add(decoded);

View File

@ -17,7 +17,8 @@ package io.netty.handler.codec;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.MessageList;
import java.util.List;
/** /**
* A decoder that splits the received {@link ByteBuf}s on line endings. * A decoder that splits the received {@link ByteBuf}s on line endings.
@ -69,7 +70,7 @@ public class LineBasedFrameDecoder extends ByteToMessageDecoder {
} }
@Override @Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, MessageList<Object> out) throws Exception { protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
Object decoded = decode(ctx, in); Object decoded = decode(ctx, in);
if (decoded != null) { if (decoded != null) {
out.add(decoded); out.add(decoded);

View File

@ -18,8 +18,6 @@ package io.netty.handler.codec;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelOutboundHandlerAdapter; import io.netty.channel.ChannelOutboundHandlerAdapter;
import io.netty.channel.ChannelPromise;
import io.netty.channel.MessageList;
import io.netty.util.ReferenceCountUtil; import io.netty.util.ReferenceCountUtil;
import io.netty.util.internal.TypeParameterMatcher; import io.netty.util.internal.TypeParameterMatcher;
@ -69,73 +67,45 @@ public abstract class MessageToByteEncoder<I> extends ChannelOutboundHandlerAdap
} }
@Override @Override
public void write(ChannelHandlerContext ctx, MessageList<Object> msgs, ChannelPromise promise) throws Exception { public void write(ChannelHandlerContext ctx, Object msg) throws Exception {
MessageList<Object> out = MessageList.newInstance();
boolean success = false;
ByteBuf buf = null; ByteBuf buf = null;
try { try {
int size = msgs.size(); if (acceptOutboundMessage(msg)) {
for (int i = 0; i < size; i ++) { @SuppressWarnings("unchecked")
// handler was removed in the loop so now copy over all remaining messages I cast = (I) msg;
if (ctx.isRemoved()) { if (buf == null) {
if (buf != null && buf.isReadable()) { if (preferDirect) {
out.add(buf); buf = ctx.alloc().ioBuffer();
buf = null; } else {
buf = ctx.alloc().heapBuffer();
} }
out.add(msgs, i, size - i);
break;
} }
Object m = msgs.get(i); try {
if (acceptOutboundMessage(m)) { encode(ctx, cast, buf);
@SuppressWarnings("unchecked") } finally {
I cast = (I) m; ReferenceCountUtil.release(cast);
if (buf == null) {
if (preferDirect) {
buf = ctx.alloc().ioBuffer();
} else {
buf = ctx.alloc().heapBuffer();
}
}
try {
encode(ctx, cast, buf);
} finally {
ReferenceCountUtil.release(cast);
}
} else {
if (buf != null && buf.isReadable()) {
out.add(buf);
buf = null;
}
out.add(m);
} }
} else {
ctx.write(msg);
} }
if (buf != null && buf.isReadable()) { if (buf != null && buf.isReadable()) {
out.add(buf); ctx.write(buf);
buf = null; buf = null;
} }
success = true;
} catch (EncoderException e) { } catch (EncoderException e) {
throw e; throw e;
} catch (Throwable e) { } catch (Throwable e) {
throw new EncoderException(e); throw new EncoderException(e);
} finally { } finally {
msgs.recycle();
if (buf != null) { if (buf != null) {
buf.release(); buf.release();
} }
if (success) {
ctx.write(out, promise);
} else {
out.releaseAllAndRecycle();
}
} }
} }
/** /**
* Encode a message into a {@link ByteBuf}. This method will be called till the {@link MessageList} has * Encode a message into a {@link ByteBuf}. This method will be called till the {@link CodecOutput} has
* nothing left. * nothing left.
* *
* @param ctx the {@link ChannelHandlerContext} which this {@link MessageToByteEncoder} belongs to * @param ctx the {@link ChannelHandlerContext} which this {@link MessageToByteEncoder} belongs to

View File

@ -17,11 +17,11 @@ package io.netty.handler.codec;
import io.netty.channel.ChannelDuplexHandler; import io.netty.channel.ChannelDuplexHandler;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelPromise;
import io.netty.channel.MessageList;
import io.netty.util.ReferenceCounted; import io.netty.util.ReferenceCounted;
import io.netty.util.internal.TypeParameterMatcher; import io.netty.util.internal.TypeParameterMatcher;
import java.util.List;
/** /**
* A Codec for on-the-fly encoding/decoding of message. * A Codec for on-the-fly encoding/decoding of message.
* *
@ -62,7 +62,7 @@ public abstract class MessageToMessageCodec<INBOUND_IN, OUTBOUND_IN> extends Cha
@Override @Override
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
protected void encode(ChannelHandlerContext ctx, Object msg, MessageList<Object> out) throws Exception { protected void encode(ChannelHandlerContext ctx, Object msg, List<Object> out) throws Exception {
MessageToMessageCodec.this.encode(ctx, (OUTBOUND_IN) msg, out); MessageToMessageCodec.this.encode(ctx, (OUTBOUND_IN) msg, out);
} }
}; };
@ -76,7 +76,7 @@ public abstract class MessageToMessageCodec<INBOUND_IN, OUTBOUND_IN> extends Cha
@Override @Override
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
protected void decode(ChannelHandlerContext ctx, Object msg, MessageList<Object> out) throws Exception { protected void decode(ChannelHandlerContext ctx, Object msg, List<Object> out) throws Exception {
MessageToMessageCodec.this.decode(ctx, (INBOUND_IN) msg, out); MessageToMessageCodec.this.decode(ctx, (INBOUND_IN) msg, out);
} }
}; };
@ -96,13 +96,13 @@ public abstract class MessageToMessageCodec<INBOUND_IN, OUTBOUND_IN> extends Cha
} }
@Override @Override
public void messageReceived(ChannelHandlerContext ctx, MessageList<Object> msgs) throws Exception { public void messageReceived(ChannelHandlerContext ctx, Object msg) throws Exception {
decoder.messageReceived(ctx, msgs); decoder.messageReceived(ctx, msg);
} }
@Override @Override
public void write(ChannelHandlerContext ctx, MessageList<Object> msgs, ChannelPromise promise) throws Exception { public void write(ChannelHandlerContext ctx, Object msg) throws Exception {
encoder.write(ctx, msgs, promise); encoder.write(ctx, msg);
} }
/** /**
@ -124,14 +124,14 @@ public abstract class MessageToMessageCodec<INBOUND_IN, OUTBOUND_IN> extends Cha
} }
/** /**
* @see MessageToMessageEncoder#encode(ChannelHandlerContext, Object, MessageList) * @see MessageToMessageEncoder#encode(ChannelHandlerContext, Object, CodecOutput)
*/ */
protected abstract void encode(ChannelHandlerContext ctx, OUTBOUND_IN msg, MessageList<Object> out) protected abstract void encode(ChannelHandlerContext ctx, OUTBOUND_IN msg, List<Object> out)
throws Exception; throws Exception;
/** /**
* @see MessageToMessageDecoder#decode(ChannelHandlerContext, Object, MessageList) * @see MessageToMessageDecoder#decode(ChannelHandlerContext, Object, CodecOutput)
*/ */
protected abstract void decode(ChannelHandlerContext ctx, INBOUND_IN msg, MessageList<Object> out) protected abstract void decode(ChannelHandlerContext ctx, INBOUND_IN msg, List<Object> out)
throws Exception; throws Exception;
} }

View File

@ -17,11 +17,12 @@ package io.netty.handler.codec;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter; import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.MessageList;
import io.netty.util.ReferenceCountUtil; import io.netty.util.ReferenceCountUtil;
import io.netty.util.ReferenceCounted; import io.netty.util.ReferenceCounted;
import io.netty.util.internal.TypeParameterMatcher; import io.netty.util.internal.TypeParameterMatcher;
import java.util.List;
/** /**
* {@link ChannelInboundHandlerAdapter} which decodes from one message to an other message. * {@link ChannelInboundHandlerAdapter} which decodes from one message to an other message.
* *
@ -35,7 +36,7 @@ import io.netty.util.internal.TypeParameterMatcher;
* *
* {@code @Override} * {@code @Override}
* public void decode({@link ChannelHandlerContext} ctx, {@link String} message, * public void decode({@link ChannelHandlerContext} ctx, {@link String} message,
* {@link MessageList} out) throws {@link Exception} { * List&lt;Object&gt; out) throws {@link Exception} {
* out.add(message.length()); * out.add(message.length());
* } * }
* } * }
@ -63,48 +64,40 @@ public abstract class MessageToMessageDecoder<I> extends ChannelInboundHandlerAd
} }
@Override @Override
public void messageReceived(ChannelHandlerContext ctx, MessageList<Object> msgs) throws Exception { public void messageReceived(ChannelHandlerContext ctx, Object msg) throws Exception {
MessageList<Object> out = MessageList.newInstance(); CodecOutput out = CodecOutput.newInstance();
try { try {
int size = msgs.size(); if (acceptInboundMessage(msg)) {
for (int i = 0; i < size; i ++) { @SuppressWarnings("unchecked")
// handler was removed in the loop so now copy over all remaining messages I cast = (I) msg;
if (ctx.isRemoved()) { try {
out.add(msgs, i, size - i); decode(ctx, cast, out);
return; } finally {
} ReferenceCountUtil.release(cast);
Object m = msgs.get(i);
if (acceptInboundMessage(m)) {
@SuppressWarnings("unchecked")
I cast = (I) m;
try {
decode(ctx, cast, out);
} finally {
ReferenceCountUtil.release(cast);
}
} else {
out.add(m);
} }
} else {
out.add(msg);
} }
} catch (DecoderException e) { } catch (DecoderException e) {
throw e; throw e;
} catch (Exception e) { } catch (Exception e) {
throw new DecoderException(e); throw new DecoderException(e);
} finally { } finally {
msgs.recycle(); for (int i = 0; i < out.size(); i ++) {
ctx.fireMessageReceived(out); ctx.fireMessageReceived(out.get(i));
}
out.recycle();
} }
} }
/** /**
* Decode from one message to an other. This method will be called till either the {@link MessageList} has * Decode from one message to an other. This method will be called till either the {@link CodecOutput} has
* nothing left or till this method returns {@code null}. * nothing left or till this method returns {@code null}.
* *
* @param ctx the {@link ChannelHandlerContext} which this {@link MessageToMessageDecoder} belongs to * @param ctx the {@link ChannelHandlerContext} which this {@link MessageToMessageDecoder} belongs to
* @param msg the message to decode to an other one * @param msg the message to decode to an other one
* @param out the {@link MessageList} to which decoded messages should be added * @param out the {@link CodecOutput} to which decoded messages should be added
* @throws Exception is thrown if an error accour * @throws Exception is thrown if an error accour
*/ */
protected abstract void decode(ChannelHandlerContext ctx, I msg, MessageList<Object> out) throws Exception; protected abstract void decode(ChannelHandlerContext ctx, I msg, List<Object> out) throws Exception;
} }

View File

@ -17,12 +17,12 @@ package io.netty.handler.codec;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelOutboundHandlerAdapter; import io.netty.channel.ChannelOutboundHandlerAdapter;
import io.netty.channel.ChannelPromise;
import io.netty.channel.MessageList;
import io.netty.util.ReferenceCountUtil; import io.netty.util.ReferenceCountUtil;
import io.netty.util.ReferenceCounted; import io.netty.util.ReferenceCounted;
import io.netty.util.internal.TypeParameterMatcher; import io.netty.util.internal.TypeParameterMatcher;
import java.util.List;
/** /**
* {@link ChannelOutboundHandlerAdapter} which encodes from one message to an other message * {@link ChannelOutboundHandlerAdapter} which encodes from one message to an other message
* *
@ -33,7 +33,7 @@ import io.netty.util.internal.TypeParameterMatcher;
* {@link MessageToMessageEncoder}&lt;{@link Integer}&gt; { * {@link MessageToMessageEncoder}&lt;{@link Integer}&gt; {
* *
* {@code @Override} * {@code @Override}
* public void encode({@link ChannelHandlerContext} ctx, {@link Integer} message, {@link MessageList} out) * public void encode({@link ChannelHandlerContext} ctx, {@link Integer} message, List&lt;Object&gt; out)
* throws {@link Exception} { * throws {@link Exception} {
* out.add(message.toString()); * out.add(message.toString());
* } * }
@ -61,54 +61,41 @@ public abstract class MessageToMessageEncoder<I> extends ChannelOutboundHandlerA
} }
@Override @Override
public void write(ChannelHandlerContext ctx, MessageList<Object> msgs, ChannelPromise promise) throws Exception { public void write(ChannelHandlerContext ctx, Object msg) throws Exception {
MessageList<Object> out = MessageList.newInstance(); CodecOutput out = CodecOutput.newInstance();
boolean success = false;
try { try {
int size = msgs.size(); if (acceptOutboundMessage(msg)) {
for (int i = 0; i < size; i ++) { @SuppressWarnings("unchecked")
// handler was removed in the loop so now copy over all remaining messages I cast = (I) msg;
if (ctx.isRemoved()) { try {
out.add(msgs, i, size - i); encode(ctx, cast, out);
break; } finally {
} ReferenceCountUtil.release(cast);
Object m = msgs.get(i);
if (acceptOutboundMessage(m)) {
@SuppressWarnings("unchecked")
I cast = (I) m;
try {
encode(ctx, cast, out);
} finally {
ReferenceCountUtil.release(cast);
}
} else {
out.add(m);
} }
} else {
out.add(msg);
} }
success = true; } catch (EncoderException e) {
} catch (CodecException e) {
throw e; throw e;
} catch (Throwable t) { } catch (Throwable t) {
throw new EncoderException(t); throw new EncoderException(t);
} finally { } finally {
msgs.recycle(); for (int i = 0; i < out.size(); i ++) {
if (success) { ctx.write(out.get(i));
ctx.write(out, promise);
} else {
out.releaseAllAndRecycle();
} }
out.recycle();
} }
} }
/** /**
* Encode from one message to an other. This method will be called till either the {@link MessageList} has nothing * Encode from one message to an other. This method will be called till either the {@link CodecOutput} has nothing
* left or till this method returns {@code null}. * left or till this method returns {@code null}.
* *
* @param ctx the {@link ChannelHandlerContext} which this {@link MessageToMessageEncoder} belongs to * @param ctx the {@link ChannelHandlerContext} which this {@link MessageToMessageEncoder} belongs to
* @param msg the message to encode to an other one * @param msg the message to encode to an other one
* @param out the {@link MessageList} into which the encoded msg should be added * @param out the {@link CodecOutput} into which the encoded msg should be added
* needs to do some kind of aggragation * needs to do some kind of aggragation
* @throws Exception is thrown if an error accour * @throws Exception is thrown if an error accour
*/ */
protected abstract void encode(ChannelHandlerContext ctx, I msg, MessageList<Object> out) throws Exception; protected abstract void encode(ChannelHandlerContext ctx, I msg, List<Object> out) throws Exception;
} }

View File

@ -19,7 +19,6 @@ import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandler; import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelPipeline; import io.netty.channel.ChannelPipeline;
import io.netty.channel.MessageList;
import io.netty.util.Signal; import io.netty.util.Signal;
import io.netty.util.internal.StringUtil; import io.netty.util.internal.StringUtil;
@ -106,7 +105,7 @@ import io.netty.util.internal.StringUtil;
* private final Queue&lt;Integer&gt; values = new LinkedList&lt;Integer&gt;(); * private final Queue&lt;Integer&gt; values = new LinkedList&lt;Integer&gt;();
* *
* {@code @Override} * {@code @Override}
* public void decode(.., {@link ByteBuf} in, {@link MessageList} out) throws Exception { * public void decode(.., {@link ByteBuf} in, List&lt;Object&gt; out) throws Exception {
* *
* // A message contains 2 integers. * // A message contains 2 integers.
* values.offer(buffer.readInt()); * values.offer(buffer.readInt());
@ -126,7 +125,7 @@ import io.netty.util.internal.StringUtil;
* private final Queue&lt;Integer&gt; values = new LinkedList&lt;Integer&gt;(); * private final Queue&lt;Integer&gt; values = new LinkedList&lt;Integer&gt;();
* *
* {@code @Override} * {@code @Override}
* public void decode(.., {@link ByteBuf} buffer, {@link MessageList} out) throws Exception { * public void decode(.., {@link ByteBuf} buffer, List&lt;Object&gt; out) throws Exception {
* *
* // Revert the state of the variable that might have been changed * // Revert the state of the variable that might have been changed
* // since the last partial decode. * // since the last partial decode.
@ -179,7 +178,7 @@ import io.netty.util.internal.StringUtil;
* *
* {@code @Override} * {@code @Override}
* protected void decode({@link ChannelHandlerContext} ctx, * protected void decode({@link ChannelHandlerContext} ctx,
* {@link ByteBuf} in, {@link MessageList} out) throws Exception { * {@link ByteBuf} in, List&lt;Object&gt; out) throws Exception {
* switch (state()) { * switch (state()) {
* case READ_LENGTH: * case READ_LENGTH:
* length = buf.readInt(); * length = buf.readInt();
@ -207,7 +206,7 @@ import io.netty.util.internal.StringUtil;
* *
* {@code @Override} * {@code @Override}
* protected void decode({@link ChannelHandlerContext} ctx, * protected void decode({@link ChannelHandlerContext} ctx,
* {@link ByteBuf} in, {@link MessageList} out) throws Exception { * {@link ByteBuf} in, List&lt;Object&gt; out) throws Exception {
* if (!readLength) { * if (!readLength) {
* length = buf.readInt(); * length = buf.readInt();
* <strong>readLength = true;</strong> * <strong>readLength = true;</strong>
@ -238,7 +237,7 @@ import io.netty.util.internal.StringUtil;
* *
* {@code @Override} * {@code @Override}
* protected Object decode({@link ChannelHandlerContext} ctx, * protected Object decode({@link ChannelHandlerContext} ctx,
* {@link ByteBuf} in, {@link MessageList} out) { * {@link ByteBuf} in, List&lt;Object&gt; out) {
* ... * ...
* // Decode the first message * // Decode the first message
* Object firstMessage = ...; * Object firstMessage = ...;
@ -320,7 +319,7 @@ public abstract class ReplayingDecoder<S> extends ByteToMessageDecoder {
@Override @Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception { public void channelInactive(ChannelHandlerContext ctx) throws Exception {
MessageList<Object> out = MessageList.newInstance(); CodecOutput out = CodecOutput.newInstance();
try { try {
replayable.terminate(); replayable.terminate();
callDecode(ctx, internalBuffer(), out); callDecode(ctx, internalBuffer(), out);
@ -338,13 +337,15 @@ public abstract class ReplayingDecoder<S> extends ByteToMessageDecoder {
cumulation = null; cumulation = null;
} }
ctx.fireMessageReceived(out); for (int i = 0; i < out.size(); i ++) {
ctx.fireMessageReceived(out.get(i));
}
ctx.fireChannelInactive(); ctx.fireChannelInactive();
} }
} }
@Override @Override
protected void callDecode(ChannelHandlerContext ctx, ByteBuf in, MessageList<Object> out) { protected void callDecode(ChannelHandlerContext ctx, ByteBuf in, CodecOutput out) {
replayable.setCumulation(in); replayable.setCumulation(in);
try { try {
while (in.isReadable()) { while (in.isReadable()) {

View File

@ -19,12 +19,13 @@ import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandler.Sharable; import io.netty.channel.ChannelHandler.Sharable;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelPipeline; import io.netty.channel.ChannelPipeline;
import io.netty.channel.MessageList;
import io.netty.handler.codec.ByteToMessageDecoder; import io.netty.handler.codec.ByteToMessageDecoder;
import io.netty.handler.codec.DelimiterBasedFrameDecoder; import io.netty.handler.codec.DelimiterBasedFrameDecoder;
import io.netty.handler.codec.Delimiters; import io.netty.handler.codec.Delimiters;
import io.netty.handler.codec.MessageToMessageDecoder; import io.netty.handler.codec.MessageToMessageDecoder;
import java.util.List;
/** /**
* Decodes a Base64-encoded {@link ByteBuf} or US-ASCII {@link String} * Decodes a Base64-encoded {@link ByteBuf} or US-ASCII {@link String}
* into a {@link ByteBuf}. Please note that this decoder must be used * into a {@link ByteBuf}. Please note that this decoder must be used
@ -59,7 +60,7 @@ public class Base64Decoder extends MessageToMessageDecoder<ByteBuf> {
} }
@Override @Override
protected void decode(ChannelHandlerContext ctx, ByteBuf msg, MessageList<Object> out) throws Exception { protected void decode(ChannelHandlerContext ctx, ByteBuf msg, List<Object> out) throws Exception {
out.add(Base64.decode(msg, msg.readerIndex(), msg.readableBytes(), dialect)); out.add(Base64.decode(msg, msg.readerIndex(), msg.readableBytes(), dialect));
} }
} }

View File

@ -19,11 +19,12 @@ import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandler.Sharable; import io.netty.channel.ChannelHandler.Sharable;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelPipeline; import io.netty.channel.ChannelPipeline;
import io.netty.channel.MessageList;
import io.netty.handler.codec.DelimiterBasedFrameDecoder; import io.netty.handler.codec.DelimiterBasedFrameDecoder;
import io.netty.handler.codec.Delimiters; import io.netty.handler.codec.Delimiters;
import io.netty.handler.codec.MessageToMessageEncoder; import io.netty.handler.codec.MessageToMessageEncoder;
import java.util.List;
/** /**
* Encodes a {@link ByteBuf} into a Base64-encoded {@link ByteBuf}. * Encodes a {@link ByteBuf} into a Base64-encoded {@link ByteBuf}.
* A typical setup for TCP/IP would be: * A typical setup for TCP/IP would be:
@ -62,7 +63,7 @@ public class Base64Encoder extends MessageToMessageEncoder<ByteBuf> {
} }
@Override @Override
protected void encode(ChannelHandlerContext ctx, ByteBuf msg, MessageList<Object> out) throws Exception { protected void encode(ChannelHandlerContext ctx, ByteBuf msg, List<Object> out) throws Exception {
out.add(Base64.encode(msg, msg.readerIndex(), msg.readableBytes(), breakLines, dialect)); out.add(Base64.encode(msg, msg.readerIndex(), msg.readableBytes(), breakLines, dialect));
} }
} }

View File

@ -18,11 +18,12 @@ package io.netty.handler.codec.bytes;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelPipeline; import io.netty.channel.ChannelPipeline;
import io.netty.channel.MessageList;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.handler.codec.LengthFieldPrepender; import io.netty.handler.codec.LengthFieldPrepender;
import io.netty.handler.codec.MessageToMessageDecoder; import io.netty.handler.codec.MessageToMessageDecoder;
import java.util.List;
/** /**
* Decodes a received {@link ByteBuf} into an array of bytes. * Decodes a received {@link ByteBuf} into an array of bytes.
* A typical setup for TCP/IP would be: * A typical setup for TCP/IP would be:
@ -49,7 +50,7 @@ import io.netty.handler.codec.MessageToMessageDecoder;
*/ */
public class ByteArrayDecoder extends MessageToMessageDecoder<ByteBuf> { public class ByteArrayDecoder extends MessageToMessageDecoder<ByteBuf> {
@Override @Override
protected void decode(ChannelHandlerContext ctx, ByteBuf msg, MessageList<Object> out) throws Exception { protected void decode(ChannelHandlerContext ctx, ByteBuf msg, List<Object> out) throws Exception {
byte[] array; byte[] array;
if (msg.hasArray()) { if (msg.hasArray()) {
if (msg.arrayOffset() == 0 && msg.readableBytes() == msg.capacity()) { if (msg.arrayOffset() == 0 && msg.readableBytes() == msg.capacity()) {

View File

@ -20,11 +20,12 @@ import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandler.Sharable; import io.netty.channel.ChannelHandler.Sharable;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelPipeline; import io.netty.channel.ChannelPipeline;
import io.netty.channel.MessageList;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.handler.codec.LengthFieldPrepender; import io.netty.handler.codec.LengthFieldPrepender;
import io.netty.handler.codec.MessageToMessageEncoder; import io.netty.handler.codec.MessageToMessageEncoder;
import java.util.List;
/** /**
* Encodes the requested array of bytes into a {@link ByteBuf}. * Encodes the requested array of bytes into a {@link ByteBuf}.
* A typical setup for TCP/IP would be: * A typical setup for TCP/IP would be:
@ -52,7 +53,7 @@ import io.netty.handler.codec.MessageToMessageEncoder;
@Sharable @Sharable
public class ByteArrayEncoder extends MessageToMessageEncoder<byte[]> { public class ByteArrayEncoder extends MessageToMessageEncoder<byte[]> {
@Override @Override
protected void encode(ChannelHandlerContext ctx, byte[] msg, MessageList<Object> out) throws Exception { protected void encode(ChannelHandlerContext ctx, byte[] msg, List<Object> out) throws Exception {
out.add(Unpooled.wrappedBuffer(msg)); out.add(Unpooled.wrappedBuffer(msg));
} }
} }

View File

@ -15,11 +15,13 @@
*/ */
package io.netty.handler.codec.compression; package io.netty.handler.codec.compression;
import com.jcraft.jzlib.Inflater;
import com.jcraft.jzlib.JZlib;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.MessageList;
import java.util.List;
import com.jcraft.jzlib.Inflater;
import com.jcraft.jzlib.JZlib;
public class JZlibDecoder extends ZlibDecoder { public class JZlibDecoder extends ZlibDecoder {
@ -82,7 +84,7 @@ public class JZlibDecoder extends ZlibDecoder {
} }
@Override @Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, MessageList<Object> out) throws Exception { protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
if (!in.isReadable()) { if (!in.isReadable()) {
return; return;

View File

@ -343,10 +343,10 @@ public class JZlibEncoder extends ZlibEncoder {
} }
} }
private ChannelFuture finishEncode(ChannelHandlerContext ctx, ChannelPromise future) { private ChannelFuture finishEncode(ChannelHandlerContext ctx, ChannelPromise promise) {
if (!finished.compareAndSet(false, true)) { if (!finished.compareAndSet(false, true)) {
future.setSuccess(); promise.setSuccess();
return future; return promise;
} }
ByteBuf footer; ByteBuf footer;
@ -366,8 +366,8 @@ public class JZlibEncoder extends ZlibEncoder {
// Write the ADLER32 checksum (stream footer). // Write the ADLER32 checksum (stream footer).
int resultCode = z.deflate(JZlib.Z_FINISH); int resultCode = z.deflate(JZlib.Z_FINISH);
if (resultCode != JZlib.Z_OK && resultCode != JZlib.Z_STREAM_END) { if (resultCode != JZlib.Z_OK && resultCode != JZlib.Z_STREAM_END) {
future.setFailure(ZlibUtil.deflaterException(z, "compression failure", resultCode)); promise.setFailure(ZlibUtil.deflaterException(z, "compression failure", resultCode));
return future; return promise;
} else if (z.next_out_index != 0) { } else if (z.next_out_index != 0) {
footer = Unpooled.wrappedBuffer(out, 0, z.next_out_index); footer = Unpooled.wrappedBuffer(out, 0, z.next_out_index);
} else { } else {
@ -385,8 +385,7 @@ public class JZlibEncoder extends ZlibEncoder {
} }
} }
ctx.write(footer, future); return ctx.write(footer).flush(promise);
return future;
} }
@Override @Override

View File

@ -255,7 +255,7 @@ public class JdkZlibEncoder extends ZlibEncoder {
deflater.end(); deflater.end();
} }
return ctx.write(footer, promise); return ctx.write(footer).flush(promise);
} }
@Override @Override

View File

@ -15,15 +15,14 @@
*/ */
package io.netty.handler.codec.compression; package io.netty.handler.codec.compression;
import static io.netty.handler.codec.compression.Snappy.validateChecksum;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil; import io.netty.buffer.ByteBufUtil;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.MessageList;
import io.netty.handler.codec.ByteToMessageDecoder; import io.netty.handler.codec.ByteToMessageDecoder;
import java.util.Arrays; import java.util.Arrays;
import java.util.List;
import static io.netty.handler.codec.compression.Snappy.*;
/** /**
* Uncompresses a {@link ByteBuf} encoded with the Snappy framing format. * Uncompresses a {@link ByteBuf} encoded with the Snappy framing format.
@ -76,7 +75,7 @@ public class SnappyFramedDecoder extends ByteToMessageDecoder {
} }
@Override @Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, MessageList<Object> out) throws Exception { protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
if (corrupted) { if (corrupted) {
in.skipBytes(in.readableBytes()); in.skipBytes(in.readableBytes());
return; return;

View File

@ -18,13 +18,14 @@ package io.netty.handler.codec.marshalling;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.channel.Channel; import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.MessageList;
import io.netty.handler.codec.ReplayingDecoder; import io.netty.handler.codec.ReplayingDecoder;
import io.netty.handler.codec.TooLongFrameException; import io.netty.handler.codec.TooLongFrameException;
import org.jboss.marshalling.ByteInput;
import org.jboss.marshalling.Unmarshaller;
import java.io.ObjectStreamConstants; import java.io.ObjectStreamConstants;
import java.util.List;
import org.jboss.marshalling.ByteInput;
import org.jboss.marshalling.Unmarshaller;
/** /**
* {@link ReplayingDecoder} which use an {@link Unmarshaller} to read the Object out of the {@link ByteBuf}. * {@link ReplayingDecoder} which use an {@link Unmarshaller} to read the Object out of the {@link ByteBuf}.
@ -55,7 +56,7 @@ public class CompatibleMarshallingDecoder extends ReplayingDecoder<Void> {
} }
@Override @Override
protected void decode(ChannelHandlerContext ctx, ByteBuf buffer, MessageList<Object> out) throws Exception { protected void decode(ChannelHandlerContext ctx, ByteBuf buffer, List<Object> out) throws Exception {
if (discardingTooLongFrame) { if (discardingTooLongFrame) {
buffer.skipBytes(actualReadableBytes()); buffer.skipBytes(actualReadableBytes());
checkpoint(); checkpoint();
@ -83,7 +84,7 @@ public class CompatibleMarshallingDecoder extends ReplayingDecoder<Void> {
} }
@Override @Override
protected void decodeLast(ChannelHandlerContext ctx, ByteBuf buffer, MessageList<Object> out) throws Exception { protected void decodeLast(ChannelHandlerContext ctx, ByteBuf buffer, List<Object> out) throws Exception {
switch (buffer.readableBytes()) { switch (buffer.readableBytes()) {
case 0: case 0:
return; return;

View File

@ -15,19 +15,21 @@
*/ */
package io.netty.handler.codec.protobuf; package io.netty.handler.codec.protobuf;
import com.google.protobuf.ExtensionRegistry;
import com.google.protobuf.Message;
import com.google.protobuf.MessageLite;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandler.Sharable; import io.netty.channel.ChannelHandler.Sharable;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelPipeline; import io.netty.channel.ChannelPipeline;
import io.netty.channel.MessageList;
import io.netty.handler.codec.ByteToMessageDecoder; import io.netty.handler.codec.ByteToMessageDecoder;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.handler.codec.LengthFieldPrepender; import io.netty.handler.codec.LengthFieldPrepender;
import io.netty.handler.codec.MessageToMessageDecoder; import io.netty.handler.codec.MessageToMessageDecoder;
import java.util.List;
import com.google.protobuf.ExtensionRegistry;
import com.google.protobuf.Message;
import com.google.protobuf.MessageLite;
/** /**
* Decodes a received {@link ByteBuf} into a * Decodes a received {@link ByteBuf} into a
* <a href="http://code.google.com/p/protobuf/">Google Protocol Buffers</a> * <a href="http://code.google.com/p/protobuf/">Google Protocol Buffers</a>
@ -95,7 +97,7 @@ public class ProtobufDecoder extends MessageToMessageDecoder<ByteBuf> {
} }
@Override @Override
protected void decode(ChannelHandlerContext ctx, ByteBuf msg, MessageList<Object> out) throws Exception { protected void decode(ChannelHandlerContext ctx, ByteBuf msg, List<Object> out) throws Exception {
final byte[] array; final byte[] array;
final int offset; final int offset;
final int length = msg.readableBytes(); final int length = msg.readableBytes();

View File

@ -15,19 +15,20 @@
*/ */
package io.netty.handler.codec.protobuf; package io.netty.handler.codec.protobuf;
import com.google.protobuf.Message; import static io.netty.buffer.Unpooled.wrappedBuffer;
import com.google.protobuf.MessageLite;
import com.google.protobuf.MessageLiteOrBuilder;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandler.Sharable; import io.netty.channel.ChannelHandler.Sharable;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelPipeline; import io.netty.channel.ChannelPipeline;
import io.netty.channel.MessageList;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.handler.codec.LengthFieldPrepender; import io.netty.handler.codec.LengthFieldPrepender;
import io.netty.handler.codec.MessageToMessageEncoder; import io.netty.handler.codec.MessageToMessageEncoder;
import static io.netty.buffer.Unpooled.*; import java.util.List;
import com.google.protobuf.Message;
import com.google.protobuf.MessageLite;
import com.google.protobuf.MessageLiteOrBuilder;
/** /**
* Encodes the requested <a href="http://code.google.com/p/protobuf/">Google * Encodes the requested <a href="http://code.google.com/p/protobuf/">Google
@ -60,7 +61,7 @@ import static io.netty.buffer.Unpooled.*;
public class ProtobufEncoder extends MessageToMessageEncoder<MessageLiteOrBuilder> { public class ProtobufEncoder extends MessageToMessageEncoder<MessageLiteOrBuilder> {
@Override @Override
protected void encode( protected void encode(
ChannelHandlerContext ctx, MessageLiteOrBuilder msg, MessageList<Object> out) throws Exception { ChannelHandlerContext ctx, MessageLiteOrBuilder msg, List<Object> out) throws Exception {
if (msg instanceof MessageLite) { if (msg instanceof MessageLite) {
out.add(wrappedBuffer(((MessageLite) msg).toByteArray())); out.add(wrappedBuffer(((MessageLite) msg).toByteArray()));
return; return;

View File

@ -15,13 +15,15 @@
*/ */
package io.netty.handler.codec.protobuf; package io.netty.handler.codec.protobuf;
import com.google.protobuf.CodedInputStream;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.MessageList;
import io.netty.handler.codec.ByteToMessageDecoder; import io.netty.handler.codec.ByteToMessageDecoder;
import io.netty.handler.codec.CorruptedFrameException; import io.netty.handler.codec.CorruptedFrameException;
import java.util.List;
import com.google.protobuf.CodedInputStream;
/** /**
* A decoder that splits the received {@link ByteBuf}s dynamically by the * A decoder that splits the received {@link ByteBuf}s dynamically by the
* value of the Google Protocol Buffers * value of the Google Protocol Buffers
@ -43,7 +45,7 @@ public class ProtobufVarint32FrameDecoder extends ByteToMessageDecoder {
// (just like LengthFieldBasedFrameDecoder) // (just like LengthFieldBasedFrameDecoder)
@Override @Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, MessageList<Object> out) throws Exception { protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
in.markReaderIndex(); in.markReaderIndex();
final byte[] buf = new byte[5]; final byte[] buf = new byte[5];
for (int i = 0; i < buf.length; i ++) { for (int i = 0; i < buf.length; i ++) {

View File

@ -19,13 +19,13 @@ import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandler.Sharable; import io.netty.channel.ChannelHandler.Sharable;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelPipeline; import io.netty.channel.ChannelPipeline;
import io.netty.channel.MessageList;
import io.netty.handler.codec.ByteToMessageDecoder; import io.netty.handler.codec.ByteToMessageDecoder;
import io.netty.handler.codec.DelimiterBasedFrameDecoder; import io.netty.handler.codec.DelimiterBasedFrameDecoder;
import io.netty.handler.codec.LineBasedFrameDecoder; import io.netty.handler.codec.LineBasedFrameDecoder;
import io.netty.handler.codec.MessageToMessageDecoder; import io.netty.handler.codec.MessageToMessageDecoder;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.util.List;
/** /**
* Decodes a received {@link ByteBuf} into a {@link String}. Please * Decodes a received {@link ByteBuf} into a {@link String}. Please
@ -75,7 +75,7 @@ public class StringDecoder extends MessageToMessageDecoder<ByteBuf> {
} }
@Override @Override
protected void decode(ChannelHandlerContext ctx, ByteBuf msg, MessageList<Object> out) throws Exception { protected void decode(ChannelHandlerContext ctx, ByteBuf msg, List<Object> out) throws Exception {
out.add(msg.toString(charset)); out.add(msg.toString(charset));
} }
} }

View File

@ -15,15 +15,17 @@
*/ */
package io.netty.handler.codec; package io.netty.handler.codec;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled; import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter; import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.MessageList;
import io.netty.channel.embedded.EmbeddedChannel; import io.netty.channel.embedded.EmbeddedChannel;
import org.junit.Test;
import static org.junit.Assert.*; import java.util.List;
import org.junit.Test;
public class ReplayingDecoderTest { public class ReplayingDecoderTest {
@ -55,7 +57,7 @@ public class ReplayingDecoderTest {
} }
@Override @Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, MessageList<Object> out) { protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) {
ByteBuf msg = in.readBytes(in.bytesBefore((byte) '\n')); ByteBuf msg = in.readBytes(in.bytesBefore((byte) '\n'));
out.add(msg); out.add(msg);
in.skipBytes(1); in.skipBytes(1);
@ -80,9 +82,9 @@ public class ReplayingDecoderTest {
private static final class BloatedLineDecoder extends ChannelInboundHandlerAdapter { private static final class BloatedLineDecoder extends ChannelInboundHandlerAdapter {
@Override @Override
public void messageReceived(ChannelHandlerContext ctx, MessageList<Object> msgs) throws Exception { public void messageReceived(ChannelHandlerContext ctx, Object msg) throws Exception {
ctx.pipeline().replace(this, "less-bloated", new LineDecoder()); ctx.pipeline().replace(this, "less-bloated", new LineDecoder());
ctx.pipeline().fireMessageReceived(msgs); ctx.pipeline().fireMessageReceived(msg);
} }
} }

View File

@ -75,7 +75,7 @@ public class AppletDiscardServer extends JApplet {
private static final class DiscardServerHandler extends SimpleChannelInboundHandler<ByteBuf> { private static final class DiscardServerHandler extends SimpleChannelInboundHandler<ByteBuf> {
@Override @Override
public void messageReceived(ChannelHandlerContext ctx, ByteBuf msg) throws Exception { public void messageReceived0(ChannelHandlerContext ctx, ByteBuf msg) throws Exception {
System.out.println("Received: " + msg.toString(CharsetUtil.UTF_8)); System.out.println("Received: " + msg.toString(CharsetUtil.UTF_8));
} }

View File

@ -19,8 +19,7 @@ import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter; import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.MessageList;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
@ -28,7 +27,7 @@ import java.util.logging.Logger;
/** /**
* Handles a client-side channel. * Handles a client-side channel.
*/ */
public class DiscardClientHandler extends ChannelInboundHandlerAdapter { public class DiscardClientHandler extends SimpleChannelInboundHandler<Object> {
private static final Logger logger = Logger.getLogger( private static final Logger logger = Logger.getLogger(
DiscardClientHandler.class.getName()); DiscardClientHandler.class.getName());
@ -63,9 +62,8 @@ public class DiscardClientHandler extends ChannelInboundHandlerAdapter {
} }
@Override @Override
public void messageReceived(ChannelHandlerContext ctx, MessageList<Object> msgs) throws Exception { public void messageReceived0(ChannelHandlerContext ctx, Object msg) throws Exception {
// Server is supposed to send nothing, but if it sends something, discard it. // Server is supposed to send nothing, but if it sends something, discard it.
msgs.releaseAllAndRecycle();
} }
@Override @Override
@ -84,7 +82,7 @@ public class DiscardClientHandler extends ChannelInboundHandlerAdapter {
private void generateTraffic() { private void generateTraffic() {
// Flush the outbound buffer to the socket. // Flush the outbound buffer to the socket.
// Once flushed, generate the same amount of traffic again. // Once flushed, generate the same amount of traffic again.
ctx.write(content.duplicate().retain()).addListener(trafficGenerator); ctx.write(content.duplicate().retain()).flush().addListener(trafficGenerator);
} }
private final ChannelFutureListener trafficGenerator = new ChannelFutureListener() { private final ChannelFutureListener trafficGenerator = new ChannelFutureListener() {

View File

@ -16,8 +16,7 @@
package io.netty.example.discard; package io.netty.example.discard;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter; import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.MessageList;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
@ -25,14 +24,14 @@ import java.util.logging.Logger;
/** /**
* Handles a server-side channel. * Handles a server-side channel.
*/ */
public class DiscardServerHandler extends ChannelInboundHandlerAdapter { public class DiscardServerHandler extends SimpleChannelInboundHandler<Object> {
private static final Logger logger = Logger.getLogger( private static final Logger logger = Logger.getLogger(
DiscardServerHandler.class.getName()); DiscardServerHandler.class.getName());
@Override @Override
public void messageReceived(ChannelHandlerContext ctx, MessageList<Object> msgs) throws Exception { public void messageReceived0(ChannelHandlerContext ctx, Object msg) throws Exception {
msgs.releaseAllAndRecycle(); // discard
} }
@Override @Override

View File

@ -19,7 +19,6 @@ import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled; import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter; import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.MessageList;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
@ -51,12 +50,17 @@ public class EchoClientHandler extends ChannelInboundHandlerAdapter {
@Override @Override
public void channelActive(ChannelHandlerContext ctx) { public void channelActive(ChannelHandlerContext ctx) {
ctx.write(firstMessage); ctx.write(firstMessage).flush();
} }
@Override @Override
public void messageReceived(ChannelHandlerContext ctx, MessageList<Object> msgs) throws Exception { public void messageReceived(ChannelHandlerContext ctx, Object msg) throws Exception {
ctx.write(msgs); ctx.write(msg);
}
@Override
public void messageReceivedLast(ChannelHandlerContext ctx) throws Exception {
ctx.flush();
} }
@Override @Override

View File

@ -18,7 +18,6 @@ package io.netty.example.echo;
import io.netty.channel.ChannelHandler.Sharable; import io.netty.channel.ChannelHandler.Sharable;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter; import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.MessageList;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
@ -33,8 +32,13 @@ public class EchoServerHandler extends ChannelInboundHandlerAdapter {
EchoServerHandler.class.getName()); EchoServerHandler.class.getName());
@Override @Override
public void messageReceived(ChannelHandlerContext ctx, MessageList<Object> msgs) throws Exception { public void messageReceived(ChannelHandlerContext ctx, Object msg) throws Exception {
ctx.write(msgs); ctx.write(msg);
}
@Override
public void messageReceivedLast(ChannelHandlerContext ctx) throws Exception {
ctx.flush();
} }
@Override @Override

View File

@ -17,11 +17,11 @@ package io.netty.example.factorial;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.MessageList;
import io.netty.handler.codec.ByteToMessageDecoder; import io.netty.handler.codec.ByteToMessageDecoder;
import io.netty.handler.codec.CorruptedFrameException; import io.netty.handler.codec.CorruptedFrameException;
import java.math.BigInteger; import java.math.BigInteger;
import java.util.List;
/** /**
* Decodes the binary representation of a {@link BigInteger} prepended * Decodes the binary representation of a {@link BigInteger} prepended
@ -32,7 +32,7 @@ import java.math.BigInteger;
public class BigIntegerDecoder extends ByteToMessageDecoder { public class BigIntegerDecoder extends ByteToMessageDecoder {
@Override @Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, MessageList<Object> out) { protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) {
// Wait until the length prefix is available. // Wait until the length prefix is available.
if (in.readableBytes() < 5) { if (in.readableBytes() < 5) {
return; return;

View File

@ -18,7 +18,6 @@ package io.netty.example.factorial;
import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.MessageList;
import io.netty.channel.SimpleChannelInboundHandler; import io.netty.channel.SimpleChannelInboundHandler;
import java.math.BigInteger; import java.math.BigInteger;
@ -71,7 +70,7 @@ public class FactorialClientHandler extends SimpleChannelInboundHandler<BigInteg
} }
@Override @Override
public void messageReceived(ChannelHandlerContext ctx, final BigInteger msg) { public void messageReceived0(ChannelHandlerContext ctx, final BigInteger msg) {
receivedMessages ++; receivedMessages ++;
if (receivedMessages == count) { if (receivedMessages == count) {
// Offer the answer after closing the connection. // Offer the answer after closing the connection.
@ -97,10 +96,9 @@ public class FactorialClientHandler extends SimpleChannelInboundHandler<BigInteg
private void sendNumbers() { private void sendNumbers() {
// Do not send more than 4096 numbers. // Do not send more than 4096 numbers.
boolean finished = false; boolean finished = false;
MessageList<Object> out = MessageList.newInstance(4096); for (int i = 0; i < 4096; i++) {
while (out.size() < 4096) {
if (i <= count) { if (i <= count) {
out.add(Integer.valueOf(i)); ctx.write(Integer.valueOf(i));
i ++; i ++;
} else { } else {
finished = true; finished = true;
@ -108,7 +106,7 @@ public class FactorialClientHandler extends SimpleChannelInboundHandler<BigInteg
} }
} }
ChannelFuture f = ctx.write(out); ChannelFuture f = ctx.flush();
if (!finished) { if (!finished) {
f.addListener(numberSender); f.addListener(numberSender);
} }

View File

@ -16,8 +16,7 @@
package io.netty.example.factorial; package io.netty.example.factorial;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter; import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.MessageList;
import java.math.BigInteger; import java.math.BigInteger;
import java.util.Formatter; import java.util.Formatter;
@ -31,7 +30,7 @@ import java.util.logging.Logger;
* to create a new handler instance whenever you create a new channel and insert * to create a new handler instance whenever you create a new channel and insert
* this handler to avoid a race condition. * this handler to avoid a race condition.
*/ */
public class FactorialServerHandler extends ChannelInboundHandlerAdapter { public class FactorialServerHandler extends SimpleChannelInboundHandler<BigInteger> {
private static final Logger logger = Logger.getLogger( private static final Logger logger = Logger.getLogger(
FactorialServerHandler.class.getName()); FactorialServerHandler.class.getName());
@ -40,29 +39,21 @@ public class FactorialServerHandler extends ChannelInboundHandlerAdapter {
private BigInteger factorial = new BigInteger("1"); private BigInteger factorial = new BigInteger("1");
@Override @Override
public void messageReceived( public void messageReceived0(ChannelHandlerContext ctx, BigInteger msg) throws Exception {
ChannelHandlerContext ctx, MessageList<Object> msgs) throws Exception { // Calculate the cumulative factorial and send it to the client.
MessageList<BigInteger> ints = msgs.cast(); lastMultiplier = msg;
for (int i = 0; i < ints.size(); i++) { factorial = factorial.multiply(msg);
BigInteger msg = ints.get(i); ctx.write(factorial).flush();
// Calculate the cumulative factorial and send it to the client.
lastMultiplier = msg;
factorial = factorial.multiply(msg);
ctx.write(factorial);
}
msgs.recycle();
} }
@Override @Override
public void channelInactive( public void channelInactive(ChannelHandlerContext ctx) throws Exception {
ChannelHandlerContext ctx) throws Exception {
logger.info(new Formatter().format( logger.info(new Formatter().format(
"Factorial of %,d is: %,d", lastMultiplier, factorial).toString()); "Factorial of %,d is: %,d", lastMultiplier, factorial).toString());
} }
@Override @Override
public void exceptionCaught( public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
ChannelHandlerContext ctx, Throwable cause) throws Exception {
logger.log( logger.log(
Level.WARNING, Level.WARNING,
"Unexpected exception from downstream.", cause); "Unexpected exception from downstream.", cause);

View File

@ -23,7 +23,6 @@ import io.netty.channel.ChannelOption;
import io.netty.channel.DefaultFileRegion; import io.netty.channel.DefaultFileRegion;
import io.netty.channel.EventLoopGroup; import io.netty.channel.EventLoopGroup;
import io.netty.channel.FileRegion; import io.netty.channel.FileRegion;
import io.netty.channel.MessageList;
import io.netty.channel.SimpleChannelInboundHandler; import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.SocketChannel;
@ -94,7 +93,7 @@ public class FileServer {
private static final class FileHandler extends SimpleChannelInboundHandler<String> { private static final class FileHandler extends SimpleChannelInboundHandler<String> {
@Override @Override
public void messageReceived(ChannelHandlerContext ctx, String msg) throws Exception { public void messageReceived0(ChannelHandlerContext ctx, String msg) throws Exception {
File file = new File(msg); File file = new File(msg);
if (file.exists()) { if (file.exists()) {
if (!file.isFile()) { if (!file.isFile()) {
@ -102,11 +101,10 @@ public class FileServer {
return; return;
} }
ctx.write(file + " " + file.length() + '\n'); ctx.write(file + " " + file.length() + '\n');
MessageList<Object> out = MessageList.newInstance();
FileRegion region = new DefaultFileRegion(new FileInputStream(file).getChannel(), 0, file.length()); FileRegion region = new DefaultFileRegion(new FileInputStream(file).getChannel(), 0, file.length());
out.add(region); ctx.write(region);
out.add("\n"); ctx.write("\n");
ctx.write(out); ctx.flush();
} else { } else {
ctx.write("File not found: " + file + '\n'); ctx.write("File not found: " + file + '\n');
} }

View File

@ -19,7 +19,6 @@ import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.MessageList;
import io.netty.channel.SimpleChannelInboundHandler; import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.DefaultFullHttpResponse; import io.netty.handler.codec.http.DefaultFullHttpResponse;
import io.netty.handler.codec.http.DefaultHttpResponse; import io.netty.handler.codec.http.DefaultHttpResponse;
@ -105,7 +104,7 @@ public class HttpStaticFileServerHandler extends SimpleChannelInboundHandler<Ful
public static final int HTTP_CACHE_SECONDS = 60; public static final int HTTP_CACHE_SECONDS = 60;
@Override @Override
public void messageReceived( public void messageReceived0(
ChannelHandlerContext ctx, FullHttpRequest request) throws Exception { ChannelHandlerContext ctx, FullHttpRequest request) throws Exception {
if (!request.getDecoderResult().isSuccess()) { if (!request.getDecoderResult().isSuccess()) {
sendError(ctx, BAD_REQUEST); sendError(ctx, BAD_REQUEST);
@ -177,15 +176,14 @@ public class HttpStaticFileServerHandler extends SimpleChannelInboundHandler<Ful
response.headers().set(CONNECTION, HttpHeaders.Values.KEEP_ALIVE); response.headers().set(CONNECTION, HttpHeaders.Values.KEEP_ALIVE);
} }
MessageList<Object> out = MessageList.newInstance();
// Write the initial line and the header. // Write the initial line and the header.
out.add(response); ctx.write(response);
// Write the content. // Write the content.
out.add(new ChunkedFile(raf, 0, fileLength, 8192)); ctx.write(new ChunkedFile(raf, 0, fileLength, 8192));
// Write the end marker // Write the end marker
out.add(LastHttpContent.EMPTY_LAST_CONTENT); ctx.write(LastHttpContent.EMPTY_LAST_CONTENT);
ChannelFuture writeFuture = ctx.write(out); ChannelFuture writeFuture = ctx.flush();
// Decide whether to close the connection or not. // Decide whether to close the connection or not.
if (!isKeepAlive(request)) { if (!isKeepAlive(request)) {
// Close the connection when the whole content is written out. // Close the connection when the whole content is written out.
@ -279,7 +277,7 @@ public class HttpStaticFileServerHandler extends SimpleChannelInboundHandler<Ful
response.content().writeBytes(Unpooled.copiedBuffer(buf, CharsetUtil.UTF_8)); response.content().writeBytes(Unpooled.copiedBuffer(buf, CharsetUtil.UTF_8));
// Close the connection as soon as the error message is sent. // Close the connection as soon as the error message is sent.
ctx.write(response).addListener(ChannelFutureListener.CLOSE); ctx.write(response).flush().addListener(ChannelFutureListener.CLOSE);
} }
private static void sendRedirect(ChannelHandlerContext ctx, String newUri) { private static void sendRedirect(ChannelHandlerContext ctx, String newUri) {
@ -287,7 +285,7 @@ public class HttpStaticFileServerHandler extends SimpleChannelInboundHandler<Ful
response.headers().set(LOCATION, newUri); response.headers().set(LOCATION, newUri);
// Close the connection as soon as the error message is sent. // Close the connection as soon as the error message is sent.
ctx.write(response).addListener(ChannelFutureListener.CLOSE); ctx.write(response).flush().addListener(ChannelFutureListener.CLOSE);
} }
private static void sendError(ChannelHandlerContext ctx, HttpResponseStatus status) { private static void sendError(ChannelHandlerContext ctx, HttpResponseStatus status) {
@ -296,7 +294,7 @@ public class HttpStaticFileServerHandler extends SimpleChannelInboundHandler<Ful
response.headers().set(CONTENT_TYPE, "text/plain; charset=UTF-8"); response.headers().set(CONTENT_TYPE, "text/plain; charset=UTF-8");
// Close the connection as soon as the error message is sent. // Close the connection as soon as the error message is sent.
ctx.write(response).addListener(ChannelFutureListener.CLOSE); ctx.write(response).flush().addListener(ChannelFutureListener.CLOSE);
} }
/** /**
@ -310,7 +308,7 @@ public class HttpStaticFileServerHandler extends SimpleChannelInboundHandler<Ful
setDateHeader(response); setDateHeader(response);
// Close the connection as soon as the error message is sent. // Close the connection as soon as the error message is sent.
ctx.write(response).addListener(ChannelFutureListener.CLOSE); ctx.write(response).flush().addListener(ChannelFutureListener.CLOSE);
} }
/** /**

View File

@ -19,8 +19,7 @@ import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled; import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.MessageList; import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.DefaultFullHttpResponse; import io.netty.handler.codec.http.DefaultFullHttpResponse;
import io.netty.handler.codec.http.FullHttpResponse; import io.netty.handler.codec.http.FullHttpResponse;
import io.netty.handler.codec.http.HttpRequest; import io.netty.handler.codec.http.HttpRequest;
@ -31,20 +30,13 @@ import static io.netty.handler.codec.http.HttpHeaders.*;
import static io.netty.handler.codec.http.HttpResponseStatus.*; import static io.netty.handler.codec.http.HttpResponseStatus.*;
import static io.netty.handler.codec.http.HttpVersion.*; import static io.netty.handler.codec.http.HttpVersion.*;
public class HttpHelloWorldServerHandler extends SimpleChannelInboundHandler<Object> { public class HttpHelloWorldServerHandler extends ChannelInboundHandlerAdapter {
private static final ByteBuf CONTENT = private static final ByteBuf CONTENT =
Unpooled.unreleasableBuffer(Unpooled.copiedBuffer("Hello World", CharsetUtil.US_ASCII)); Unpooled.unreleasableBuffer(Unpooled.copiedBuffer("Hello World", CharsetUtil.US_ASCII));
private MessageList<Object> out;
@Override @Override
protected void beginMessageReceived(ChannelHandlerContext ctx) { public void messageReceivedLast(ChannelHandlerContext ctx) {
out = MessageList.newInstance(); ctx.flush();
}
@Override
protected void endMessageReceived(ChannelHandlerContext ctx) {
ctx.write(out);
out = null;
} }
@Override @Override
@ -53,7 +45,7 @@ public class HttpHelloWorldServerHandler extends SimpleChannelInboundHandler<Obj
HttpRequest req = (HttpRequest) msg; HttpRequest req = (HttpRequest) msg;
if (is100ContinueExpected(req)) { if (is100ContinueExpected(req)) {
out.add(new DefaultFullHttpResponse(HTTP_1_1, CONTINUE)); ctx.write(new DefaultFullHttpResponse(HTTP_1_1, CONTINUE)).flush();
} }
boolean keepAlive = isKeepAlive(req); boolean keepAlive = isKeepAlive(req);
FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, OK, CONTENT.duplicate()); FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, OK, CONTENT.duplicate());
@ -61,11 +53,9 @@ public class HttpHelloWorldServerHandler extends SimpleChannelInboundHandler<Obj
response.headers().set(CONTENT_LENGTH, response.content().readableBytes()); response.headers().set(CONTENT_LENGTH, response.content().readableBytes());
if (!keepAlive) { if (!keepAlive) {
out.add(response); ctx.write(response).flush().addListener(ChannelFutureListener.CLOSE);
ctx.write(out).addListener(ChannelFutureListener.CLOSE);
out = MessageList.newInstance();
} else { } else {
out.add(response); ctx.write(response);
response.headers().set(CONNECTION, Values.KEEP_ALIVE); response.headers().set(CONNECTION, Values.KEEP_ALIVE);
} }
} }

View File

@ -27,7 +27,7 @@ import io.netty.util.CharsetUtil;
public class HttpSnoopClientHandler extends SimpleChannelInboundHandler<HttpObject> { public class HttpSnoopClientHandler extends SimpleChannelInboundHandler<HttpObject> {
@Override @Override
public void messageReceived(ChannelHandlerContext ctx, HttpObject msg) throws Exception { public void messageReceived0(ChannelHandlerContext ctx, HttpObject msg) throws Exception {
if (msg instanceof HttpResponse) { if (msg instanceof HttpResponse) {
HttpResponse response = (HttpResponse) msg; HttpResponse response = (HttpResponse) msg;

View File

@ -18,8 +18,7 @@ package io.netty.example.http.snoop;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled; import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter; import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.MessageList;
import io.netty.handler.codec.DecoderResult; import io.netty.handler.codec.DecoderResult;
import io.netty.handler.codec.http.Cookie; import io.netty.handler.codec.http.Cookie;
import io.netty.handler.codec.http.CookieDecoder; import io.netty.handler.codec.http.CookieDecoder;
@ -44,34 +43,24 @@ import static io.netty.handler.codec.http.HttpHeaders.*;
import static io.netty.handler.codec.http.HttpResponseStatus.*; import static io.netty.handler.codec.http.HttpResponseStatus.*;
import static io.netty.handler.codec.http.HttpVersion.*; import static io.netty.handler.codec.http.HttpVersion.*;
public class HttpSnoopServerHandler extends ChannelInboundHandlerAdapter { public class HttpSnoopServerHandler extends SimpleChannelInboundHandler<Object> {
private HttpRequest request; private HttpRequest request;
/** Buffer that stores the response content */ /** Buffer that stores the response content */
private final StringBuilder buf = new StringBuilder(); private final StringBuilder buf = new StringBuilder();
@Override @Override
public void messageReceived(ChannelHandlerContext ctx, MessageList<Object> msgs) throws Exception { public void messageReceivedLast(ChannelHandlerContext ctx) throws Exception {
MessageList<Object> out = MessageList.newInstance(); ctx.flush();
int size = msgs.size();
try {
for (int i = 0; i < size; i ++) {
if (!messageReceived(ctx, msgs.get(i), out)) {
break;
}
}
} finally {
msgs.releaseAllAndRecycle();
ctx.write(out);
}
} }
private boolean messageReceived(ChannelHandlerContext ctx, Object msg, MessageList<Object> out) { @Override
protected void messageReceived0(ChannelHandlerContext ctx, Object msg) {
if (msg instanceof HttpRequest) { if (msg instanceof HttpRequest) {
HttpRequest request = this.request = (HttpRequest) msg; HttpRequest request = this.request = (HttpRequest) msg;
if (is100ContinueExpected(request)) { if (is100ContinueExpected(request)) {
send100Continue(out); send100Continue(ctx);
} }
buf.setLength(0); buf.setLength(0);
@ -134,10 +123,9 @@ public class HttpSnoopServerHandler extends ChannelInboundHandlerAdapter {
buf.append("\r\n"); buf.append("\r\n");
} }
return writeResponse(trailer, out); writeResponse(trailer, ctx);
} }
} }
return true;
} }
private static void appendDecoderResult(StringBuilder buf, HttpObject o) { private static void appendDecoderResult(StringBuilder buf, HttpObject o) {
@ -151,7 +139,7 @@ public class HttpSnoopServerHandler extends ChannelInboundHandlerAdapter {
buf.append("\r\n"); buf.append("\r\n");
} }
private boolean writeResponse(HttpObject currentObj, MessageList<Object> out) { private boolean writeResponse(HttpObject currentObj, ChannelHandlerContext ctx) {
// Decide whether to close the connection or not. // Decide whether to close the connection or not.
boolean keepAlive = isKeepAlive(request); boolean keepAlive = isKeepAlive(request);
// Build the response object. // Build the response object.
@ -186,14 +174,14 @@ public class HttpSnoopServerHandler extends ChannelInboundHandlerAdapter {
} }
// Write the response. // Write the response.
out.add(response); ctx.write(response);
return keepAlive; return keepAlive;
} }
private static void send100Continue(MessageList<Object> out) { private static void send100Continue(ChannelHandlerContext ctx) {
FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, CONTINUE); FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, CONTINUE);
out.add(response); ctx.write(response);
} }
@Override @Override

View File

@ -202,7 +202,7 @@ public class HttpUploadClient {
// send request // send request
List<Entry<String, String>> entries = headers.entries(); List<Entry<String, String>> entries = headers.entries();
channel.write(request).sync(); channel.write(request).flush().sync();
// Wait for the server to close the connection. // Wait for the server to close the connection.
channel.closeFuture().sync(); channel.closeFuture().sync();
@ -276,7 +276,7 @@ public class HttpUploadClient {
if (bodyRequestEncoder.isChunked()) { if (bodyRequestEncoder.isChunked()) {
// could do either request.isChunked() // could do either request.isChunked()
// either do it through ChunkedWriteHandler // either do it through ChunkedWriteHandler
channel.write(bodyRequestEncoder).awaitUninterruptibly(); channel.write(bodyRequestEncoder).flush().awaitUninterruptibly();
} }
// Do not clear here since we will reuse the InterfaceHttpData on the // Do not clear here since we will reuse the InterfaceHttpData on the
@ -351,7 +351,7 @@ public class HttpUploadClient {
// test if request was chunked and if so, finish the write // test if request was chunked and if so, finish the write
if (bodyRequestEncoder.isChunked()) { if (bodyRequestEncoder.isChunked()) {
channel.write(bodyRequestEncoder).awaitUninterruptibly(); channel.write(bodyRequestEncoder).flush().awaitUninterruptibly();
} }
// Now no more use of file representation (and list of HttpData) // Now no more use of file representation (and list of HttpData)

View File

@ -36,7 +36,7 @@ public class HttpUploadClientHandler extends SimpleChannelInboundHandler<HttpObj
private boolean readingChunks; private boolean readingChunks;
@Override @Override
public void messageReceived(ChannelHandlerContext ctx, HttpObject msg) throws Exception { public void messageReceived0(ChannelHandlerContext ctx, HttpObject msg) throws Exception {
if (msg instanceof HttpResponse) { if (msg instanceof HttpResponse) {
HttpResponse response = (HttpResponse) msg; HttpResponse response = (HttpResponse) msg;

View File

@ -95,7 +95,7 @@ public class HttpUploadServerHandler extends SimpleChannelInboundHandler<HttpObj
} }
@Override @Override
public void messageReceived(ChannelHandlerContext ctx, HttpObject msg) throws Exception { public void messageReceived0(ChannelHandlerContext ctx, HttpObject msg) throws Exception {
if (msg instanceof HttpRequest) { if (msg instanceof HttpRequest) {
HttpRequest request = this.request = (HttpRequest) msg; HttpRequest request = this.request = (HttpRequest) msg;
URI uri = new URI(request.getUri()); URI uri = new URI(request.getUri());
@ -313,7 +313,7 @@ public class HttpUploadServerHandler extends SimpleChannelInboundHandler<HttpObj
} }
} }
// Write the response. // Write the response.
ChannelFuture future = channel.write(response); ChannelFuture future = channel.write(response).flush();
// Close the connection after the write operation is done if necessary. // Close the connection after the write operation is done if necessary.
if (close) { if (close) {
future.addListener(ChannelFutureListener.CLOSE); future.addListener(ChannelFutureListener.CLOSE);

View File

@ -20,7 +20,6 @@ import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter; import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.MessageList;
import io.netty.handler.codec.http.DefaultFullHttpResponse; import io.netty.handler.codec.http.DefaultFullHttpResponse;
import io.netty.handler.codec.http.FullHttpRequest; import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.FullHttpResponse; import io.netty.handler.codec.http.FullHttpResponse;
@ -53,18 +52,17 @@ public class AutobahnServerHandler extends ChannelInboundHandlerAdapter {
private WebSocketServerHandshaker handshaker; private WebSocketServerHandshaker handshaker;
@Override @Override
public void messageReceived(ChannelHandlerContext ctx, MessageList<Object> msgs) throws Exception { public void messageReceived(ChannelHandlerContext ctx, Object msg) throws Exception {
MessageList<Object> out = MessageList.newInstance(msgs.size()); if (msg instanceof FullHttpRequest) {
for (int i = 0; i < msgs.size(); i++) { handleHttpRequest(ctx, (FullHttpRequest) msg);
Object msg = msgs.get(i); } else if (msg instanceof WebSocketFrame) {
if (msg instanceof FullHttpRequest) { handleWebSocketFrame(ctx, (WebSocketFrame) msg);
handleHttpRequest(ctx, (FullHttpRequest) msg);
} else if (msg instanceof WebSocketFrame) {
handleWebSocketFrame(ctx, (WebSocketFrame) msg, out);
}
} }
msgs.recycle(); }
ctx.write(out);
@Override
public void messageReceivedLast(ChannelHandlerContext ctx) throws Exception {
ctx.flush();
} }
private void handleHttpRequest(ChannelHandlerContext ctx, FullHttpRequest req) private void handleHttpRequest(ChannelHandlerContext ctx, FullHttpRequest req)
@ -92,7 +90,7 @@ public class AutobahnServerHandler extends ChannelInboundHandlerAdapter {
} }
} }
private void handleWebSocketFrame(ChannelHandlerContext ctx, WebSocketFrame frame, MessageList<Object> out) { private void handleWebSocketFrame(ChannelHandlerContext ctx, WebSocketFrame frame) {
if (logger.isLoggable(Level.FINE)) { if (logger.isLoggable(Level.FINE)) {
logger.fine(String.format( logger.fine(String.format(
"Channel %s received %s", ctx.channel().hashCode(), frame.getClass().getSimpleName())); "Channel %s received %s", ctx.channel().hashCode(), frame.getClass().getSimpleName()));
@ -101,13 +99,13 @@ public class AutobahnServerHandler extends ChannelInboundHandlerAdapter {
if (frame instanceof CloseWebSocketFrame) { if (frame instanceof CloseWebSocketFrame) {
handshaker.close(ctx.channel(), (CloseWebSocketFrame) frame); handshaker.close(ctx.channel(), (CloseWebSocketFrame) frame);
} else if (frame instanceof PingWebSocketFrame) { } else if (frame instanceof PingWebSocketFrame) {
out.add(new PongWebSocketFrame(frame.isFinalFragment(), frame.rsv(), frame.content())); ctx.write(new PongWebSocketFrame(frame.isFinalFragment(), frame.rsv(), frame.content()));
} else if (frame instanceof TextWebSocketFrame) { } else if (frame instanceof TextWebSocketFrame) {
out.add(frame); ctx.write(frame);
} else if (frame instanceof BinaryWebSocketFrame) { } else if (frame instanceof BinaryWebSocketFrame) {
out.add(frame); ctx.write(frame);
} else if (frame instanceof ContinuationWebSocketFrame) { } else if (frame instanceof ContinuationWebSocketFrame) {
out.add(frame); ctx.write(frame);
} else if (frame instanceof PongWebSocketFrame) { } else if (frame instanceof PongWebSocketFrame) {
frame.release(); frame.release();
// Ignore // Ignore
@ -126,7 +124,7 @@ public class AutobahnServerHandler extends ChannelInboundHandlerAdapter {
} }
// Send the response and close the connection if necessary. // Send the response and close the connection if necessary.
ChannelFuture f = ctx.channel().write(res); ChannelFuture f = ctx.channel().write(res).flush();
if (!isKeepAlive(req) || res.getStatus().code() != 200) { if (!isKeepAlive(req) || res.getStatus().code() != 200) {
f.addListener(ChannelFutureListener.CLOSE); f.addListener(ChannelFutureListener.CLOSE);
} }

View File

@ -79,7 +79,7 @@ public class WebSocketClientHandler extends SimpleChannelInboundHandler<Object>
} }
@Override @Override
public void messageReceived(ChannelHandlerContext ctx, Object msg) throws Exception { public void messageReceived0(ChannelHandlerContext ctx, Object msg) throws Exception {
Channel ch = ctx.channel(); Channel ch = ctx.channel();
if (!handshaker.isHandshakeComplete()) { if (!handshaker.isHandshakeComplete()) {
handshaker.finishHandshake(ch, (FullHttpResponse) msg); handshaker.finishHandshake(ch, (FullHttpResponse) msg);

View File

@ -21,7 +21,7 @@ import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
public class CustomTextFrameHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> { public class CustomTextFrameHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {
@Override @Override
public void messageReceived(ChannelHandlerContext ctx, TextWebSocketFrame frame) throws Exception { protected void messageReceived0(ChannelHandlerContext ctx, TextWebSocketFrame frame) throws Exception {
String request = frame.text(); String request = frame.text();
ctx.channel().write(new TextWebSocketFrame(request.toUpperCase())); ctx.channel().write(new TextWebSocketFrame(request.toUpperCase()));
} }

View File

@ -53,7 +53,7 @@ public class WebSocketServerHandler extends SimpleChannelInboundHandler<Object>
private WebSocketServerHandshaker handshaker; private WebSocketServerHandshaker handshaker;
@Override @Override
public void messageReceived(ChannelHandlerContext ctx, Object msg) throws Exception { public void messageReceived0(ChannelHandlerContext ctx, Object msg) throws Exception {
if (msg instanceof FullHttpRequest) { if (msg instanceof FullHttpRequest) {
handleHttpRequest(ctx, (FullHttpRequest) msg); handleHttpRequest(ctx, (FullHttpRequest) msg);
} else if (msg instanceof WebSocketFrame) { } else if (msg instanceof WebSocketFrame) {
@ -135,7 +135,7 @@ public class WebSocketServerHandler extends SimpleChannelInboundHandler<Object>
} }
// Send the response and close the connection if necessary. // Send the response and close the connection if necessary.
ChannelFuture f = ctx.channel().write(res); ChannelFuture f = ctx.channel().write(res).flush();
if (!isKeepAlive(req) || res.getStatus().code() != 200) { if (!isKeepAlive(req) || res.getStatus().code() != 200) {
f.addListener(ChannelFutureListener.CLOSE); f.addListener(ChannelFutureListener.CLOSE);
} }

View File

@ -54,7 +54,7 @@ public class WebSocketSslServerHandler extends SimpleChannelInboundHandler<Objec
private WebSocketServerHandshaker handshaker; private WebSocketServerHandshaker handshaker;
@Override @Override
public void messageReceived(ChannelHandlerContext ctx, Object msg) throws Exception { public void messageReceived0(ChannelHandlerContext ctx, Object msg) throws Exception {
if (msg instanceof FullHttpRequest) { if (msg instanceof FullHttpRequest) {
handleHttpRequest(ctx, (FullHttpRequest) msg); handleHttpRequest(ctx, (FullHttpRequest) msg);
} else if (msg instanceof WebSocketFrame) { } else if (msg instanceof WebSocketFrame) {
@ -137,7 +137,7 @@ public class WebSocketSslServerHandler extends SimpleChannelInboundHandler<Objec
} }
// Send the response and close the connection if necessary. // Send the response and close the connection if necessary.
ChannelFuture f = ctx.channel().write(res); ChannelFuture f = ctx.channel().write(res).flush();
if (!isKeepAlive(req) || res.getStatus().code() != 200) { if (!isKeepAlive(req) || res.getStatus().code() != 200) {
f.addListener(ChannelFutureListener.CLOSE); f.addListener(ChannelFutureListener.CLOSE);
} }

View File

@ -97,7 +97,7 @@ public class LocalEcho {
} }
// Sends the received line to the server. // Sends the received line to the server.
lastWriteFuture = ch.write(line); lastWriteFuture = ch.write(line).flush();
} }
// Wait until all messages are flushed before closing the channel. // Wait until all messages are flushed before closing the channel.

View File

@ -21,7 +21,7 @@ import io.netty.channel.SimpleChannelInboundHandler;
public class LocalEchoClientHandler extends SimpleChannelInboundHandler<Object> { public class LocalEchoClientHandler extends SimpleChannelInboundHandler<Object> {
@Override @Override
public void messageReceived(ChannelHandlerContext ctx, Object msg) throws Exception { public void messageReceived0(ChannelHandlerContext ctx, Object msg) throws Exception {
// Print as received // Print as received
System.out.println(msg); System.out.println(msg);
} }

View File

@ -17,14 +17,19 @@ package io.netty.example.localecho;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter; import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.MessageList;
public class LocalEchoServerHandler extends ChannelInboundHandlerAdapter { public class LocalEchoServerHandler extends ChannelInboundHandlerAdapter {
@Override @Override
public void messageReceived(ChannelHandlerContext ctx, MessageList<Object> msgs) throws Exception { public void messageReceived(ChannelHandlerContext ctx, Object msg) throws Exception {
// Write back as received // Write back as received
ctx.write(msgs); ctx.write(msg);
}
@Override
public void messageReceivedLast(ChannelHandlerContext ctx) throws Exception {
ctx.flush();
} }
@Override @Override

View File

@ -17,7 +17,6 @@ package io.netty.example.objectecho;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter; import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.MessageList;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -57,9 +56,14 @@ public class ObjectEchoClientHandler extends ChannelInboundHandlerAdapter {
} }
@Override @Override
public void messageReceived(ChannelHandlerContext ctx, MessageList<Object> msgs) throws Exception { public void messageReceived(ChannelHandlerContext ctx, Object msg) throws Exception {
// Echo back the received object to the server. // Echo back the received object to the server.
ctx.write(msgs); ctx.write(msg);
}
@Override
public void messageReceivedLast(ChannelHandlerContext ctx) throws Exception {
ctx.flush();
} }
@Override @Override

View File

@ -17,7 +17,6 @@ package io.netty.example.objectecho;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter; import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.MessageList;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
@ -33,9 +32,14 @@ public class ObjectEchoServerHandler extends ChannelInboundHandlerAdapter {
@Override @Override
public void messageReceived( public void messageReceived(
ChannelHandlerContext ctx, MessageList<Object> msgs) throws Exception { ChannelHandlerContext ctx, Object msg) throws Exception {
// Echo back the received object to the client. // Echo back the received object to the client.
ctx.write(msgs); ctx.write(msg);
}
@Override
public void messageReceivedLast(ChannelHandlerContext ctx) throws Exception {
ctx.flush();
} }
@Override @Override

View File

@ -18,7 +18,6 @@ package io.netty.example.portunification;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelPipeline; import io.netty.channel.ChannelPipeline;
import io.netty.channel.MessageList;
import io.netty.example.factorial.BigIntegerDecoder; import io.netty.example.factorial.BigIntegerDecoder;
import io.netty.example.factorial.FactorialServerHandler; import io.netty.example.factorial.FactorialServerHandler;
import io.netty.example.factorial.NumberEncoder; import io.netty.example.factorial.NumberEncoder;
@ -33,6 +32,7 @@ import io.netty.handler.codec.http.HttpResponseEncoder;
import io.netty.handler.ssl.SslHandler; import io.netty.handler.ssl.SslHandler;
import javax.net.ssl.SSLEngine; import javax.net.ssl.SSLEngine;
import java.util.List;
/** /**
* Manipulates the current pipeline dynamically to switch protocols or enable * Manipulates the current pipeline dynamically to switch protocols or enable
@ -53,7 +53,7 @@ public class PortUnificationServerHandler extends ByteToMessageDecoder {
} }
@Override @Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, MessageList<Object> out) throws Exception { protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
// Will use the first five bytes to detect a protocol. // Will use the first five bytes to detect a protocol.
if (in.readableBytes() < 5) { if (in.readableBytes() < 5) {
return; return;

View File

@ -21,7 +21,6 @@ import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter; import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.MessageList;
public class HexDumpProxyBackendHandler extends ChannelInboundHandlerAdapter { public class HexDumpProxyBackendHandler extends ChannelInboundHandlerAdapter {
@ -38,8 +37,8 @@ public class HexDumpProxyBackendHandler extends ChannelInboundHandlerAdapter {
} }
@Override @Override
public void messageReceived(final ChannelHandlerContext ctx, MessageList<Object> msgs) throws Exception { public void messageReceived(final ChannelHandlerContext ctx, Object msg) throws Exception {
inboundChannel.write(msgs).addListener(new ChannelFutureListener() { inboundChannel.write(msg).flush().addListener(new ChannelFutureListener() {
@Override @Override
public void operationComplete(ChannelFuture future) throws Exception { public void operationComplete(ChannelFuture future) throws Exception {
if (future.isSuccess()) { if (future.isSuccess()) {

View File

@ -23,7 +23,6 @@ import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter; import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.ChannelOption; import io.netty.channel.ChannelOption;
import io.netty.channel.MessageList;
public class HexDumpProxyFrontendHandler extends ChannelInboundHandlerAdapter { public class HexDumpProxyFrontendHandler extends ChannelInboundHandlerAdapter {
@ -64,9 +63,9 @@ public class HexDumpProxyFrontendHandler extends ChannelInboundHandlerAdapter {
} }
@Override @Override
public void messageReceived(final ChannelHandlerContext ctx, MessageList<Object> msgs) throws Exception { public void messageReceived(final ChannelHandlerContext ctx, Object msg) throws Exception {
if (outboundChannel.isActive()) { if (outboundChannel.isActive()) {
outboundChannel.write(msgs).addListener(new ChannelFutureListener() { outboundChannel.write(msg).flush().addListener(new ChannelFutureListener() {
@Override @Override
public void operationComplete(ChannelFuture future) throws Exception { public void operationComplete(ChannelFuture future) throws Exception {
if (future.isSuccess()) { if (future.isSuccess()) {
@ -98,7 +97,7 @@ public class HexDumpProxyFrontendHandler extends ChannelInboundHandlerAdapter {
*/ */
static void closeOnFlush(Channel ch) { static void closeOnFlush(Channel ch) {
if (ch.isActive()) { if (ch.isActive()) {
ch.write(Unpooled.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE); ch.write(Unpooled.EMPTY_BUFFER).flush().addListener(ChannelFutureListener.CLOSE);
} }
} }
} }

View File

@ -55,7 +55,7 @@ public class QuoteOfTheMomentClient {
// Broadcast the QOTM request to port 8080. // Broadcast the QOTM request to port 8080.
ch.write(new DatagramPacket( ch.write(new DatagramPacket(
Unpooled.copiedBuffer("QOTM?", CharsetUtil.UTF_8), Unpooled.copiedBuffer("QOTM?", CharsetUtil.UTF_8),
new InetSocketAddress("255.255.255.255", port))).sync(); new InetSocketAddress("255.255.255.255", port))).flush().sync();
// QuoteOfTheMomentClientHandler will close the DatagramChannel when a // QuoteOfTheMomentClientHandler will close the DatagramChannel when a
// response is received. If the channel is not closed within 5 seconds, // response is received. If the channel is not closed within 5 seconds,

View File

@ -23,7 +23,7 @@ import io.netty.util.CharsetUtil;
public class QuoteOfTheMomentClientHandler extends SimpleChannelInboundHandler<DatagramPacket> { public class QuoteOfTheMomentClientHandler extends SimpleChannelInboundHandler<DatagramPacket> {
@Override @Override
public void messageReceived(ChannelHandlerContext ctx, DatagramPacket msg) throws Exception { public void messageReceived0(ChannelHandlerContext ctx, DatagramPacket msg) throws Exception {
String response = msg.content().toString(CharsetUtil.UTF_8); String response = msg.content().toString(CharsetUtil.UTF_8);
if (response.startsWith("QOTM: ")) { if (response.startsWith("QOTM: ")) {
System.out.println("Quote of the Moment: " + response.substring(6)); System.out.println("Quote of the Moment: " + response.substring(6));

View File

@ -44,7 +44,7 @@ public class QuoteOfTheMomentServerHandler extends SimpleChannelInboundHandler<D
} }
@Override @Override
public void messageReceived(ChannelHandlerContext ctx, DatagramPacket packet) throws Exception { public void messageReceived0(ChannelHandlerContext ctx, DatagramPacket packet) throws Exception {
System.err.println(packet); System.err.println(packet);
if ("QOTM?".equals(packet.content().toString(CharsetUtil.UTF_8))) { if ("QOTM?".equals(packet.content().toString(CharsetUtil.UTF_8))) {
ctx.write(new DatagramPacket( ctx.write(new DatagramPacket(

View File

@ -26,7 +26,7 @@ public class RxtxClientHandler extends SimpleChannelInboundHandler<String> {
} }
@Override @Override
public void messageReceived(ChannelHandlerContext ctx, String msg) throws Exception { public void messageReceived0(ChannelHandlerContext ctx, String msg) throws Exception {
if ("OK".equals(msg)) { if ("OK".equals(msg)) {
System.out.println("Serial port responded to AT"); System.out.println("Serial port responded to AT");
} else { } else {

View File

@ -16,11 +16,9 @@
package io.netty.example.sctp; package io.netty.example.sctp;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil;
import io.netty.buffer.Unpooled; import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter; import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.MessageList;
import io.netty.channel.sctp.SctpMessage; import io.netty.channel.sctp.SctpMessage;
import java.util.logging.Level; import java.util.logging.Level;
@ -57,8 +55,13 @@ public class SctpEchoClientHandler extends ChannelInboundHandlerAdapter {
} }
@Override @Override
public void messageReceived(ChannelHandlerContext ctx, MessageList<Object> messages) throws Exception { public void messageReceived(ChannelHandlerContext ctx, Object msg) throws Exception {
ctx.write(messages); ctx.write(msg);
}
@Override
public void messageReceivedLast(ChannelHandlerContext ctx) throws Exception {
ctx.flush();
} }
@Override @Override

View File

@ -18,7 +18,6 @@ package io.netty.example.sctp;
import io.netty.channel.ChannelHandler.Sharable; import io.netty.channel.ChannelHandler.Sharable;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter; import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.MessageList;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
@ -40,7 +39,12 @@ public class SctpEchoServerHandler extends ChannelInboundHandlerAdapter {
} }
@Override @Override
public void messageReceived(ChannelHandlerContext ctx, MessageList<Object> msgs) throws Exception { public void messageReceived(ChannelHandlerContext ctx, Object msg) throws Exception {
ctx.write(msgs); ctx.write(msg);
}
@Override
public void messageReceivedLast(ChannelHandlerContext ctx) throws Exception {
ctx.flush();
} }
} }

View File

@ -60,7 +60,7 @@ public class SecureChatClient {
} }
// Sends the received line to the server. // Sends the received line to the server.
lastWriteFuture = ch.write(line + "\r\n"); lastWriteFuture = ch.write(line + "\r\n").flush();
// If user typed the 'bye' command, wait until the server closes // If user typed the 'bye' command, wait until the server closes
// the connection. // the connection.

View File

@ -30,7 +30,7 @@ public class SecureChatClientHandler extends SimpleChannelInboundHandler<String>
SecureChatClientHandler.class.getName()); SecureChatClientHandler.class.getName());
@Override @Override
public void messageReceived(ChannelHandlerContext ctx, String msg) throws Exception { public void messageReceived0(ChannelHandlerContext ctx, String msg) throws Exception {
System.err.println(msg); System.err.println(msg);
} }

View File

@ -61,7 +61,7 @@ public class SecureChatServerHandler extends SimpleChannelInboundHandler<String>
} }
@Override @Override
public void messageReceived(ChannelHandlerContext ctx, String msg) throws Exception { public void messageReceived0(ChannelHandlerContext ctx, String msg) throws Exception {
// Send the received message to all channels but the current one. // Send the received message to all channels but the current one.
for (Channel c: channels) { for (Channel c: channels) {
if (c != ctx.channel()) { if (c != ctx.channel()) {

View File

@ -19,7 +19,7 @@ import io.netty.buffer.Unpooled;
import io.netty.channel.Channel; import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter; import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.MessageList; import io.netty.util.ReferenceCountUtil;
public final class RelayHandler extends ChannelInboundHandlerAdapter { public final class RelayHandler extends ChannelInboundHandlerAdapter {
@ -41,9 +41,11 @@ public final class RelayHandler extends ChannelInboundHandlerAdapter {
} }
@Override @Override
public void messageReceived(ChannelHandlerContext ctx, MessageList<Object> msgs) throws Exception { public void messageReceived(ChannelHandlerContext ctx, Object msg) throws Exception {
if (relayChannel.isActive()) { if (relayChannel.isActive()) {
relayChannel.write(msgs); relayChannel.write(msg).flush();
} else {
ReferenceCountUtil.release(msg);
} }
} }

View File

@ -39,11 +39,11 @@ public final class SocksServerConnectHandler extends SimpleChannelInboundHandler
private final Bootstrap b = new Bootstrap(); private final Bootstrap b = new Bootstrap();
@Override @Override
public void messageReceived(final ChannelHandlerContext ctx, final SocksCmdRequest request) throws Exception { public void messageReceived0(final ChannelHandlerContext ctx, final SocksCmdRequest request) throws Exception {
CallbackNotifier cb = new CallbackNotifier() { CallbackNotifier cb = new CallbackNotifier() {
@Override @Override
public void onSuccess(final ChannelHandlerContext outboundCtx) { public void onSuccess(final ChannelHandlerContext outboundCtx) {
ctx.channel().write(new SocksCmdResponse(SocksCmdStatus.SUCCESS, request.addressType())) ctx.channel().write(new SocksCmdResponse(SocksCmdStatus.SUCCESS, request.addressType())).flush()
.addListener(new ChannelFutureListener() { .addListener(new ChannelFutureListener() {
@Override @Override
public void operationComplete(ChannelFuture channelFuture) throws Exception { public void operationComplete(ChannelFuture channelFuture) throws Exception {

View File

@ -37,7 +37,7 @@ public final class SocksServerHandler extends SimpleChannelInboundHandler<SocksR
} }
@Override @Override
public void messageReceived(ChannelHandlerContext ctx, SocksRequest socksRequest) throws Exception { public void messageReceived0(ChannelHandlerContext ctx, SocksRequest socksRequest) throws Exception {
switch (socksRequest.requestType()) { switch (socksRequest.requestType()) {
case INIT: { case INIT: {
// auth support example // auth support example

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