Synchronized between 4.1 and master

Motivation:

4 and 5 were diverged long time ago and we recently reverted some of the
early commits in master.  We must make sure 4.1 and master are not very
different now.

Modification:

Fix found differences

Result:

4.1 and master got closer.
This commit is contained in:
Trustin Lee 2014-04-24 21:13:19 +09:00
parent 65ee10fbd0
commit db3709e652
54 changed files with 242 additions and 186 deletions

View File

@ -22,4 +22,5 @@ Note that this is build-time requirement. JDK 5 (for 3.x) or 6 (for 4.0+) is en
## Branches to look
[The 'master' branch](https://github.com/netty/netty/tree/master) is where the development of the latest major version lives on. The development of all other major versions takes place in each branch whose name is identical to its major version number. For example, the development of 3.x and 4.x resides in [the branch '3'](https://github.com/netty/netty/tree/3) and [the branch '4'](https://github.com/netty/netty/tree/4) respectively.
[The 'master' branch](https://github.com/netty/netty/tree/master) is where the development of the latest major version lives on. The development of all other versions takes place in each branch whose name is identical to `<majorVersion>.<minorVersion>`. For example, the development of 3.9 and 4.0 resides in [the branch '3.9'](https://github.com/netty/netty/tree/3.9) and [the branch '4.0'](https://github.com/netty/netty/tree/4.0) respectively.

View File

@ -714,7 +714,7 @@ final class AdvancedLeakAwareByteBuf extends WrappedByteBuf {
@Override
public boolean release() {
boolean deallocated = super.release();
boolean deallocated = super.release();
if (deallocated) {
leak.close();
} else {

View File

@ -27,7 +27,7 @@ import java.nio.channels.GatheringByteChannel;
import java.nio.channels.ScatteringByteChannel;
import java.nio.charset.Charset;
class WrappedByteBuf extends ByteBuf {
public class WrappedByteBuf extends ByteBuf {
protected final ByteBuf buf;

View File

@ -75,13 +75,13 @@
* type.
* <pre>
* // The composite type is compatible with the component type.
* {@link ByteBuf} message = {@link Unpooled}.wrappedBuffer(header, body);
* {@link io.netty.buffer.ByteBuf} message = {@link io.netty.buffer.Unpooled}.wrappedBuffer(header, body);
*
* // Therefore, you can even create a composite by mixing a composite and an
* // ordinary buffer.
* {@link ByteBuf} messageWithFooter = {@link Unpooled}.wrappedBuffer(message, footer);
* {@link io.netty.buffer.ByteBuf} messageWithFooter = {@link io.netty.buffer.Unpooled}.wrappedBuffer(message, footer);
*
* // Because the composite is still a {@link ByteBuf}, you can access its content
* // Because the composite is still a {@link io.netty.buffer.ByteBuf}, you can access its content
* // easily, and the accessor method will behave just like it's a single buffer
* // even if the region you want to access spans over multiple components. The
* // unsigned integer being read here is located across body and footer.
@ -100,7 +100,7 @@
* <pre>
* // A new dynamic buffer is created. Internally, the actual buffer is created
* // lazily to avoid potentially wasted memory space.
* {@link ByteBuf} b = {@link Unpooled}.buffer(4);
* {@link io.netty.buffer.ByteBuf} b = {@link io.netty.buffer.Unpooled}.buffer(4);
*
* // When the first write attempt is made, the internal buffer is created with
* // the specified initial capacity (4).

View File

@ -381,6 +381,14 @@ public class DefaultHttpHeaders extends HttpHeaders {
return names;
}
void encode(ByteBuf buf) {
HeaderEntry e = head.after;
while (e != head) {
e.encode(buf);
e = e.after;
}
}
private static CharSequence toCharSequence(Object value) {
if (value == null) {
return null;
@ -400,14 +408,6 @@ public class DefaultHttpHeaders extends HttpHeaders {
return value.toString();
}
void encode(ByteBuf buf) {
HeaderEntry e = head.after;
while (e != head) {
e.encode(buf);
e = e.after;
}
}
private final class HeaderIterator implements Iterator<Map.Entry<String, String>> {
private HeaderEntry current = head;

View File

@ -34,12 +34,15 @@ public abstract class DefaultHttpMessage extends DefaultHttpObject implements Ht
this(version, true);
}
protected DefaultHttpMessage(final HttpVersion version, boolean validate) {
/**
* Creates a new instance.
*/
protected DefaultHttpMessage(final HttpVersion version, boolean validateHeaders) {
if (version == null) {
throw new NullPointerException("version");
}
this.version = version;
headers = new DefaultHttpHeaders(validate);
headers = new DefaultHttpHeaders(validateHeaders);
}
@Override

View File

@ -42,7 +42,7 @@ public class DefaultHttpRequest extends DefaultHttpMessage implements HttpReques
* @param httpVersion the HTTP version of the request
* @param method the HTTP getMethod of the request
* @param uri the URI or path of the request
* @param validateHeaders validate the headers when adding them
* @param validateHeaders validate the header names and values when adding them to the {@link HttpHeaders}
*/
public DefaultHttpRequest(HttpVersion httpVersion, HttpMethod method, String uri, boolean validateHeaders) {
super(httpVersion, validateHeaders);

View File

@ -39,7 +39,7 @@ public class DefaultHttpResponse extends DefaultHttpMessage implements HttpRespo
*
* @param version the HTTP version of this response
* @param status the getStatus of this response
* @param validateHeaders validate the headers when adding them
* @param validateHeaders validate the header names and values when adding them to the {@link HttpHeaders}
*/
public DefaultHttpResponse(HttpVersion version, HttpResponseStatus status, boolean validateHeaders) {
super(version, validateHeaders);

View File

@ -114,9 +114,9 @@ public class DefaultLastHttpContent extends DefaultHttpContent implements LastHt
@Override
void validateHeaderName0(CharSequence name) {
super.validateHeaderName0(name);
if (HttpHeaders.equalsIgnoreCase(HttpHeaders.Names.CONTENT_LENGTH, name) ||
HttpHeaders.equalsIgnoreCase(HttpHeaders.Names.TRANSFER_ENCODING, name) ||
HttpHeaders.equalsIgnoreCase(HttpHeaders.Names.TRAILER, name)) {
if (equalsIgnoreCase(HttpHeaders.Names.CONTENT_LENGTH, name) ||
equalsIgnoreCase(HttpHeaders.Names.TRANSFER_ENCODING, name) ||
equalsIgnoreCase(HttpHeaders.Names.TRAILER, name)) {
throw new IllegalArgumentException(
"prohibited trailing header: " + name);
}

View File

@ -149,8 +149,8 @@ public class HttpMethod implements Comparable<HttpMethod> {
}
for (int i = 0; i < name.length(); i ++) {
if (Character.isISOControl(name.charAt(i)) ||
Character.isWhitespace(name.charAt(i))) {
char c = name.charAt(i);
if (Character.isISOControl(c) || Character.isWhitespace(c)) {
throw new IllegalArgumentException("invalid character in name");
}
}

View File

@ -213,8 +213,7 @@ public class HttpResponseStatus implements Comparable<HttpResponseStatus> {
/**
* 417 Expectation Failed
*/
public static final HttpResponseStatus EXPECTATION_FAILED =
new HttpResponseStatus(417, "Expectation Failed", true);
public static final HttpResponseStatus EXPECTATION_FAILED = new HttpResponseStatus(417, "Expectation Failed", true);
/**
* 422 Unprocessable Entity (WebDAV, RFC4918)
@ -225,8 +224,7 @@ public class HttpResponseStatus implements Comparable<HttpResponseStatus> {
/**
* 423 Locked (WebDAV, RFC4918)
*/
public static final HttpResponseStatus LOCKED =
new HttpResponseStatus(423, "Locked", true);
public static final HttpResponseStatus LOCKED = new HttpResponseStatus(423, "Locked", true);
/**
* 424 Failed Dependency (WebDAV, RFC4918)

View File

@ -198,13 +198,13 @@ public class WebSocketClientHandshaker00 extends WebSocketClientHandshaker {
HttpHeaders headers = response.headers();
String upgrade = headers.get(Names.UPGRADE);
if (!Values.WEBSOCKET.equalsIgnoreCase(upgrade)) {
if (!HttpHeaders.equalsIgnoreCase(Values.WEBSOCKET, upgrade)) {
throw new WebSocketHandshakeException("Invalid handshake response upgrade: "
+ upgrade);
}
String connection = headers.get(Names.CONNECTION);
if (!Values.UPGRADE.equalsIgnoreCase(connection)) {
if (!HttpHeaders.equalsIgnoreCase(Values.UPGRADE, connection)) {
throw new WebSocketHandshakeException("Invalid handshake response connection: "
+ connection);
}

View File

@ -40,7 +40,7 @@ import java.net.URI;
public class WebSocketClientHandshaker07 extends WebSocketClientHandshaker {
private static final InternalLogger logger = InternalLoggerFactory.getInstance(WebSocketClientHandshaker07.class);
private static final CharSequence WEBSOCKET = HttpHeaders.newEntity(Values.WEBSOCKET.toLowerCase());
public static final String MAGIC_GUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
private String expectedChallengeResponseString;
@ -119,7 +119,7 @@ public class WebSocketClientHandshaker07 extends WebSocketClientHandshaker {
FullHttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, path);
HttpHeaders headers = request.headers();
headers.add(Names.UPGRADE, Values.WEBSOCKET.toLowerCase())
headers.add(Names.UPGRADE, WEBSOCKET)
.add(Names.CONNECTION, Values.UPGRADE)
.add(Names.SEC_WEBSOCKET_KEY, key)
.add(Names.HOST, wsURL.getHost());
@ -173,12 +173,12 @@ public class WebSocketClientHandshaker07 extends WebSocketClientHandshaker {
}
String upgrade = headers.get(Names.UPGRADE);
if (!Values.WEBSOCKET.equalsIgnoreCase(upgrade)) {
if (!HttpHeaders.equalsIgnoreCase(Values.WEBSOCKET, upgrade)) {
throw new WebSocketHandshakeException("Invalid handshake response upgrade: " + upgrade);
}
String connection = headers.get(Names.CONNECTION);
if (!Values.UPGRADE.equalsIgnoreCase(connection)) {
if (!HttpHeaders.equalsIgnoreCase(Values.UPGRADE, connection)) {
throw new WebSocketHandshakeException("Invalid handshake response connection: " + connection);
}

View File

@ -40,6 +40,7 @@ import java.net.URI;
public class WebSocketClientHandshaker08 extends WebSocketClientHandshaker {
private static final InternalLogger logger = InternalLoggerFactory.getInstance(WebSocketClientHandshaker08.class);
private static final CharSequence WEBSOCKET = HttpHeaders.newEntity(Values.WEBSOCKET.toLowerCase());
public static final String MAGIC_GUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
@ -119,7 +120,7 @@ public class WebSocketClientHandshaker08 extends WebSocketClientHandshaker {
FullHttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, path);
HttpHeaders headers = request.headers();
headers.add(Names.UPGRADE, Values.WEBSOCKET.toLowerCase())
headers.add(Names.UPGRADE, WEBSOCKET)
.add(Names.CONNECTION, Values.UPGRADE)
.add(Names.SEC_WEBSOCKET_KEY, key)
.add(Names.HOST, wsURL.getHost());
@ -173,12 +174,12 @@ public class WebSocketClientHandshaker08 extends WebSocketClientHandshaker {
}
String upgrade = headers.get(Names.UPGRADE);
if (!Values.WEBSOCKET.equalsIgnoreCase(upgrade)) {
if (!HttpHeaders.equalsIgnoreCase(Values.WEBSOCKET, upgrade)) {
throw new WebSocketHandshakeException("Invalid handshake response upgrade: " + upgrade);
}
String connection = headers.get(Names.CONNECTION);
if (!Values.UPGRADE.equalsIgnoreCase(connection)) {
if (!HttpHeaders.equalsIgnoreCase(Values.UPGRADE, connection)) {
throw new WebSocketHandshakeException("Invalid handshake response connection: " + connection);
}

View File

@ -40,6 +40,7 @@ import java.net.URI;
public class WebSocketClientHandshaker13 extends WebSocketClientHandshaker {
private static final InternalLogger logger = InternalLoggerFactory.getInstance(WebSocketClientHandshaker13.class);
private static final CharSequence WEBSOCKET = HttpHeaders.newEntity(Values.WEBSOCKET.toLowerCase());
public static final String MAGIC_GUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
@ -130,7 +131,7 @@ public class WebSocketClientHandshaker13 extends WebSocketClientHandshaker {
FullHttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, path);
HttpHeaders headers = request.headers();
headers.add(Names.UPGRADE, Values.WEBSOCKET.toLowerCase())
headers.add(Names.UPGRADE, WEBSOCKET)
.add(Names.CONNECTION, Values.UPGRADE)
.add(Names.SEC_WEBSOCKET_KEY, key)
.add(Names.HOST, wsURL.getHost() + ':' + wsPort);
@ -183,12 +184,12 @@ public class WebSocketClientHandshaker13 extends WebSocketClientHandshaker {
}
String upgrade = headers.get(Names.UPGRADE);
if (!Values.WEBSOCKET.equalsIgnoreCase(upgrade)) {
if (!HttpHeaders.equalsIgnoreCase(Values.WEBSOCKET, upgrade)) {
throw new WebSocketHandshakeException("Invalid handshake response upgrade: " + upgrade);
}
String connection = headers.get(Names.CONNECTION);
if (!Values.UPGRADE.equalsIgnoreCase(connection)) {
if (!HttpHeaders.equalsIgnoreCase(Values.UPGRADE, connection)) {
throw new WebSocketHandshakeException("Invalid handshake response connection: " + connection);
}

View File

@ -109,8 +109,8 @@ public class WebSocketServerHandshaker00 extends WebSocketServerHandshaker {
protected FullHttpResponse newHandshakeResponse(FullHttpRequest req, HttpHeaders headers) {
// Serve the WebSocket handshake request.
if (!Values.UPGRADE.equalsIgnoreCase(req.headers().get(CONNECTION))
|| !WEBSOCKET.equalsIgnoreCase(req.headers().get(Names.UPGRADE))) {
if (!HttpHeaders.equalsIgnoreCase(Values.UPGRADE, req.headers().get(CONNECTION))
|| !HttpHeaders.equalsIgnoreCase(WEBSOCKET, req.headers().get(Names.UPGRADE))) {
throw new WebSocketHandshakeException("not a WebSocket handshake request: missing upgrade");
}

View File

@ -20,10 +20,10 @@ import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.FullHttpResponse;
import io.netty.handler.codec.http.HttpHeaders;
import io.netty.handler.codec.http.HttpHeaders.Names;
import io.netty.handler.codec.http.HttpHeaders.Values;
import io.netty.handler.codec.http.HttpResponseStatus;
import io.netty.util.CharsetUtil;
import static io.netty.handler.codec.http.HttpHeaders.Values.*;
import static io.netty.handler.codec.http.HttpVersion.*;
/**
@ -35,6 +35,8 @@ import static io.netty.handler.codec.http.HttpVersion.*;
*/
public class WebSocketServerHandshaker07 extends WebSocketServerHandshaker {
private static final CharSequence WEBSOCKET = HttpHeaders.newEntity(Values.WEBSOCKET.toLowerCase());
public static final String WEBSOCKET_07_ACCEPT_GUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
private final boolean allowExtensions;
@ -114,7 +116,7 @@ public class WebSocketServerHandshaker07 extends WebSocketServerHandshaker {
logger.debug("WebSocket version 07 server handshake key: {}, response: {}.", key, accept);
}
res.headers().add(Names.UPGRADE, WEBSOCKET.toLowerCase());
res.headers().add(Names.UPGRADE, WEBSOCKET);
res.headers().add(Names.CONNECTION, Names.UPGRADE);
res.headers().add(Names.SEC_WEBSOCKET_ACCEPT, accept);
String subprotocols = req.headers().get(Names.SEC_WEBSOCKET_PROTOCOL);

View File

@ -20,10 +20,10 @@ import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.FullHttpResponse;
import io.netty.handler.codec.http.HttpHeaders;
import io.netty.handler.codec.http.HttpHeaders.Names;
import io.netty.handler.codec.http.HttpHeaders.Values;
import io.netty.handler.codec.http.HttpResponseStatus;
import io.netty.util.CharsetUtil;
import static io.netty.handler.codec.http.HttpHeaders.Values.*;
import static io.netty.handler.codec.http.HttpVersion.*;
/**
@ -35,6 +35,8 @@ import static io.netty.handler.codec.http.HttpVersion.*;
*/
public class WebSocketServerHandshaker08 extends WebSocketServerHandshaker {
private static final CharSequence WEBSOCKET = HttpHeaders.newEntity(Values.WEBSOCKET.toLowerCase());
public static final String WEBSOCKET_08_ACCEPT_GUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
private final boolean allowExtensions;
@ -113,7 +115,7 @@ public class WebSocketServerHandshaker08 extends WebSocketServerHandshaker {
logger.debug("WebSocket version 08 server handshake key: {}, response: {}", key, accept);
}
res.headers().add(Names.UPGRADE, WEBSOCKET.toLowerCase());
res.headers().add(Names.UPGRADE, WEBSOCKET);
res.headers().add(Names.CONNECTION, Names.UPGRADE);
res.headers().add(Names.SEC_WEBSOCKET_ACCEPT, accept);
String subprotocols = req.headers().get(Names.SEC_WEBSOCKET_PROTOCOL);

View File

@ -20,10 +20,10 @@ import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.FullHttpResponse;
import io.netty.handler.codec.http.HttpHeaders;
import io.netty.handler.codec.http.HttpHeaders.Names;
import io.netty.handler.codec.http.HttpHeaders.Values;
import io.netty.handler.codec.http.HttpResponseStatus;
import io.netty.util.CharsetUtil;
import static io.netty.handler.codec.http.HttpHeaders.Values.*;
import static io.netty.handler.codec.http.HttpVersion.*;
/**
@ -34,6 +34,8 @@ import static io.netty.handler.codec.http.HttpVersion.*;
*/
public class WebSocketServerHandshaker13 extends WebSocketServerHandshaker {
private static final CharSequence WEBSOCKET = HttpHeaders.newEntity(Values.WEBSOCKET.toLowerCase());
public static final String WEBSOCKET_13_ACCEPT_GUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
private final boolean allowExtensions;
@ -111,7 +113,7 @@ public class WebSocketServerHandshaker13 extends WebSocketServerHandshaker {
logger.debug("WebSocket version 13 server handshake key: {}, response: {}", key, accept);
}
res.headers().add(Names.UPGRADE, WEBSOCKET.toLowerCase());
res.headers().add(Names.UPGRADE, WEBSOCKET);
res.headers().add(Names.CONNECTION, Names.UPGRADE);
res.headers().add(Names.SEC_WEBSOCKET_ACCEPT, accept);
String subprotocols = req.headers().get(Names.SEC_WEBSOCKET_PROTOCOL);

View File

@ -17,6 +17,7 @@ package io.netty.handler.codec.rtsp;
import io.netty.buffer.ByteBuf;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.HttpHeaders;
import io.netty.handler.codec.http.HttpRequest;
import io.netty.util.CharsetUtil;
@ -38,11 +39,11 @@ public class RtspRequestEncoder extends RtspObjectEncoder<HttpRequest> {
@Override
protected void encodeInitialLine(ByteBuf buf, HttpRequest request)
throws Exception {
encodeAscii(request.getMethod().toString(), buf);
HttpHeaders.encodeAscii(request.getMethod().toString(), buf);
buf.writeByte(SP);
buf.writeBytes(request.getUri().getBytes(CharsetUtil.UTF_8));
buf.writeByte(SP);
encodeAscii(request.getProtocolVersion().toString(), buf);
HttpHeaders.encodeAscii(request.getProtocolVersion().toString(), buf);
buf.writeBytes(CRLF);
}
}

View File

@ -17,6 +17,7 @@ package io.netty.handler.codec.rtsp;
import io.netty.buffer.ByteBuf;
import io.netty.handler.codec.http.FullHttpResponse;
import io.netty.handler.codec.http.HttpHeaders;
import io.netty.handler.codec.http.HttpResponse;
import io.netty.util.CharsetUtil;
@ -38,11 +39,11 @@ public class RtspResponseEncoder extends RtspObjectEncoder<HttpResponse> {
@Override
protected void encodeInitialLine(ByteBuf buf, HttpResponse response)
throws Exception {
encodeAscii(response.getProtocolVersion().toString(), buf);
HttpHeaders.encodeAscii(response.getProtocolVersion().toString(), buf);
buf.writeByte(SP);
buf.writeBytes(String.valueOf(response.getStatus().code()).getBytes(CharsetUtil.US_ASCII));
buf.writeByte(SP);
encodeAscii(String.valueOf(response.getStatus().reasonPhrase()), buf);
HttpHeaders.encodeAscii(String.valueOf(response.getStatus().reasonPhrase()), buf);
buf.writeBytes(CRLF);
}
}

View File

@ -16,7 +16,6 @@
package io.netty.handler.codec.spdy;
import io.netty.buffer.ByteBuf;
import io.netty.util.CharsetUtil;
final class SpdyCodecUtil {

View File

@ -24,13 +24,12 @@ import io.netty.util.internal.EmptyArrays;
import java.util.concurrent.atomic.AtomicInteger;
import static io.netty.handler.codec.spdy.SpdyCodecUtil.SPDY_SESSION_STREAM_ID;
import static io.netty.handler.codec.spdy.SpdyCodecUtil.*;
/**
* Manages streams within a SPDY session.
*/
public class SpdySessionHandler
extends ChannelDuplexHandler {
public class SpdySessionHandler extends ChannelDuplexHandler {
private static final SpdyProtocolException PROTOCOL_EXCEPTION = new SpdyProtocolException();
private static final SpdyProtocolException STREAM_CLOSED = new SpdyProtocolException("Stream closed");

View File

@ -15,8 +15,6 @@
*/
package io.netty.handler.codec.http;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import io.netty.buffer.ByteBuf;
import io.netty.channel.embedded.EmbeddedChannel;
import io.netty.handler.stream.ChunkedFile;
@ -25,6 +23,7 @@ import io.netty.handler.stream.ChunkedNioFile;
import io.netty.handler.stream.ChunkedNioStream;
import io.netty.handler.stream.ChunkedStream;
import io.netty.handler.stream.ChunkedWriteHandler;
import org.junit.Test;
import java.io.ByteArrayInputStream;
import java.io.File;
@ -32,7 +31,7 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.Channels;
import org.junit.Test;
import static org.junit.Assert.*;
public class HttpChunkedInputTest {
private static final byte[] BYTES = new byte[1024 * 64];
@ -96,7 +95,7 @@ public class HttpChunkedInputTest {
int read = 0;
HttpContent lastHttpContent = null;
for (;;) {
HttpContent httpContent = (HttpContent) ch.readOutbound();
HttpContent httpContent = ch.readOutbound();
if (httpContent == null) {
break;
} else {

View File

@ -265,6 +265,33 @@ public class HttpResponseDecoderTest {
assertThat(ch.readInbound(), is(nullValue()));
}
@Test
public void testLastResponseWithHeaderRemoveTrailingSpaces() {
EmbeddedChannel ch = new EmbeddedChannel(new HttpResponseDecoder());
ch.writeInbound(Unpooled.copiedBuffer(
"HTTP/1.1 200 OK\r\nX-Header: h2=h2v2; Expires=Wed, 09-Jun-2021 10:18:14 GMT \r\n\r\n",
CharsetUtil.US_ASCII));
HttpResponse res = ch.readInbound();
assertThat(res.getProtocolVersion(), sameInstance(HttpVersion.HTTP_1_1));
assertThat(res.getStatus(), is(HttpResponseStatus.OK));
assertThat(res.headers().get("X-Header"), is("h2=h2v2; Expires=Wed, 09-Jun-2021 10:18:14 GMT"));
assertThat(ch.readInbound(), is(nullValue()));
ch.writeInbound(Unpooled.wrappedBuffer(new byte[1024]));
HttpContent content = ch.readInbound();
assertThat(content.content().readableBytes(), is(1024));
content.release();
assertThat(ch.finish(), is(true));
LastHttpContent lastContent = ch.readInbound();
assertThat(lastContent.content().isReadable(), is(false));
lastContent.release();
assertThat(ch.readInbound(), is(nullValue()));
}
@Test
public void testLastResponseWithTrailingHeader() {
EmbeddedChannel ch = new EmbeddedChannel(new HttpResponseDecoder());

View File

@ -240,11 +240,9 @@ public class CorsHandlerTest {
}
private static class EchoHandler extends SimpleChannelInboundHandler<Object> {
@Override
public void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {
ctx.writeAndFlush(new DefaultHttpResponse(HTTP_1_1, HttpResponseStatus.OK));
}
}
}

View File

@ -75,6 +75,7 @@ public class WebSocketServerHandshaker00Test {
HttpResponse res = ch2.readInbound();
Assert.assertEquals("ws://example.com/chat", res.headers().get(Names.SEC_WEBSOCKET_LOCATION));
if (subProtocol) {
Assert.assertEquals("chat", res.headers().get(Names.SEC_WEBSOCKET_PROTOCOL));
} else {

View File

@ -18,7 +18,6 @@ package io.netty.handler.codec.compression;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import java.nio.ByteOrder;
import java.util.List;
import java.util.zip.CRC32;
import java.util.zip.DataFormatException;

View File

@ -30,7 +30,6 @@ import static io.netty.util.concurrent.AbstractEventExecutor.*;
* Abstract base class for {@link EventExecutorGroup} implementations.
*/
public abstract class AbstractEventExecutorGroup implements EventExecutorGroup {
@Override
public Future<?> submit(Runnable task) {
return next().submit(task);

View File

@ -20,7 +20,7 @@ import java.util.concurrent.ThreadFactory;
/**
* Default {@link SingleThreadEventExecutor} implementation which just execute all submitted task in a
* serial fashion
* serial fashion.
*/
public final class DefaultEventExecutor extends SingleThreadEventExecutor {

View File

@ -21,13 +21,14 @@ import java.util.concurrent.TimeUnit;
* {@link AbstractEventExecutor} which execute tasks in the callers thread.
*/
public final class ImmediateEventExecutor extends AbstractEventExecutor {
public static final ImmediateEventExecutor INSTANCE = new ImmediateEventExecutor();
private final Future<?> terminationFuture = new FailedFuture<Object>(
GlobalEventExecutor.INSTANCE, new UnsupportedOperationException());
private ImmediateEventExecutor() {
// use static instance
// Singleton
}
@Override

View File

@ -88,7 +88,7 @@ public class HttpUploadServerHandler extends SimpleChannelInboundHandler<HttpObj
}
@Override
public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
if (decoder != null) {
decoder.cleanFiles();
}
@ -286,9 +286,9 @@ public class HttpUploadServerHandler extends SimpleChannelInboundHandler<HttpObj
responseContent.setLength(0);
// Decide whether to close the connection or not.
boolean close = HttpHeaders.Values.CLOSE.equalsIgnoreCase(request.headers().get(CONNECTION))
boolean close = request.headers().contains(CONNECTION, HttpHeaders.Values.CLOSE, true)
|| request.getProtocolVersion().equals(HttpVersion.HTTP_1_0)
&& !HttpHeaders.Values.KEEP_ALIVE.equalsIgnoreCase(request.headers().get(CONNECTION));
&& !request.headers().contains(CONNECTION, HttpHeaders.Values.KEEP_ALIVE, true);
// Build the response object.
FullHttpResponse response = new DefaultFullHttpResponse(

View File

@ -67,25 +67,26 @@ public final class SocksServerConnectHandler extends SimpleChannelInboundHandler
});
final Channel inboundChannel = ctx.channel();
b.group(inboundChannel.eventLoop())
.channel(NioSocketChannel.class)
.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 10000)
.option(ChannelOption.SO_KEEPALIVE, true)
.handler(new DirectClientInitializer(promise));
b.connect(request.host(), request.port())
.addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) throws Exception {
if (future.isSuccess()) {
// Connection established use handler provided results
} else {
// Close the connection if the connection attempt has failed.
ctx.channel().writeAndFlush(
new SocksCmdResponse(SocksCmdStatus.FAILURE, request.addressType()));
SocksServerUtils.closeOnFlush(ctx.channel());
}
b.connect(request.host(), request.port()).addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) throws Exception {
if (future.isSuccess()) {
// Connection established use handler provided results
} else {
// Close the connection if the connection attempt has failed.
ctx.channel().writeAndFlush(
new SocksCmdResponse(SocksCmdStatus.FAILURE, request.addressType()));
SocksServerUtils.closeOnFlush(ctx.channel());
}
});
}
});
}
@Override

View File

@ -67,6 +67,7 @@ public class SpdyServer {
}
public static void main(String[] args) throws Exception {
checkForNpnSupport();
int port;
if (args.length > 0) {
port = Integer.parseInt(args[0]);
@ -80,4 +81,18 @@ public class SpdyServer {
new SpdyServer(port).run();
}
private static void checkForNpnSupport() {
try {
Class.forName("sun.security.ssl.NextProtoNegoExtension");
} catch (ClassNotFoundException ignored) {
System.err.println();
System.err.println("Could not locate Next Protocol Negotiation (NPN) implementation.");
System.err.println("The NPN jar should have been made available when building the examples with maven.");
System.err.println("Please check that your JDK is among those supported by Jetty-NPN:");
System.err.println("http://wiki.eclipse.org/Jetty/Feature/NPN#Versions");
System.err.println();
throw new IllegalStateException("Could not locate NPN implementation. See console err for details.");
}
}
}

View File

@ -62,10 +62,10 @@ public class UptimeClient {
.channel(NioSocketChannel.class)
.remoteAddress(host, port)
.handler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(new IdleStateHandler(READ_TIMEOUT, 0, 0), handler);
}
@Override
public void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(new IdleStateHandler(READ_TIMEOUT, 0, 0), handler);
}
});
return b;

View File

@ -68,13 +68,9 @@ public class UptimeClientHandler extends SimpleChannelInboundHandler<Object> {
}
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
public void channelInactive(final ChannelHandlerContext ctx) throws Exception {
println("Disconnected from: " + ctx.channel().remoteAddress());
}
@Override
public void channelUnregistered(final ChannelHandlerContext ctx)
throws Exception {
println("Sleeping for: " + UptimeClient.RECONNECT_DELAY + 's');
final EventLoop loop = ctx.channel().eventLoop();

View File

@ -17,6 +17,9 @@ package io.netty.handler.logging;
import io.netty.util.internal.logging.InternalLogLevel;
/**
* Maps the regular {@link LogLevel}s with the {@link InternalLogLevel} ones.
*/
public enum LogLevel {
TRACE(InternalLogLevel.TRACE),
DEBUG(InternalLogLevel.DEBUG),
@ -30,6 +33,11 @@ public enum LogLevel {
this.internalLevel = internalLevel;
}
/**
* Converts the specified {@link LogLevel} to its {@link InternalLogLevel} variant.
*
* @return the converted level.
*/
InternalLogLevel toInternalLevel() {
return internalLevel;
}

View File

@ -35,6 +35,7 @@ import java.net.SocketAddress;
* By default, all events are logged at <tt>DEBUG</tt> level.
*/
@Sharable
@SuppressWarnings("StringConcatenationInsideStringBufferAppend")
public class LoggingHandler extends ChannelDuplexHandler {
private static final LogLevel DEFAULT_LEVEL = LogLevel.DEBUG;
@ -112,7 +113,7 @@ public class LoggingHandler extends ChannelDuplexHandler {
* Creates a new instance whose logger name is the fully qualified class
* name of the instance.
*
* @param level the log level
* @param level the log level
*/
public LoggingHandler(LogLevel level) {
if (level == null) {
@ -127,6 +128,8 @@ public class LoggingHandler extends ChannelDuplexHandler {
/**
* Creates a new instance with the specified logger name and with hex dump
* enabled.
*
* @param clazz the class type to generate the logger for
*/
public LoggingHandler(Class<?> clazz) {
this(clazz, DEFAULT_LEVEL);
@ -135,7 +138,8 @@ public class LoggingHandler extends ChannelDuplexHandler {
/**
* Creates a new instance with the specified logger name.
*
* @param level the log level
* @param clazz the class type to generate the logger for
* @param level the log level
*/
public LoggingHandler(Class<?> clazz, LogLevel level) {
if (clazz == null) {
@ -144,13 +148,16 @@ public class LoggingHandler extends ChannelDuplexHandler {
if (level == null) {
throw new NullPointerException("level");
}
logger = InternalLoggerFactory.getInstance(clazz);
this.level = level;
internalLevel = level.toInternalLevel();
}
/**
* Creates a new instance with the specified logger name.
* Creates a new instance with the specified logger name using the default log level.
*
* @param name the name of the class to use for the logger
*/
public LoggingHandler(String name) {
this(name, DEFAULT_LEVEL);
@ -159,7 +166,8 @@ public class LoggingHandler extends ChannelDuplexHandler {
/**
* Creates a new instance with the specified logger name.
*
* @param level the log level
* @param name the name of the class to use for the logger
* @param level the log level
*/
public LoggingHandler(String name, LogLevel level) {
if (name == null) {
@ -168,6 +176,7 @@ public class LoggingHandler extends ChannelDuplexHandler {
if (level == null) {
throw new NullPointerException("level");
}
logger = InternalLoggerFactory.getInstance(name);
this.level = level;
internalLevel = level.toInternalLevel();
@ -181,8 +190,7 @@ public class LoggingHandler extends ChannelDuplexHandler {
}
@Override
public void channelRegistered(ChannelHandlerContext ctx)
throws Exception {
public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
if (logger.isEnabled(internalLevel)) {
logger.log(internalLevel, format(ctx, "REGISTERED"));
}
@ -190,8 +198,7 @@ public class LoggingHandler extends ChannelDuplexHandler {
}
@Override
public void channelUnregistered(ChannelHandlerContext ctx)
throws Exception {
public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
if (logger.isEnabled(internalLevel)) {
logger.log(internalLevel, format(ctx, "UNREGISTERED"));
}
@ -199,8 +206,7 @@ public class LoggingHandler extends ChannelDuplexHandler {
}
@Override
public void channelActive(ChannelHandlerContext ctx)
throws Exception {
public void channelActive(ChannelHandlerContext ctx) throws Exception {
if (logger.isEnabled(internalLevel)) {
logger.log(internalLevel, format(ctx, "ACTIVE"));
}
@ -208,8 +214,7 @@ public class LoggingHandler extends ChannelDuplexHandler {
}
@Override
public void channelInactive(ChannelHandlerContext ctx)
throws Exception {
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
if (logger.isEnabled(internalLevel)) {
logger.log(internalLevel, format(ctx, "INACTIVE"));
}
@ -217,8 +222,7 @@ public class LoggingHandler extends ChannelDuplexHandler {
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx,
Throwable cause) throws Exception {
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
if (logger.isEnabled(internalLevel)) {
logger.log(internalLevel, format(ctx, "EXCEPTION", cause), cause);
}
@ -226,8 +230,7 @@ public class LoggingHandler extends ChannelDuplexHandler {
}
@Override
public void userEventTriggered(ChannelHandlerContext ctx,
Object evt) throws Exception {
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
if (logger.isEnabled(internalLevel)) {
logger.log(internalLevel, format(ctx, "USER_EVENT", evt));
}
@ -235,8 +238,7 @@ public class LoggingHandler extends ChannelDuplexHandler {
}
@Override
public void bind(ChannelHandlerContext ctx,
SocketAddress localAddress, ChannelPromise promise) throws Exception {
public void bind(ChannelHandlerContext ctx, SocketAddress localAddress, ChannelPromise promise) throws Exception {
if (logger.isEnabled(internalLevel)) {
logger.log(internalLevel, format(ctx, "BIND", localAddress));
}
@ -244,9 +246,9 @@ public class LoggingHandler extends ChannelDuplexHandler {
}
@Override
public void connect(ChannelHandlerContext ctx,
SocketAddress remoteAddress, SocketAddress localAddress,
ChannelPromise promise) throws Exception {
public void connect(
ChannelHandlerContext ctx,
SocketAddress remoteAddress, SocketAddress localAddress, ChannelPromise promise) throws Exception {
if (logger.isEnabled(internalLevel)) {
logger.log(internalLevel, format(ctx, "CONNECT", remoteAddress, localAddress));
}
@ -254,8 +256,7 @@ public class LoggingHandler extends ChannelDuplexHandler {
}
@Override
public void disconnect(ChannelHandlerContext ctx,
ChannelPromise promise) throws Exception {
public void disconnect(ChannelHandlerContext ctx, ChannelPromise promise) throws Exception {
if (logger.isEnabled(internalLevel)) {
logger.log(internalLevel, format(ctx, "DISCONNECT"));
}
@ -263,8 +264,7 @@ public class LoggingHandler extends ChannelDuplexHandler {
}
@Override
public void close(ChannelHandlerContext ctx,
ChannelPromise promise) throws Exception {
public void close(ChannelHandlerContext ctx, ChannelPromise promise) throws Exception {
if (logger.isEnabled(internalLevel)) {
logger.log(internalLevel, format(ctx, "CLOSE"));
}
@ -272,8 +272,7 @@ public class LoggingHandler extends ChannelDuplexHandler {
}
@Override
public void deregister(ChannelHandlerContext ctx,
ChannelPromise promise) throws Exception {
public void deregister(ChannelHandlerContext ctx, ChannelPromise promise) throws Exception {
if (logger.isEnabled(internalLevel)) {
logger.log(internalLevel, format(ctx, "DEREGISTER"));
}

View File

@ -15,6 +15,6 @@
*/
/**
* Logs a {@link io.netty.channel.ChannelEvent} for debugging purpose.
* Logs the I/O events for debugging purpose.
*/
package io.netty.handler.logging;

View File

@ -23,20 +23,21 @@
*
* <p>Two classes implement this behavior:
* <ul>
* <li> <tt>{@link TrafficCounter}</tt>: this class implements the counters needed by the handlers.
* It can be accessed to get some extra information like the read or write bytes since last check, the read and write
* bandwidth from last check...</li>
* <li> <tt>{@link io.netty.handler.traffic.TrafficCounter}</tt>: this class implements the counters needed by the
* handlers. It can be accessed to get some extra information like the read or write bytes since last check,
* the read and write bandwidth from last check...</li>
*
* <li> <tt>{@link AbstractTrafficShapingHandler}</tt>: this abstract class implements the kernel
* of traffic shaping. It could be extended to fit your needs. Two classes are proposed as default
* implementations: see {@link ChannelTrafficShapingHandler} and see {@link GlobalTrafficShapingHandler}
* respectively for Channel traffic shaping and Global traffic shaping.</li>
* <li> <tt>{@link io.netty.handler.traffic.AbstractTrafficShapingHandler}</tt>: this abstract class implements
* the kernel of traffic shaping. It could be extended to fit your needs. Two classes are proposed as default
* implementations: see {@link io.netty.handler.traffic.ChannelTrafficShapingHandler} and
* see {@link io.netty.handler.traffic.GlobalTrafficShapingHandler} respectively for Channel traffic shaping and
* global traffic shaping.</li>
* </ul></p>
*
* <p>Both inbound and outbound traffic can be shaped independently. This is done by either passing in
* the desired limiting values to the constructors of both the Channel and Global traffic shaping handlers,
* or by calling the <tt>configure</tt> method on the {@link AbstractTrafficShapingHandler}. A value of
* 0 for either parameter indicates that there should be no limitation. This allows you to monitor the
* or by calling the <tt>configure</tt> method on the {@link io.netty.handler.traffic.AbstractTrafficShapingHandler}.
* A value of 0 for either parameter indicates that there should be no limitation. This allows you to monitor the
* incoming and outgoing traffic without shaping.</p>
*
* <p>To activate or deactivate the statistics, you can adjust the delay to a low (suggested not less than 200ms
@ -44,11 +45,13 @@
* or even using <tt>0</tt> which means no computation will be done.</p>
*
* <p>If you want to do anything with these statistics, just override the <tt>doAccounting</tt> method.<br>
* This interval can be changed either from the method <tt>configure</tt> in {@link AbstractTrafficShapingHandler}
* or directly using the method <tt>configure</tt> of {@link TrafficCounter}.</p>
* This interval can be changed either from the method <tt>configure</tt>
* in {@link io.netty.handler.traffic.AbstractTrafficShapingHandler} or directly using the method <tt>configure</tt>
* of {@link io.netty.handler.traffic.TrafficCounter}.</p>
*
* <p>Note that a new {@link ChannelTrafficShapingHandler} must be created for each new channel,
* but only one {@link GlobalTrafficShapingHandler} must be created for all channels.</p>
* <p>Note that a new {@link io.netty.handler.traffic.ChannelTrafficShapingHandler} must be created
* for each new channel, but only one {@link io.netty.handler.traffic.GlobalTrafficShapingHandler} must be created
* for all channels.</p>
*
* <p>Note also that you can create different GlobalTrafficShapingHandler if you want to separate classes of
* channels (for instance either from business point of view or from bind address point of view).</p>

View File

@ -90,6 +90,10 @@ public class SocketFileRegionTest extends AbstractSocketTest {
out.close();
ChannelInboundHandler ch = new SimpleChannelInboundHandler<Object>() {
@Override
public void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {
}
@Override
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
if (!autoRead) {
@ -97,10 +101,6 @@ public class SocketFileRegionTest extends AbstractSocketTest {
}
}
@Override
public void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
ctx.close();

View File

@ -43,7 +43,6 @@ public class WriteBeforeRegisteredTest extends AbstractClientSocketTest {
}
private static class TestHandler extends ChannelInboundHandlerAdapter {
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();

View File

@ -36,20 +36,21 @@ public class AutobahnServer {
}
public void run() throws Exception {
EventLoopGroup group = new NioEventLoopGroup();
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap b = new ServerBootstrap();
b.group(group)
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.childOption(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT)
.option(ChannelOption.SO_BACKLOG, 1024)
.childHandler(new AutobahnServerInitializer());
ChannelFuture f = b.bind(port).sync();
System.out.println("Web Socket Server started at port " + port);
f.channel().closeFuture().sync();
} finally {
group.shutdownGracefully();
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}

View File

@ -24,7 +24,6 @@ import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.codec.http.DefaultFullHttpResponse;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.FullHttpResponse;
import io.netty.handler.codec.http.HttpHeaders;
import io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame;
import io.netty.handler.codec.http.websocketx.CloseWebSocketFrame;
import io.netty.handler.codec.http.websocketx.ContinuationWebSocketFrame;
@ -35,7 +34,6 @@ import io.netty.handler.codec.http.websocketx.WebSocketFrame;
import io.netty.handler.codec.http.websocketx.WebSocketServerHandshaker;
import io.netty.handler.codec.http.websocketx.WebSocketServerHandshakerFactory;
import io.netty.util.CharsetUtil;
import io.netty.util.ReferenceCountUtil;
import io.netty.util.internal.StringUtil;
import java.util.logging.Level;
@ -61,7 +59,7 @@ public class AutobahnServerHandler extends ChannelInboundHandlerAdapter {
} else if (msg instanceof WebSocketFrame) {
handleWebSocketFrame(ctx, (WebSocketFrame) msg);
} else {
ReferenceCountUtil.release(msg);
throw new IllegalStateException("unknown message: " + msg);
}
}
@ -107,13 +105,13 @@ public class AutobahnServerHandler extends ChannelInboundHandlerAdapter {
if (frame instanceof CloseWebSocketFrame) {
handshaker.close(ctx.channel(), (CloseWebSocketFrame) frame);
} else if (frame instanceof PingWebSocketFrame) {
ctx.write(new PongWebSocketFrame(frame.isFinalFragment(), frame.rsv(), frame.content()), ctx.voidPromise());
ctx.write(new PongWebSocketFrame(frame.isFinalFragment(), frame.rsv(), frame.content()));
} else if (frame instanceof TextWebSocketFrame) {
ctx.write(frame, ctx.voidPromise());
ctx.write(frame);
} else if (frame instanceof BinaryWebSocketFrame) {
ctx.write(frame, ctx.voidPromise());
ctx.write(frame);
} else if (frame instanceof ContinuationWebSocketFrame) {
ctx.write(frame, ctx.voidPromise());
ctx.write(frame);
} else if (frame instanceof PongWebSocketFrame) {
frame.release();
// Ignore
@ -146,6 +144,6 @@ public class AutobahnServerHandler extends ChannelInboundHandlerAdapter {
}
private static String getWebSocketLocation(FullHttpRequest req) {
return "ws://" + req.headers().get(HttpHeaders.Names.HOST);
return "ws://" + req.headers().get(Names.HOST);
}
}

View File

@ -33,12 +33,12 @@ import io.netty.channel.RecvByteBufAllocator;
* <tr>
* <th>Name</th><th>Associated setter method</th>
* </tr><tr>
* <td>{@link io.netty.channel.ChannelOption#SO_RCVBUF}</td><td>{@link #setReceiveBufferSize(int)}</td>
* </tr><tr>
* <td>{@link io.netty.channel.ChannelOption#SO_SNDBUF}</td><td>{@link #setSendBufferSize(int)}</td>
* </tr><tr>
* <td>{@link SctpChannelOption#SCTP_NODELAY}</td><td>{@link #setSctpNoDelay(boolean)}}</td>
* </tr><tr>
* <td>{@link SctpChannelOption#SO_RCVBUF}</td><td>{@link #setReceiveBufferSize(int)}</td>
* </tr><tr>
* <td>{@link SctpChannelOption#SO_SNDBUF}</td><td>{@link #setSendBufferSize(int)}</td>
* </tr><tr>
* <td>{@link SctpChannelOption#SCTP_INIT_MAXSTREAMS}</td><td>{@link #setInitMaxStreams(InitMaxStreams)}</td>
* </tr>
* </table>

View File

@ -18,6 +18,7 @@ package io.netty.channel.sctp;
import com.sun.nio.sctp.SctpStandardSocketOptions.InitMaxStreams;
import io.netty.buffer.ByteBufAllocator;
import io.netty.channel.ChannelConfig;
import io.netty.channel.ChannelOption;
import io.netty.channel.MessageSizeEstimator;
import io.netty.channel.RecvByteBufAllocator;
@ -34,11 +35,11 @@ import io.netty.channel.RecvByteBufAllocator;
* <tr>
* <th>Name</th><th>Associated setter method</th>
* </tr><tr>
* <td>{@link SctpChannelOption#SO_BACKLOG}</td><td>{@link #setBacklog(int)}</td>
* <td>{@link ChannelOption#SO_BACKLOG}</td><td>{@link #setBacklog(int)}</td>
* </tr><tr>
* <td>{@link SctpChannelOption#SO_RCVBUF}</td><td>{@link #setReceiveBufferSize(int)}</td>
* <td>{@link ChannelOption#SO_RCVBUF}</td><td>{@link #setReceiveBufferSize(int)}</td>
* </tr><tr>
* <td>{@link SctpChannelOption#SO_SNDBUF}</td><td>{@link #setSendBufferSize(int)}</td>
* <td>{@link ChannelOption#SO_SNDBUF}</td><td>{@link #setSendBufferSize(int)}</td>
* </tr><tr>
* <td>{@link SctpChannelOption#SCTP_INIT_MAXSTREAMS}</td><td>{@link #setInitMaxStreams(InitMaxStreams)}</td>
* </tr>

View File

@ -277,7 +277,7 @@ public final class ServerBootstrap extends AbstractBootstrap<ServerBootstrap, Se
ctx.channel().eventLoop().schedule(new Runnable() {
@Override
public void run() {
config.setAutoRead(true);
config.setAutoRead(true);
}
}, 1, TimeUnit.SECONDS);
}

View File

@ -459,7 +459,7 @@ public interface Channel extends AttributeMap, Comparable<Channel> {
SocketAddress remoteAddress();
/**
* Register the {@link Channel} of the {@link ChannelPromise} with the {@link EventLoop} and notify
* Register the {@link Channel} of the {@link ChannelPromise} and notify
* the {@link ChannelFuture} once the registration was complete.
*/
void register(EventLoop eventLoop, ChannelPromise promise);

View File

@ -50,8 +50,8 @@ import java.util.concurrent.TimeUnit;
* +--------------------------+ | | Completed with failure |
* | isDone() = <b>false</b> | | +---------------------------+
* | isSuccess() = false |----+----> isDone() = <b>true</b> |
* | isCancelled() = false | | | cause() = <b>non-null</b> |
* | cause() = null | | +===========================+
* | isCancelled() = false | | | cause() = <b>non-null</b> |
* | cause() = null | | +===========================+
* +--------------------------+ | | Completed by cancellation |
* | +---------------------------+
* +----> isDone() = <b>true</b> |

View File

@ -56,7 +56,7 @@ import java.lang.annotation.Target;
* {@link ChannelPipeline} it belongs to via a context object. Using the
* context object, the {@link ChannelHandler} can pass events upstream or
* downstream, modify the pipeline dynamically, or store the information
* (using {@link AttributeKey}s) which is specific to the handler.
* (using {@link AttributeKey}s) which is specific to the handler.
*
* <h3>State management</h3>
*
@ -104,7 +104,7 @@ import java.lang.annotation.Target;
*
* </pre>
*
* <h4>Using {@link AttributeKey}</h4>
* <h4>Using {@link AttributeKey}s</h4>
*
* Although it's recommended to use member variables to store the state of a
* handler, for some reason you might not want to create many handler instances.
@ -138,7 +138,7 @@ import java.lang.annotation.Target;
* ...
* }
* </pre>
* Now that the state of the handler isattached to the {@link ChannelHandlerContext}, you can add the
* Now that the state of the handler is attached to the {@link ChannelHandlerContext}, you can add the
* same handler instance to different pipelines:
* <pre>
* public class DataServerInitializer extends {@link ChannelInitializer}&lt{@link Channel}&gt {

View File

@ -30,12 +30,14 @@ import java.nio.channels.Channels;
/**
* Enables a {@link ChannelHandler} to interact with its {@link ChannelPipeline}
* and other handlers. A handler can notify the next {@link ChannelHandler} in the {@link ChannelPipeline},
* modify the {@link ChannelPipeline} it belongs to dynamically.
* and other handlers. Among other things a handler can notify the next {@link ChannelHandler} in the
* {@link ChannelPipeline} as well as modify the {@link ChannelPipeline} it belongs to dynamically.
*
* <h3>Notify</h3>
*
* You can notify the closest handler in the same {@link ChannelPipeline} by calling one of the various method.
* You can notify the closest handler in the same {@link ChannelPipeline} by calling one of the various methods
* provided here.
*
* Please refer to {@link ChannelPipeline} to understand how an event flows.
*
* <h3>Modifying a pipeline</h3>
@ -84,15 +86,14 @@ import java.nio.channels.Channels;
* as how many times it is added to pipelines, regardless if it is added to the
* same pipeline multiple times or added to different pipelines multiple times:
* <pre>
* public class FactorialHandler extends {@link ChannelInboundHandlerAdapter}&lt{@link Integer}&gt {
* public class FactorialHandler extends {@link ChannelInboundHandlerAdapter} {
*
* private final {@link AttributeKey}&lt{@link Integer}&gt counter =
* new {@link AttributeKey}&lt{@link Integer}&gt("counter");
* private final {@link AttributeKey}&lt{@link Integer}&gt counter = {@link AttributeKey}.valueOf("counter");
*
* // This handler will receive a sequence of increasing integers starting
* // from 1.
* {@code @Override}
* public void channelRead({@link ChannelHandlerContext} ctx, {@link Integer} integer) {
* public void channelRead({@link ChannelHandlerContext} ctx, Object msg) {
* {@link Attribute}&lt{@link Integer}&gt attr = ctx.getAttr(counter);
* Integer a = ctx.getAttr(counter).get();
*
@ -100,13 +101,13 @@ import java.nio.channels.Channels;
* a = 1;
* }
*
* attr.set(a * integer));
* attr.set(a * (Integer) msg));
* }
* }
*
* // Different context objects are given to "f1", "f2", "f3", and "f4" even if
* // they refer to the same handler instance. Because the FactorialHandler
* // stores its state in a context object (as an (using an {@link AttributeKey}), the factorial is
* // stores its state in a context object (using an {@link AttributeKey}), the factorial is
* // calculated correctly 4 times once the two pipelines (p1 and p2) are active.
* FactorialHandler fh = new FactorialHandler();
*

View File

@ -99,7 +99,7 @@ public final class ChannelOption<T> extends AbstractConstant<ChannelOption<T>> {
valueOf("DATAGRAM_CHANNEL_ACTIVE_ON_REGISTRATION");
/**
* Creates a new {@link ChannelOption} with the specified {@code name}.
* Creates a new {@link ChannelOption} with the specified unique {@code name}.
*/
private ChannelOption(int id, String name) {
super(id, name);

View File

@ -48,7 +48,7 @@ public class DefaultChannelHandlerInvoker implements ChannelHandlerInvoker {
if (executor.inEventLoop()) {
invokeChannelRegisteredNow(ctx);
} else {
executor.execute(new Runnable() {
executor.execute(new OneTimeTask() {
@Override
public void run() {
invokeChannelRegisteredNow(ctx);
@ -62,7 +62,7 @@ public class DefaultChannelHandlerInvoker implements ChannelHandlerInvoker {
if (executor.inEventLoop()) {
invokeChannelUnregisteredNow(ctx);
} else {
executor.execute(new Runnable() {
executor.execute(new OneTimeTask() {
@Override
public void run() {
invokeChannelUnregisteredNow(ctx);
@ -76,7 +76,7 @@ public class DefaultChannelHandlerInvoker implements ChannelHandlerInvoker {
if (executor.inEventLoop()) {
invokeChannelActiveNow(ctx);
} else {
executor.execute(new Runnable() {
executor.execute(new OneTimeTask() {
@Override
public void run() {
invokeChannelActiveNow(ctx);
@ -90,7 +90,7 @@ public class DefaultChannelHandlerInvoker implements ChannelHandlerInvoker {
if (executor.inEventLoop()) {
invokeChannelInactiveNow(ctx);
} else {
executor.execute(new Runnable() {
executor.execute(new OneTimeTask() {
@Override
public void run() {
invokeChannelInactiveNow(ctx);
@ -109,7 +109,7 @@ public class DefaultChannelHandlerInvoker implements ChannelHandlerInvoker {
invokeExceptionCaughtNow(ctx, cause);
} else {
try {
executor.execute(new Runnable() {
executor.execute(new OneTimeTask() {
@Override
public void run() {
invokeExceptionCaughtNow(ctx, cause);
@ -133,7 +133,7 @@ public class DefaultChannelHandlerInvoker implements ChannelHandlerInvoker {
if (executor.inEventLoop()) {
invokeUserEventTriggeredNow(ctx, event);
} else {
safeExecuteInbound(new Runnable() {
safeExecuteInbound(new OneTimeTask() {
@Override
public void run() {
invokeUserEventTriggeredNow(ctx, event);
@ -151,7 +151,7 @@ public class DefaultChannelHandlerInvoker implements ChannelHandlerInvoker {
if (executor.inEventLoop()) {
invokeChannelReadNow(ctx, msg);
} else {
safeExecuteInbound(new Runnable() {
safeExecuteInbound(new OneTimeTask() {
@Override
public void run() {
invokeChannelReadNow(ctx, msg);
@ -212,7 +212,7 @@ public class DefaultChannelHandlerInvoker implements ChannelHandlerInvoker {
if (executor.inEventLoop()) {
invokeBindNow(ctx, localAddress, promise);
} else {
safeExecuteOutbound(new Runnable() {
safeExecuteOutbound(new OneTimeTask() {
@Override
public void run() {
invokeBindNow(ctx, localAddress, promise);
@ -236,7 +236,7 @@ public class DefaultChannelHandlerInvoker implements ChannelHandlerInvoker {
if (executor.inEventLoop()) {
invokeConnectNow(ctx, remoteAddress, localAddress, promise);
} else {
safeExecuteOutbound(new Runnable() {
safeExecuteOutbound(new OneTimeTask() {
@Override
public void run() {
invokeConnectNow(ctx, remoteAddress, localAddress, promise);
@ -255,7 +255,7 @@ public class DefaultChannelHandlerInvoker implements ChannelHandlerInvoker {
if (executor.inEventLoop()) {
invokeDisconnectNow(ctx, promise);
} else {
safeExecuteOutbound(new Runnable() {
safeExecuteOutbound(new OneTimeTask() {
@Override
public void run() {
invokeDisconnectNow(ctx, promise);
@ -274,7 +274,7 @@ public class DefaultChannelHandlerInvoker implements ChannelHandlerInvoker {
if (executor.inEventLoop()) {
invokeCloseNow(ctx, promise);
} else {
safeExecuteOutbound(new Runnable() {
safeExecuteOutbound(new OneTimeTask() {
@Override
public void run() {
invokeCloseNow(ctx, promise);
@ -293,7 +293,7 @@ public class DefaultChannelHandlerInvoker implements ChannelHandlerInvoker {
if (executor.inEventLoop()) {
invokeDeregisterNow(ctx, promise);
} else {
safeExecuteOutbound(new Runnable() {
safeExecuteOutbound(new OneTimeTask() {
@Override
public void run() {
invokeDeregisterNow(ctx, promise);

View File

@ -15,7 +15,7 @@
*/
/**
* A virtual {@link Channel} that helps wrapping a series of handlers to
* A virtual {@link io.netty.channel.Channel} that helps wrapping a series of handlers to
* unit test the handlers or use them in non-I/O context.
*/
package io.netty.channel.embedded;