Clean up code of HTTP/2 codec

Motivation:

Too many warnings from IntelliJ IDEA code inspector, PMD and FindBugs.

Modifications:

- Removed unnecessary casts, braces, modifiers, imports, throws on methods, etc.
- Added static modifiers where it is possible.
- Fixed incorrect links in javadoc.

Result:

Better code.
This commit is contained in:
Idel Pivnitskiy 2014-11-09 22:43:10 +03:00 committed by Scott Mitchell
parent f23f3b9617
commit 543daa3a9b
38 changed files with 127 additions and 120 deletions

View File

@ -92,9 +92,9 @@ public class CompressorHttp2ConnectionEncoder extends DefaultHttp2ConnectionEnco
if (builder.memLevel < 1 || builder.memLevel > 9) { if (builder.memLevel < 1 || builder.memLevel > 9) {
throw new IllegalArgumentException("memLevel: " + builder.memLevel + " (expected: 1-9)"); throw new IllegalArgumentException("memLevel: " + builder.memLevel + " (expected: 1-9)");
} }
this.compressionLevel = builder.compressionLevel; compressionLevel = builder.compressionLevel;
this.windowBits = builder.windowBits; windowBits = builder.windowBits;
this.memLevel = builder.memLevel; memLevel = builder.memLevel;
connection().addListener(CLEAN_UP_LISTENER); connection().addListener(CLEAN_UP_LISTENER);
} }
@ -125,7 +125,7 @@ public class CompressorHttp2ConnectionEncoder extends DefaultHttp2ConnectionEnco
ChannelPromiseAggregator aggregator = new ChannelPromiseAggregator(promise); ChannelPromiseAggregator aggregator = new ChannelPromiseAggregator(promise);
for (;;) { for (;;) {
final ByteBuf nextBuf = nextReadableBuf(compressor); final ByteBuf nextBuf = nextReadableBuf(compressor);
final boolean endOfStreamForBuf = nextBuf == null ? endOfStream : false; final boolean endOfStreamForBuf = nextBuf == null && endOfStream;
ChannelPromise newPromise = ctx.newPromise(); ChannelPromise newPromise = ctx.newPromise();
aggregator.add(newPromise); aggregator.add(newPromise);
@ -252,7 +252,7 @@ public class CompressorHttp2ConnectionEncoder extends DefaultHttp2ConnectionEnco
* Release remaining content from {@link EmbeddedChannel} and remove the compressor from the {@link Http2Stream}. * Release remaining content from {@link EmbeddedChannel} and remove the compressor from the {@link Http2Stream}.
* *
* @param stream The stream for which {@code compressor} is the compressor for * @param stream The stream for which {@code compressor} is the compressor for
* @param decompressor The compressor for {@code stream} * @param compressor The compressor for {@code stream}
*/ */
private static void cleanup(Http2Stream stream, EmbeddedChannel compressor) { private static void cleanup(Http2Stream stream, EmbeddedChannel compressor) {
if (compressor.finish()) { if (compressor.finish()) {
@ -270,7 +270,7 @@ public class CompressorHttp2ConnectionEncoder extends DefaultHttp2ConnectionEnco
/** /**
* Read the next compressed {@link ByteBuf} from the {@link EmbeddedChannel} or {@code null} if one does not exist. * Read the next compressed {@link ByteBuf} from the {@link EmbeddedChannel} or {@code null} if one does not exist.
* *
* @param decompressor The channel to read from * @param compressor The channel to read from
* @return The next decoded {@link ByteBuf} from the {@link EmbeddedChannel} or {@code null} if one does not exist * @return The next decoded {@link ByteBuf} from the {@link EmbeddedChannel} or {@code null} if one does not exist
*/ */
private static ByteBuf nextReadableBuf(EmbeddedChannel compressor) { private static ByteBuf nextReadableBuf(EmbeddedChannel compressor) {

View File

@ -417,7 +417,7 @@ public class DefaultHttp2Connection implements Http2Connection {
weight(weight); weight(weight);
if (newParent != parent() || exclusive) { if (newParent != parent() || exclusive) {
List<ParentChangedEvent> events = null; List<ParentChangedEvent> events;
if (newParent.isDescendantOf(this)) { if (newParent.isDescendantOf(this)) {
events = new ArrayList<ParentChangedEvent>(2 + (exclusive ? newParent.numChildren(): 0)); events = new ArrayList<ParentChangedEvent>(2 + (exclusive ? newParent.numChildren(): 0));
parent.takeChild(newParent, false, events); parent.takeChild(newParent, false, events);
@ -605,15 +605,15 @@ public class DefaultHttp2Connection implements Http2Connection {
* Allows a correlation to be made between a stream and its old parent before a parent change occurs * Allows a correlation to be made between a stream and its old parent before a parent change occurs
*/ */
private final class ParentChangedEvent { private final class ParentChangedEvent {
private Http2Stream stream; private final Http2Stream stream;
private Http2Stream oldParent; private final Http2Stream oldParent;
/** /**
* Create a new instance * Create a new instance
* @param stream The stream who has had a parent change * @param stream The stream who has had a parent change
* @param oldParent The previous parent * @param oldParent The previous parent
*/ */
public ParentChangedEvent(Http2Stream stream, Http2Stream oldParent) { ParentChangedEvent(Http2Stream stream, Http2Stream oldParent) {
this.stream = stream; this.stream = stream;
this.oldParent = oldParent; this.oldParent = oldParent;
} }

View File

@ -101,12 +101,12 @@ public class DefaultHttp2ConnectionDecoder implements Http2ConnectionDecoder {
} }
protected DefaultHttp2ConnectionDecoder(Builder builder) { protected DefaultHttp2ConnectionDecoder(Builder builder) {
this.connection = checkNotNull(builder.connection, "connection"); connection = checkNotNull(builder.connection, "connection");
this.frameReader = checkNotNull(builder.frameReader, "frameReader"); frameReader = checkNotNull(builder.frameReader, "frameReader");
this.lifecycleManager = checkNotNull(builder.lifecycleManager, "lifecycleManager"); lifecycleManager = checkNotNull(builder.lifecycleManager, "lifecycleManager");
this.encoder = checkNotNull(builder.encoder, "encoder"); encoder = checkNotNull(builder.encoder, "encoder");
this.inboundFlow = checkNotNull(builder.inboundFlow, "inboundFlow"); inboundFlow = checkNotNull(builder.inboundFlow, "inboundFlow");
this.listener = checkNotNull(builder.listener, "listener"); listener = checkNotNull(builder.listener, "listener");
} }
@Override @Override

View File

@ -85,10 +85,10 @@ public class DefaultHttp2ConnectionEncoder implements Http2ConnectionEncoder {
} }
protected DefaultHttp2ConnectionEncoder(Builder builder) { protected DefaultHttp2ConnectionEncoder(Builder builder) {
this.frameWriter = checkNotNull(builder.frameWriter, "frameWriter"); frameWriter = checkNotNull(builder.frameWriter, "frameWriter");
this.connection = checkNotNull(builder.connection, "connection"); connection = checkNotNull(builder.connection, "connection");
this.outboundFlow = checkNotNull(builder.outboundFlow, "outboundFlow"); outboundFlow = checkNotNull(builder.outboundFlow, "outboundFlow");
this.lifecycleManager = checkNotNull(builder.lifecycleManager, "lifecycleManager"); lifecycleManager = checkNotNull(builder.lifecycleManager, "lifecycleManager");
} }
@Override @Override
@ -251,10 +251,10 @@ public class DefaultHttp2ConnectionEncoder implements Http2ConnectionEncoder {
"Sending non-trailing headers after data has been sent for stream: " "Sending non-trailing headers after data has been sent for stream: "
+ streamId); + streamId);
} }
} catch (Http2NoMoreStreamIdsException e) {
lifecycleManager.onException(ctx, e);
return promise.setFailure(e);
} catch (Throwable e) { } catch (Throwable e) {
if (e instanceof Http2NoMoreStreamIdsException) {
lifecycleManager.onException(ctx, e);
}
return promise.setFailure(e); return promise.setFailure(e);
} }

View File

@ -23,7 +23,6 @@ import static io.netty.handler.codec.http2.Http2CodecUtil.SETTINGS_MAX_FRAME_SIZ
import static io.netty.handler.codec.http2.Http2CodecUtil.SETTING_ENTRY_LENGTH; import static io.netty.handler.codec.http2.Http2CodecUtil.SETTING_ENTRY_LENGTH;
import static io.netty.handler.codec.http2.Http2CodecUtil.isMaxFrameSizeValid; import static io.netty.handler.codec.http2.Http2CodecUtil.isMaxFrameSizeValid;
import static io.netty.handler.codec.http2.Http2CodecUtil.readUnsignedInt; import static io.netty.handler.codec.http2.Http2CodecUtil.readUnsignedInt;
import static io.netty.handler.codec.http2.Http2Error.FRAME_SIZE_ERROR;
import static io.netty.handler.codec.http2.Http2Exception.protocolError; import static io.netty.handler.codec.http2.Http2Exception.protocolError;
import static io.netty.handler.codec.http2.Http2FrameTypes.CONTINUATION; import static io.netty.handler.codec.http2.Http2FrameTypes.CONTINUATION;
import static io.netty.handler.codec.http2.Http2FrameTypes.DATA; import static io.netty.handler.codec.http2.Http2FrameTypes.DATA;
@ -87,7 +86,8 @@ public class DefaultHttp2FrameReader implements Http2FrameReader, Http2FrameSize
@Override @Override
public void maxFrameSize(int max) throws Http2Exception { public void maxFrameSize(int max) throws Http2Exception {
if (!isMaxFrameSizeValid(max)) { if (!isMaxFrameSizeValid(max)) {
Http2Exception.format(FRAME_SIZE_ERROR, "Invalid MAX_FRAME_SIZE specified in sent settings: %d", max); Http2Exception.format(Http2Error.FRAME_SIZE_ERROR,
"Invalid MAX_FRAME_SIZE specified in sent settings: %d", max);
} }
maxFrameSize = max; maxFrameSize = max;
} }
@ -560,8 +560,7 @@ public class DefaultHttp2FrameReader implements Http2FrameReader, Http2FrameSize
listener); listener);
} }
private void readUnknownFrame(ChannelHandlerContext ctx, ByteBuf payload, Http2FrameListener listener) private void readUnknownFrame(ChannelHandlerContext ctx, ByteBuf payload, Http2FrameListener listener) {
throws Http2Exception {
payload = payload.readSlice(payload.readableBytes()); payload = payload.readSlice(payload.readableBytes());
listener.onUnknownFrame(ctx, frameType, streamId, flags, payload); listener.onUnknownFrame(ctx, frameType, streamId, flags, payload);
} }

View File

@ -52,6 +52,9 @@ import io.netty.util.collection.IntObjectMap;
* A {@link Http2FrameWriter} that supports all frame types defined by the HTTP/2 specification. * A {@link Http2FrameWriter} that supports all frame types defined by the HTTP/2 specification.
*/ */
public class DefaultHttp2FrameWriter implements Http2FrameWriter, Http2FrameSizePolicy, Configuration { public class DefaultHttp2FrameWriter implements Http2FrameWriter, Http2FrameSizePolicy, Configuration {
private static final String STREAM_ID = "Stream ID";
private static final String STREAM_DEPENDENCY = "Stream Dependency";
private final Http2HeadersEncoder headersEncoder; private final Http2HeadersEncoder headersEncoder;
private int maxFrameSize; private int maxFrameSize;
@ -99,7 +102,7 @@ public class DefaultHttp2FrameWriter implements Http2FrameWriter, Http2FrameSize
public ChannelFuture writeData(ChannelHandlerContext ctx, int streamId, ByteBuf data, public ChannelFuture writeData(ChannelHandlerContext ctx, int streamId, ByteBuf data,
int padding, boolean endStream, ChannelPromise promise) { int padding, boolean endStream, ChannelPromise promise) {
try { try {
verifyStreamId(streamId, "Stream ID"); verifyStreamId(streamId, STREAM_ID);
verifyPadding(padding); verifyPadding(padding);
Http2Flags flags = new Http2Flags().paddingPresent(padding > 0).endOfStream(endStream); Http2Flags flags = new Http2Flags().paddingPresent(padding > 0).endOfStream(endStream);
@ -145,14 +148,14 @@ public class DefaultHttp2FrameWriter implements Http2FrameWriter, Http2FrameSize
public ChannelFuture writePriority(ChannelHandlerContext ctx, int streamId, public ChannelFuture writePriority(ChannelHandlerContext ctx, int streamId,
int streamDependency, short weight, boolean exclusive, ChannelPromise promise) { int streamDependency, short weight, boolean exclusive, ChannelPromise promise) {
try { try {
verifyStreamId(streamId, "Stream ID"); verifyStreamId(streamId, STREAM_ID);
verifyStreamId(streamDependency, "Stream Dependency"); verifyStreamId(streamDependency, STREAM_DEPENDENCY);
verifyWeight(weight); verifyWeight(weight);
ByteBuf frame = ctx.alloc().buffer(FRAME_HEADER_LENGTH + PRIORITY_ENTRY_LENGTH); ByteBuf frame = ctx.alloc().buffer(FRAME_HEADER_LENGTH + PRIORITY_ENTRY_LENGTH);
writeFrameHeader(frame, PRIORITY_ENTRY_LENGTH, PRIORITY, writeFrameHeader(frame, PRIORITY_ENTRY_LENGTH, PRIORITY,
new Http2Flags(), streamId); new Http2Flags(), streamId);
long word1 = exclusive ? (0x80000000L | streamDependency) : streamDependency; long word1 = exclusive ? 0x80000000L | streamDependency : streamDependency;
writeUnsignedInt(word1, frame); writeUnsignedInt(word1, frame);
// Adjust the weight so that it fits into a single byte on the wire. // Adjust the weight so that it fits into a single byte on the wire.
@ -167,7 +170,7 @@ public class DefaultHttp2FrameWriter implements Http2FrameWriter, Http2FrameSize
public ChannelFuture writeRstStream(ChannelHandlerContext ctx, int streamId, long errorCode, public ChannelFuture writeRstStream(ChannelHandlerContext ctx, int streamId, long errorCode,
ChannelPromise promise) { ChannelPromise promise) {
try { try {
verifyStreamId(streamId, "Stream ID"); verifyStreamId(streamId, STREAM_ID);
verifyErrorCode(errorCode); verifyErrorCode(errorCode);
ByteBuf frame = ctx.alloc().buffer(FRAME_HEADER_LENGTH + INT_FIELD_LENGTH); ByteBuf frame = ctx.alloc().buffer(FRAME_HEADER_LENGTH + INT_FIELD_LENGTH);
@ -232,7 +235,7 @@ public class DefaultHttp2FrameWriter implements Http2FrameWriter, Http2FrameSize
int promisedStreamId, Http2Headers headers, int padding, ChannelPromise promise) { int promisedStreamId, Http2Headers headers, int padding, ChannelPromise promise) {
ByteBuf headerBlock = null; ByteBuf headerBlock = null;
try { try {
verifyStreamId(streamId, "Stream ID"); verifyStreamId(streamId, STREAM_ID);
verifyStreamId(promisedStreamId, "Promised Stream ID"); verifyStreamId(promisedStreamId, "Promised Stream ID");
verifyPadding(padding); verifyPadding(padding);
@ -306,7 +309,7 @@ public class DefaultHttp2FrameWriter implements Http2FrameWriter, Http2FrameSize
public ChannelFuture writeWindowUpdate(ChannelHandlerContext ctx, int streamId, public ChannelFuture writeWindowUpdate(ChannelHandlerContext ctx, int streamId,
int windowSizeIncrement, ChannelPromise promise) { int windowSizeIncrement, ChannelPromise promise) {
try { try {
verifyStreamOrConnectionId(streamId, "Stream ID"); verifyStreamOrConnectionId(streamId, STREAM_ID);
verifyWindowSizeIncrement(windowSizeIncrement); verifyWindowSizeIncrement(windowSizeIncrement);
ByteBuf frame = ctx.alloc().buffer(FRAME_HEADER_LENGTH + INT_FIELD_LENGTH); ByteBuf frame = ctx.alloc().buffer(FRAME_HEADER_LENGTH + INT_FIELD_LENGTH);
@ -323,7 +326,7 @@ public class DefaultHttp2FrameWriter implements Http2FrameWriter, Http2FrameSize
public ChannelFuture writeFrame(ChannelHandlerContext ctx, byte frameType, int streamId, public ChannelFuture writeFrame(ChannelHandlerContext ctx, byte frameType, int streamId,
Http2Flags flags, ByteBuf payload, ChannelPromise promise) { Http2Flags flags, ByteBuf payload, ChannelPromise promise) {
try { try {
verifyStreamOrConnectionId(streamId, "Stream ID"); verifyStreamOrConnectionId(streamId, STREAM_ID);
ByteBuf frame = ctx.alloc().buffer(FRAME_HEADER_LENGTH + payload.readableBytes()); ByteBuf frame = ctx.alloc().buffer(FRAME_HEADER_LENGTH + payload.readableBytes());
writeFrameHeader(frame, payload.readableBytes(), frameType, flags, streamId); writeFrameHeader(frame, payload.readableBytes(), frameType, flags, streamId);
frame.writeBytes(payload); frame.writeBytes(payload);
@ -338,9 +341,9 @@ public class DefaultHttp2FrameWriter implements Http2FrameWriter, Http2FrameSize
boolean hasPriority, int streamDependency, short weight, boolean exclusive) { boolean hasPriority, int streamDependency, short weight, boolean exclusive) {
ByteBuf headerBlock = null; ByteBuf headerBlock = null;
try { try {
verifyStreamId(streamId, "Stream ID"); verifyStreamId(streamId, STREAM_ID);
if (hasPriority) { if (hasPriority) {
verifyStreamOrConnectionId(streamDependency, "Stream Dependency"); verifyStreamOrConnectionId(streamDependency, STREAM_DEPENDENCY);
verifyPadding(padding); verifyPadding(padding);
verifyWeight(weight); verifyWeight(weight);
} }

View File

@ -99,7 +99,7 @@ public class DefaultHttp2HeadersDecoder implements Http2HeadersDecoder, Http2Hea
@Override @Override
public void maxHeaderTableSize(int max) throws Http2Exception { public void maxHeaderTableSize(int max) throws Http2Exception {
if (max < 0) { if (max < 0) {
throw Http2Exception.protocolError("Header Table Size must be non-negative but was %d", max); throw protocolError("Header Table Size must be non-negative but was %d", max);
} }
try { try {
decoder.setMaxHeaderTableSize(max); decoder.setMaxHeaderTableSize(max);

View File

@ -107,7 +107,7 @@ public class DefaultHttp2HeadersEncoder implements Http2HeadersEncoder, Http2Hea
} }
private void encodeHeader(AsciiString key, AsciiString value, OutputStream stream) throws IOException { private void encodeHeader(AsciiString key, AsciiString value, OutputStream stream) throws IOException {
boolean sensitive = sensitiveHeaders.contains(key); boolean sensitive = sensitiveHeaders.contains(key.toString());
encoder.encodeHeader(stream, key.array(), value.array(), sensitive); encoder.encodeHeader(stream, key.array(), value.array(), sensitive);
} }
@ -118,7 +118,7 @@ public class DefaultHttp2HeadersEncoder implements Http2HeadersEncoder, Http2Hea
@Override @Override
public void maxHeaderTableSize(int max) throws Http2Exception { public void maxHeaderTableSize(int max) throws Http2Exception {
if (max < 0) { if (max < 0) {
throw Http2Exception.protocolError("Header Table Size must be non-negative but was %d", max); throw protocolError("Header Table Size must be non-negative but was %d", max);
} }
try { try {
// No headers should be emitted. If they are, we throw. // No headers should be emitted. If they are, we throw.

View File

@ -150,7 +150,7 @@ public class DefaultHttp2InboundFlowController implements Http2InboundFlowContro
} }
private InboundFlowState state(Http2Stream stream) { private InboundFlowState state(Http2Stream stream) {
return stream != null? (InboundFlowState) stream.inboundFlow() : null; return stream != null ? (InboundFlowState) stream.inboundFlow() : null;
} }
/** /**

View File

@ -551,7 +551,7 @@ public class DefaultHttp2OutboundFlowController implements Http2OutboundFlowCont
this.padding = padding; this.padding = padding;
this.endStream = endStream; this.endStream = endStream;
this.promiseAggregator = promiseAggregator; this.promiseAggregator = promiseAggregator;
this.promise = ctx.newPromise(); promise = ctx.newPromise();
promiseAggregator.add(promise); promiseAggregator.add(promise);
} }
@ -599,7 +599,7 @@ public class DefaultHttp2OutboundFlowController implements Http2OutboundFlowCont
final Http2FrameSizePolicy frameSizePolicy = frameWriter.configuration().frameSizePolicy(); final Http2FrameSizePolicy frameSizePolicy = frameWriter.configuration().frameSizePolicy();
do { do {
int bytesToWrite = size(); int bytesToWrite = size();
int frameBytes = Math.min(bytesToWrite, frameSizePolicy.maxFrameSize()); int frameBytes = min(bytesToWrite, frameSizePolicy.maxFrameSize());
if (frameBytes == bytesToWrite) { if (frameBytes == bytesToWrite) {
// All the bytes fit into a single HTTP/2 frame, just send it all. // All the bytes fit into a single HTTP/2 frame, just send it all.
try { try {

View File

@ -86,7 +86,7 @@ public class DelegatingDecompressorFrameListener extends Http2FrameListenerDecor
} else { } else {
for (;;) { for (;;) {
final ByteBuf nextBuf = nextReadableBuf(decompressor); final ByteBuf nextBuf = nextReadableBuf(decompressor);
final boolean endOfStreamForBuf = nextBuf == null ? endOfStream : false; final boolean endOfStreamForBuf = nextBuf == null && endOfStream;
listener.onDataRead(ctx, streamId, buf, padding, endOfStreamForBuf); listener.onDataRead(ctx, streamId, buf, padding, endOfStreamForBuf);
if (nextBuf == null) { if (nextBuf == null) {

View File

@ -32,7 +32,7 @@ public final class Http2CodecUtil {
private static final byte[] CONNECTION_PREFACE = "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n".getBytes(UTF_8); private static final byte[] CONNECTION_PREFACE = "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n".getBytes(UTF_8);
private static final byte[] EMPTY_PING = new byte[8]; private static final byte[] EMPTY_PING = new byte[8];
private static IgnoreSettingsHandler ignoreSettingsHandler = new IgnoreSettingsHandler(); private static final IgnoreSettingsHandler IGNORE_SETTINGS_HANDLER = new IgnoreSettingsHandler();
public static final int CONNECTION_STREAM_ID = 0; public static final int CONNECTION_STREAM_ID = 0;
public static final int HTTP_UPGRADE_STREAM_ID = 1; public static final int HTTP_UPGRADE_STREAM_ID = 1;
@ -48,8 +48,8 @@ public final class Http2CodecUtil {
public static final int SETTING_ENTRY_LENGTH = 6; public static final int SETTING_ENTRY_LENGTH = 6;
public static final int PRIORITY_ENTRY_LENGTH = 5; public static final int PRIORITY_ENTRY_LENGTH = 5;
public static final int INT_FIELD_LENGTH = 4; public static final int INT_FIELD_LENGTH = 4;
public static final short MAX_WEIGHT = (short) 256; public static final short MAX_WEIGHT = 256;
public static final short MIN_WEIGHT = (short) 1; public static final short MIN_WEIGHT = 1;
public static final int SETTINGS_HEADER_TABLE_SIZE = 1; public static final int SETTINGS_HEADER_TABLE_SIZE = 1;
public static final int SETTINGS_ENABLE_PUSH = 2; public static final int SETTINGS_ENABLE_PUSH = 2;
@ -124,7 +124,7 @@ public final class Http2CodecUtil {
* settings frames directly. * settings frames directly.
*/ */
public static ChannelHandler ignoreSettingsHandler() { public static ChannelHandler ignoreSettingsHandler() {
return ignoreSettingsHandler; return IGNORE_SETTINGS_HANDLER;
} }
/** /**

View File

@ -31,7 +31,7 @@ public interface Http2ConnectionDecoder extends Closeable {
/** /**
* Builder for new instances of {@link Http2ConnectionDecoder}. * Builder for new instances of {@link Http2ConnectionDecoder}.
*/ */
public interface Builder { interface Builder {
/** /**
* Sets the {@link Http2Connection} to be used when building the decoder. * Sets the {@link Http2Connection} to be used when building the decoder.
@ -39,7 +39,7 @@ public interface Http2ConnectionDecoder extends Closeable {
Builder connection(Http2Connection connection); Builder connection(Http2Connection connection);
/** /**
* Sets the {@link LifecycleManager} to be used when building the decoder. * Sets the {@link Http2LifecycleManager} to be used when building the decoder.
*/ */
Builder lifecycleManager(Http2LifecycleManager lifecycleManager); Builder lifecycleManager(Http2LifecycleManager lifecycleManager);

View File

@ -21,14 +21,14 @@ import io.netty.channel.ChannelPromise;
/** /**
* Handler for outbound traffic on behalf of {@link Http2ConectionHandler}. * Handler for outbound HTTP/2 traffic.
*/ */
public interface Http2ConnectionEncoder extends Http2FrameWriter, Http2OutboundFlowController { public interface Http2ConnectionEncoder extends Http2FrameWriter, Http2OutboundFlowController {
/** /**
* Builder for new instances of {@link Http2ConnectionEncoder}. * Builder for new instances of {@link Http2ConnectionEncoder}.
*/ */
public interface Builder { interface Builder {
/** /**
* Sets the {@link Http2Connection} to be used when building the encoder. * Sets the {@link Http2Connection} to be used when building the encoder.
@ -36,7 +36,7 @@ public interface Http2ConnectionEncoder extends Http2FrameWriter, Http2OutboundF
Builder connection(Http2Connection connection); Builder connection(Http2Connection connection);
/** /**
* Sets the {@link LifecycleManager} to be used when building the encoder. * Sets the {@link Http2LifecycleManager} to be used when building the encoder.
*/ */
Builder lifecycleManager(Http2LifecycleManager lifecycleManager); Builder lifecycleManager(Http2LifecycleManager lifecycleManager);

View File

@ -213,6 +213,7 @@ public class Http2ConnectionHandler extends ByteToMessageDecoder implements Http
* @param stream the stream to be half closed. * @param stream the stream to be half closed.
* @param future If closing, the future after which to close the channel. * @param future If closing, the future after which to close the channel.
*/ */
@Override
public void closeLocalSide(Http2Stream stream, ChannelFuture future) { public void closeLocalSide(Http2Stream stream, ChannelFuture future) {
switch (stream.state()) { switch (stream.state()) {
case HALF_CLOSED_LOCAL: case HALF_CLOSED_LOCAL:
@ -232,6 +233,7 @@ public class Http2ConnectionHandler extends ByteToMessageDecoder implements Http
* @param stream the stream to be half closed. * @param stream the stream to be half closed.
* @param future If closing, the future after which to close the channel. * @param future If closing, the future after which to close the channel.
*/ */
@Override
public void closeRemoteSide(Http2Stream stream, ChannelFuture future) { public void closeRemoteSide(Http2Stream stream, ChannelFuture future) {
switch (stream.state()) { switch (stream.state()) {
case HALF_CLOSED_REMOTE: case HALF_CLOSED_REMOTE:
@ -310,6 +312,7 @@ public class Http2ConnectionHandler extends ByteToMessageDecoder implements Http
/** /**
* Writes a {@code RST_STREAM} frame to the remote endpoint and updates the connection state appropriately. * Writes a {@code RST_STREAM} frame to the remote endpoint and updates the connection state appropriately.
*/ */
@Override
public ChannelFuture writeRstStream(ChannelHandlerContext ctx, int streamId, long errorCode, public ChannelFuture writeRstStream(ChannelHandlerContext ctx, int streamId, long errorCode,
ChannelPromise promise) { ChannelPromise promise) {
Http2Stream stream = connection().stream(streamId); Http2Stream stream = connection().stream(streamId);
@ -327,6 +330,7 @@ public class Http2ConnectionHandler extends ByteToMessageDecoder implements Http
/** /**
* Sends a {@code GO_AWAY} frame to the remote endpoint and updates the connection state appropriately. * Sends a {@code GO_AWAY} frame to the remote endpoint and updates the connection state appropriately.
*/ */
@Override
public ChannelFuture writeGoAway(ChannelHandlerContext ctx, int lastStreamId, long errorCode, ByteBuf debugData, public ChannelFuture writeGoAway(ChannelHandlerContext ctx, int lastStreamId, long errorCode, ByteBuf debugData,
ChannelPromise promise) { ChannelPromise promise) {
Http2Connection connection = connection(); Http2Connection connection = connection();

View File

@ -28,7 +28,7 @@ public interface Http2FrameReader extends Closeable {
/** /**
* Configuration specific to {@link Http2FrameReader} * Configuration specific to {@link Http2FrameReader}
*/ */
public interface Configuration { interface Configuration {
/** /**
* Get the {@link Http2HeaderTable} for this {@link Http2FrameReader} * Get the {@link Http2HeaderTable} for this {@link Http2FrameReader}
*/ */

View File

@ -31,7 +31,7 @@ public interface Http2FrameWriter extends Http2DataWriter, Closeable {
/** /**
* Configuration specific to {@link Http2FrameWriter} * Configuration specific to {@link Http2FrameWriter}
*/ */
public interface Configuration { interface Configuration {
/** /**
* Get the {@link Http2HeaderTable} for this {@link Http2FrameWriter} * Get the {@link Http2HeaderTable} for this {@link Http2FrameWriter}
*/ */

View File

@ -24,7 +24,7 @@ public interface Http2HeadersDecoder {
/** /**
* Configuration related elements for the {@link Http2HeadersDecoder} interface * Configuration related elements for the {@link Http2HeadersDecoder} interface
*/ */
public interface Configuration { interface Configuration {
/** /**
* Access the Http2HeaderTable for this {@link Http2HeadersDecoder} * Access the Http2HeaderTable for this {@link Http2HeadersDecoder}
*/ */

View File

@ -24,7 +24,7 @@ public interface Http2HeadersEncoder {
/** /**
* Configuration related elements for the {@link Http2HeadersEncoder} interface * Configuration related elements for the {@link Http2HeadersEncoder} interface
*/ */
public interface Configuration { interface Configuration {
/** /**
* Access the Http2HeaderTable for this {@link Http2HeadersEncoder} * Access the Http2HeaderTable for this {@link Http2HeadersEncoder}
*/ */

View File

@ -148,9 +148,8 @@ public abstract class Http2OrHttpChooser extends ByteToMessageDecoder {
protected abstract ChannelHandler createHttp1RequestHandler(); protected abstract ChannelHandler createHttp1RequestHandler();
/** /**
* Create the {@link io.netty.channel.ChannelHandler} that is responsible for handling the http * Create the {@link ChannelHandler} that is responsible for handling the http responses
* responses when the when the {@link SelectedProtocol} was {@link SelectedProtocol#HTTP_2}. The * when the when the {@link SelectedProtocol} was {@link SelectedProtocol#HTTP_2}.
* returned class should be a subclass of {@link DelegatingHttp2ConnectionHandler}.
*/ */
protected abstract ChannelHandler createHttp2RequestHandler(); protected abstract Http2ConnectionHandler createHttp2RequestHandler();
} }

View File

@ -24,8 +24,6 @@ import java.util.List;
* Provides utilities related to security requirements specific to HTTP/2. * Provides utilities related to security requirements specific to HTTP/2.
*/ */
public final class Http2SecurityUtil { public final class Http2SecurityUtil {
private Http2SecurityUtil() { }
/** /**
* The following list is derived from <a * The following list is derived from <a
* href="http://docs.oracle.com/javase/8/docs/technotes/guides/security/SunProviders.html">SunJSSE Supported * href="http://docs.oracle.com/javase/8/docs/technotes/guides/security/SunProviders.html">SunJSSE Supported
@ -78,4 +76,6 @@ public final class Http2SecurityUtil {
ciphers.addAll(CIPHERS_JAVA_DISABLED_DEFAULT); ciphers.addAll(CIPHERS_JAVA_DISABLED_DEFAULT);
CIPHERS = Collections.unmodifiableList(ciphers); CIPHERS = Collections.unmodifiableList(ciphers);
} }
private Http2SecurityUtil() { }
} }

View File

@ -133,8 +133,7 @@ public class Http2ServerUpgradeCodec implements HttpServerUpgradeHandler.Upgrade
final Http2Settings decodedSettings = new Http2Settings(); final Http2Settings decodedSettings = new Http2Settings();
frameReader.readFrame(ctx, frame, new Http2FrameAdapter() { frameReader.readFrame(ctx, frame, new Http2FrameAdapter() {
@Override @Override
public void onSettingsRead(ChannelHandlerContext ctx, Http2Settings settings) public void onSettingsRead(ChannelHandlerContext ctx, Http2Settings settings) {
throws Http2Exception {
decodedSettings.copyFrom(settings); decodedSettings.copyFrom(settings);
} }
}); });

View File

@ -177,7 +177,7 @@ public final class Http2Settings extends IntObjectHashMap<Long> {
return value.intValue(); return value.intValue();
} }
private void verifyStandardSetting(int key, Long value) { private static void verifyStandardSetting(int key, Long value) {
checkNotNull(value, "value"); checkNotNull(value, "value");
switch (key) { switch (key) {
case SETTINGS_HEADER_TABLE_SIZE: case SETTINGS_HEADER_TABLE_SIZE:
@ -215,6 +215,8 @@ public final class Http2Settings extends IntObjectHashMap<Long> {
+ value); + value);
} }
break; break;
default:
throw new IllegalArgumentException("key");
} }
} }

View File

@ -22,7 +22,7 @@ import io.netty.handler.codec.http.FullHttpMessage;
import io.netty.handler.codec.http.HttpHeaders; import io.netty.handler.codec.http.HttpHeaders;
/** /**
* Light weight wrapper around {@link DelegatingHttp2ConnectionHandler} to provide HTTP/1.x objects to HTTP/2 frames * Translates HTTP/1.x object writes into HTTP/2 frames
* <p> * <p>
* See {@link InboundHttp2ToHttpAdapter} to get translation from HTTP/2 frames to HTTP/1.x objects * See {@link InboundHttp2ToHttpAdapter} to get translation from HTTP/2 frames to HTTP/1.x objects
*/ */

View File

@ -125,7 +125,7 @@ public final class InboundHttp2ToHttpPriorityAdapter extends InboundHttp2ToHttpA
* @param msg The message containing the headers and trailing headers * @param msg The message containing the headers and trailing headers
* @return The headers object which can be appended to or modified * @return The headers object which can be appended to or modified
*/ */
private HttpHeaders getActiveHeaders(FullHttpMessage msg) { private static HttpHeaders getActiveHeaders(FullHttpMessage msg) {
return msg.content().isReadable() ? msg.trailingHeaders() : msg.headers(); return msg.content().isReadable() ? msg.trailingHeaders() : msg.headers();
} }
@ -159,7 +159,7 @@ public final class InboundHttp2ToHttpPriorityAdapter extends InboundHttp2ToHttpA
* This will remove all headers which are related to priority tree events * This will remove all headers which are related to priority tree events
* @param headers The headers to remove the priority tree elements from * @param headers The headers to remove the priority tree elements from
*/ */
private void removePriorityRelatedHeaders(HttpHeaders headers) { private static void removePriorityRelatedHeaders(HttpHeaders headers) {
headers.remove(HttpUtil.ExtensionHeaderNames.STREAM_DEPENDENCY_ID.text()); headers.remove(HttpUtil.ExtensionHeaderNames.STREAM_DEPENDENCY_ID.text());
headers.remove(HttpUtil.ExtensionHeaderNames.STREAM_WEIGHT.text()); headers.remove(HttpUtil.ExtensionHeaderNames.STREAM_WEIGHT.text());
} }
@ -181,7 +181,7 @@ public final class InboundHttp2ToHttpPriorityAdapter extends InboundHttp2ToHttpA
* @param httpHeaders The HTTP headers to translate to HTTP/2 * @param httpHeaders The HTTP headers to translate to HTTP/2
* @param http2Headers The target HTTP/2 headers * @param http2Headers The target HTTP/2 headers
*/ */
private void addHttpHeadersToHttp2Headers(HttpHeaders httpHeaders, final Http2Headers http2Headers) { private static void addHttpHeadersToHttp2Headers(HttpHeaders httpHeaders, final Http2Headers http2Headers) {
try { try {
httpHeaders.forEachEntry(new EntryVisitor() { httpHeaders.forEachEntry(new EntryVisitor() {
@Override @Override
@ -239,7 +239,7 @@ public final class InboundHttp2ToHttpPriorityAdapter extends InboundHttp2ToHttpA
@Override @Override
public void onWeightChanged(Http2Stream stream, short oldWeight) { public void onWeightChanged(Http2Stream stream, short oldWeight) {
FullHttpMessage msg = messageMap.get(stream.id()); FullHttpMessage msg = messageMap.get(stream.id());
HttpHeaders headers = null; HttpHeaders headers;
if (msg == null) { if (msg == null) {
// msg may be null if a HTTP/2 frame event in received outside the HTTP message flow // msg may be null if a HTTP/2 frame event in received outside the HTTP message flow
// For example a PRIORITY frame can be received in any state besides IDLE // For example a PRIORITY frame can be received in any state besides IDLE

View File

@ -19,8 +19,7 @@ import static io.netty.handler.codec.http2.Http2TestUtil.as;
import static io.netty.handler.codec.http2.Http2TestUtil.runInChannel; import static io.netty.handler.codec.http2.Http2TestUtil.runInChannel;
import static java.util.concurrent.TimeUnit.MILLISECONDS; import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.concurrent.TimeUnit.SECONDS; import static java.util.concurrent.TimeUnit.SECONDS;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.*;
import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.any; import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq; import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.times; import static org.mockito.Mockito.times;
@ -243,8 +242,8 @@ public class DataCompressionHttp2Test {
assertEquals(data1, dataCapture.get(0)); assertEquals(data1, dataCapture.get(0));
assertEquals(data2, dataCapture.get(1)); assertEquals(data2, dataCapture.get(1));
List<Boolean> endStreamCapture = endStreamCaptor.getAllValues(); List<Boolean> endStreamCapture = endStreamCaptor.getAllValues();
assertEquals(false, endStreamCapture.get(0)); assertFalse(endStreamCapture.get(0));
assertEquals(true, endStreamCapture.get(1)); assertTrue(endStreamCapture.get(1));
} finally { } finally {
data1.release(); data1.release();
data2.release(); data2.release();

View File

@ -345,7 +345,7 @@ public class DefaultHttp2ConnectionDecoderTest {
public void rstStreamReadShouldCloseStream() throws Exception { public void rstStreamReadShouldCloseStream() throws Exception {
decode().onRstStreamRead(ctx, STREAM_ID, PROTOCOL_ERROR.code()); decode().onRstStreamRead(ctx, STREAM_ID, PROTOCOL_ERROR.code());
verify(lifecycleManager).closeStream(eq(stream), eq(future)); verify(lifecycleManager).closeStream(eq(stream), eq(future));
verify(listener).onRstStreamRead(eq(ctx), eq(STREAM_ID), eq((long) PROTOCOL_ERROR.code())); verify(listener).onRstStreamRead(eq(ctx), eq(STREAM_ID), eq(PROTOCOL_ERROR.code()));
} }
@Test @Test

View File

@ -314,7 +314,7 @@ public class DefaultHttp2ConnectionEncoderTest {
@Test @Test
public void rstStreamWriteShouldCloseStream() throws Exception { public void rstStreamWriteShouldCloseStream() throws Exception {
encoder.writeRstStream(ctx, STREAM_ID, PROTOCOL_ERROR.code(), promise); encoder.writeRstStream(ctx, STREAM_ID, PROTOCOL_ERROR.code(), promise);
verify(lifecycleManager).writeRstStream(eq(ctx), eq(STREAM_ID), eq((long) PROTOCOL_ERROR.code()), eq(promise)); verify(lifecycleManager).writeRstStream(eq(ctx), eq(STREAM_ID), eq(PROTOCOL_ERROR.code()), eq(promise));
} }
@Test @Test

View File

@ -33,7 +33,6 @@ import io.netty.handler.codec.http2.Http2Stream.State;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import org.junit.Assert;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.mockito.ArgumentCaptor; import org.mockito.ArgumentCaptor;
@ -304,7 +303,7 @@ public class DefaultHttp2ConnectionTest {
reset(clientListener); reset(clientListener);
streamD.setPriority(streamD.parent().id(), newWeight, false); streamD.setPriority(streamD.parent().id(), newWeight, false);
verify(clientListener).onWeightChanged(eq(streamD), eq(oldWeight)); verify(clientListener).onWeightChanged(eq(streamD), eq(oldWeight));
Assert.assertEquals(streamD.weight(), newWeight); assertEquals(streamD.weight(), newWeight);
verify(clientListener, never()).priorityTreeParentChanging(any(Http2Stream.class), verify(clientListener, never()).priorityTreeParentChanging(any(Http2Stream.class),
any(Http2Stream.class)); any(Http2Stream.class));
verify(clientListener, never()).priorityTreeParentChanged(any(Http2Stream.class), verify(clientListener, never()).priorityTreeParentChanged(any(Http2Stream.class),
@ -533,34 +532,34 @@ public class DefaultHttp2ConnectionTest {
} }
private void verifyParentChanging(List<Http2Stream> expectedArg1, List<Http2Stream> expectedArg2) { private void verifyParentChanging(List<Http2Stream> expectedArg1, List<Http2Stream> expectedArg2) {
Assert.assertTrue(expectedArg1.size() == expectedArg2.size()); assertTrue(expectedArg1.size() == expectedArg2.size());
ArgumentCaptor<Http2Stream> arg1Captor = ArgumentCaptor.forClass(Http2Stream.class); ArgumentCaptor<Http2Stream> arg1Captor = ArgumentCaptor.forClass(Http2Stream.class);
ArgumentCaptor<Http2Stream> arg2Captor = ArgumentCaptor.forClass(Http2Stream.class); ArgumentCaptor<Http2Stream> arg2Captor = ArgumentCaptor.forClass(Http2Stream.class);
verify(clientListener, times(expectedArg1.size())).priorityTreeParentChanging(arg1Captor.capture(), verify(clientListener, times(expectedArg1.size())).priorityTreeParentChanging(arg1Captor.capture(),
arg2Captor.capture()); arg2Captor.capture());
List<Http2Stream> capturedArg1 = arg1Captor.getAllValues(); List<Http2Stream> capturedArg1 = arg1Captor.getAllValues();
List<Http2Stream> capturedArg2 = arg2Captor.getAllValues(); List<Http2Stream> capturedArg2 = arg2Captor.getAllValues();
Assert.assertTrue(capturedArg1.size() == capturedArg2.size()); assertTrue(capturedArg1.size() == capturedArg2.size());
Assert.assertTrue(capturedArg1.size() == expectedArg1.size()); assertTrue(capturedArg1.size() == expectedArg1.size());
for (int i = 0; i < capturedArg1.size(); ++i) { for (int i = 0; i < capturedArg1.size(); ++i) {
Assert.assertEquals(expectedArg1.get(i), capturedArg1.get(i)); assertEquals(expectedArg1.get(i), capturedArg1.get(i));
Assert.assertEquals(expectedArg2.get(i), capturedArg2.get(i)); assertEquals(expectedArg2.get(i), capturedArg2.get(i));
} }
} }
private void verifyParentsChanged(List<Http2Stream> expectedArg1, List<Http2Stream> expectedArg2) { private void verifyParentsChanged(List<Http2Stream> expectedArg1, List<Http2Stream> expectedArg2) {
Assert.assertTrue(expectedArg1.size() == expectedArg2.size()); assertTrue(expectedArg1.size() == expectedArg2.size());
ArgumentCaptor<Http2Stream> arg1Captor = ArgumentCaptor.forClass(Http2Stream.class); ArgumentCaptor<Http2Stream> arg1Captor = ArgumentCaptor.forClass(Http2Stream.class);
ArgumentCaptor<Http2Stream> arg2Captor = ArgumentCaptor.forClass(Http2Stream.class); ArgumentCaptor<Http2Stream> arg2Captor = ArgumentCaptor.forClass(Http2Stream.class);
verify(clientListener, times(expectedArg1.size())).priorityTreeParentChanged(arg1Captor.capture(), verify(clientListener, times(expectedArg1.size())).priorityTreeParentChanged(arg1Captor.capture(),
arg2Captor.capture()); arg2Captor.capture());
List<Http2Stream> capturedArg1 = arg1Captor.getAllValues(); List<Http2Stream> capturedArg1 = arg1Captor.getAllValues();
List<Http2Stream> capturedArg2 = arg2Captor.getAllValues(); List<Http2Stream> capturedArg2 = arg2Captor.getAllValues();
Assert.assertTrue(capturedArg1.size() == capturedArg2.size()); assertTrue(capturedArg1.size() == capturedArg2.size());
Assert.assertTrue(capturedArg1.size() == expectedArg1.size()); assertTrue(capturedArg1.size() == expectedArg1.size());
for (int i = 0; i < capturedArg1.size(); ++i) { for (int i = 0; i < capturedArg1.size(); ++i) {
Assert.assertEquals(expectedArg1.get(i), capturedArg1.get(i)); assertEquals(expectedArg1.get(i), capturedArg1.get(i));
Assert.assertEquals(expectedArg2.get(i), capturedArg2.get(i)); assertEquals(expectedArg2.get(i), capturedArg2.get(i));
} }
} }

View File

@ -54,7 +54,7 @@ public class DefaultHttp2HeadersEncoderTest {
encoder.encodeHeaders(headers, Unpooled.buffer()); encoder.encodeHeaders(headers, Unpooled.buffer());
} }
private Http2Headers headers() { private static Http2Headers headers() {
return new DefaultHttp2Headers().method(as("GET")).add(as("a"), as("1")) return new DefaultHttp2Headers().method(as("GET")).add(as("a"), as("1"))
.add(as("a"), as("2")); .add(as("a"), as("2"));
} }

View File

@ -213,7 +213,7 @@ public class DefaultHttp2InboundFlowControllerTest {
return buffer; return buffer;
} }
private void verifyWindowUpdateSent(int streamId, int windowSizeIncrement) throws Http2Exception { private void verifyWindowUpdateSent(int streamId, int windowSizeIncrement) {
verify(frameWriter).writeWindowUpdate(eq(ctx), eq(streamId), eq(windowSizeIncrement), eq(promise)); verify(frameWriter).writeWindowUpdate(eq(ctx), eq(streamId), eq(windowSizeIncrement), eq(promise));
} }
@ -221,7 +221,7 @@ public class DefaultHttp2InboundFlowControllerTest {
verify(frameWriter, never()).writeWindowUpdate(eq(ctx), eq(streamId), anyInt(), eq(promise)); verify(frameWriter, never()).writeWindowUpdate(eq(ctx), eq(streamId), anyInt(), eq(promise));
} }
private void verifyWindowUpdateNotSent() throws Http2Exception { private void verifyWindowUpdateNotSent() {
verify(frameWriter, never()).writeWindowUpdate(any(ChannelHandlerContext.class), anyInt(), anyInt(), verify(frameWriter, never()).writeWindowUpdate(any(ChannelHandlerContext.class), anyInt(), anyInt(),
any(ChannelPromise.class)); any(ChannelPromise.class));
} }

View File

@ -20,6 +20,7 @@ import static io.netty.handler.codec.http2.Http2CodecUtil.DEFAULT_PRIORITY_WEIGH
import static io.netty.handler.codec.http2.Http2CodecUtil.DEFAULT_WINDOW_SIZE; import static io.netty.handler.codec.http2.Http2CodecUtil.DEFAULT_WINDOW_SIZE;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertNotSame;
import static org.mockito.Matchers.any; import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyBoolean; import static org.mockito.Matchers.anyBoolean;
import static org.mockito.Matchers.anyInt; import static org.mockito.Matchers.anyInt;
@ -151,7 +152,7 @@ public class DefaultHttp2OutboundFlowControllerTest {
// Now write another and verify that the last write is updated. // Now write another and verify that the last write is updated.
ChannelFuture future2 = controller.writeData(ctx, STREAM_A, data, 0, false, promise2); ChannelFuture future2 = controller.writeData(ctx, STREAM_A, data, 0, false, promise2);
assertTrue(future1 != future2); assertNotSame(future1, future2);
assertEquals(future2, controller.lastWriteForStream(STREAM_A)); assertEquals(future2, controller.lastWriteForStream(STREAM_A));
} finally { } finally {
manualSafeRelease(data); manualSafeRelease(data);
@ -656,7 +657,7 @@ public class DefaultHttp2OutboundFlowControllerTest {
assertEquals(0, window(CONNECTION_STREAM_ID)); assertEquals(0, window(CONNECTION_STREAM_ID));
assertEquals(0, window(STREAM_A)); assertEquals(0, window(STREAM_A));
assertEquals(DEFAULT_WINDOW_SIZE - 5, window(STREAM_B), 2); assertEquals(DEFAULT_WINDOW_SIZE - 5, window(STREAM_B), 2);
assertEquals((2 * DEFAULT_WINDOW_SIZE) - 5, window(STREAM_C) + window(STREAM_D), 5); assertEquals(2 * DEFAULT_WINDOW_SIZE - 5, window(STREAM_C) + window(STREAM_D), 5);
final ArgumentCaptor<ByteBuf> captor = ArgumentCaptor.forClass(ByteBuf.class); final ArgumentCaptor<ByteBuf> captor = ArgumentCaptor.forClass(ByteBuf.class);
@ -769,7 +770,7 @@ public class DefaultHttp2OutboundFlowControllerTest {
assertEquals(0, window(CONNECTION_STREAM_ID)); assertEquals(0, window(CONNECTION_STREAM_ID));
assertEquals(DEFAULT_WINDOW_SIZE - 5, window(STREAM_A)); assertEquals(DEFAULT_WINDOW_SIZE - 5, window(STREAM_A));
assertEquals(0, window(STREAM_B)); assertEquals(0, window(STREAM_B));
assertEquals((2 * DEFAULT_WINDOW_SIZE) - 5, window(STREAM_C) + window(STREAM_D)); assertEquals(2 * DEFAULT_WINDOW_SIZE - 5, window(STREAM_C) + window(STREAM_D));
final ArgumentCaptor<ByteBuf> captor = ArgumentCaptor.forClass(ByteBuf.class); final ArgumentCaptor<ByteBuf> captor = ArgumentCaptor.forClass(ByteBuf.class);
@ -1287,7 +1288,7 @@ public class DefaultHttp2OutboundFlowControllerTest {
return sum; return sum;
} }
private void send(int streamId, ByteBuf data, int padding) throws Http2Exception { private void send(int streamId, ByteBuf data, int padding) {
ChannelFuture future = controller.writeData(ctx, streamId, data, padding, false, promise); ChannelFuture future = controller.writeData(ctx, streamId, data, padding, false, promise);
assertEquals(future, controller.lastWriteForStream(streamId)); assertEquals(future, controller.lastWriteForStream(streamId));
} }

View File

@ -163,7 +163,7 @@ public class Http2ConnectionHandlerTest {
handler = newHandler(); handler = newHandler();
handler.channelRead(ctx, copiedBuffer("BAD_PREFACE", UTF_8)); handler.channelRead(ctx, copiedBuffer("BAD_PREFACE", UTF_8));
ArgumentCaptor<ByteBuf> captor = ArgumentCaptor.forClass(ByteBuf.class); ArgumentCaptor<ByteBuf> captor = ArgumentCaptor.forClass(ByteBuf.class);
verify(frameWriter).writeGoAway(eq(ctx), eq(0), eq((long) PROTOCOL_ERROR.code()), verify(frameWriter).writeGoAway(eq(ctx), eq(0), eq(PROTOCOL_ERROR.code()),
captor.capture(), eq(promise)); captor.capture(), eq(promise));
captor.getValue().release(); captor.getValue().release();
} }
@ -187,7 +187,7 @@ public class Http2ConnectionHandlerTest {
when(remote.lastStreamCreated()).thenReturn(STREAM_ID); when(remote.lastStreamCreated()).thenReturn(STREAM_ID);
handler.exceptionCaught(ctx, e); handler.exceptionCaught(ctx, e);
ArgumentCaptor<ByteBuf> captor = ArgumentCaptor.forClass(ByteBuf.class); ArgumentCaptor<ByteBuf> captor = ArgumentCaptor.forClass(ByteBuf.class);
verify(frameWriter).writeGoAway(eq(ctx), eq(STREAM_ID), eq((long) PROTOCOL_ERROR.code()), verify(frameWriter).writeGoAway(eq(ctx), eq(STREAM_ID), eq(PROTOCOL_ERROR.code()),
captor.capture(), eq(promise)); captor.capture(), eq(promise));
captor.getValue().release(); captor.getValue().release();
} }

View File

@ -18,8 +18,10 @@ package io.netty.handler.codec.http2;
import static io.netty.handler.codec.http2.Http2TestUtil.as; import static io.netty.handler.codec.http2.Http2TestUtil.as;
import static io.netty.handler.codec.http2.Http2TestUtil.randomString; import static io.netty.handler.codec.http2.Http2TestUtil.randomString;
import static io.netty.handler.codec.http2.Http2TestUtil.runInChannel; import static io.netty.handler.codec.http2.Http2TestUtil.runInChannel;
import static io.netty.handler.codec.http2.Http2TestUtil.FrameCountDown;
import static io.netty.util.CharsetUtil.UTF_8; import static io.netty.util.CharsetUtil.UTF_8;
import static java.util.concurrent.TimeUnit.SECONDS; import static java.util.concurrent.TimeUnit.SECONDS;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertFalse;
@ -57,7 +59,6 @@ import java.io.ByteArrayOutputStream;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.util.Random; import java.util.Random;
import java.util.concurrent.CountDownLatch; import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import org.junit.After; import org.junit.After;
import org.junit.Before; import org.junit.Before;
@ -83,7 +84,7 @@ public class Http2ConnectionRoundtripTest {
private Bootstrap cb; private Bootstrap cb;
private Channel serverChannel; private Channel serverChannel;
private Channel clientChannel; private Channel clientChannel;
private Http2TestUtil.FrameCountDown serverFrameCountDown; private FrameCountDown serverFrameCountDown;
private CountDownLatch requestLatch; private CountDownLatch requestLatch;
private CountDownLatch dataLatch; private CountDownLatch dataLatch;
private CountDownLatch trailersLatch; private CountDownLatch trailersLatch;
@ -98,9 +99,9 @@ public class Http2ConnectionRoundtripTest {
@After @After
public void teardown() throws Exception { public void teardown() throws Exception {
serverChannel.close().sync(); serverChannel.close().sync();
Future<?> serverGroup = sb.group().shutdownGracefully(0, 0, TimeUnit.MILLISECONDS); Future<?> serverGroup = sb.group().shutdownGracefully(0, 0, MILLISECONDS);
Future<?> serverChildGroup = sb.childGroup().shutdownGracefully(0, 0, TimeUnit.MILLISECONDS); Future<?> serverChildGroup = sb.childGroup().shutdownGracefully(0, 0, MILLISECONDS);
Future<?> clientGroup = cb.group().shutdownGracefully(0, 0, TimeUnit.MILLISECONDS); Future<?> clientGroup = cb.group().shutdownGracefully(0, 0, MILLISECONDS);
serverGroup.sync(); serverGroup.sync();
serverChildGroup.sync(); serverChildGroup.sync();
clientGroup.sync(); clientGroup.sync();
@ -130,7 +131,7 @@ public class Http2ConnectionRoundtripTest {
}); });
// Wait for the server to create the stream. // Wait for the server to create the stream.
assertTrue(requestLatch.await(5, TimeUnit.SECONDS)); assertTrue(requestLatch.await(5, SECONDS));
// Add a handler that will immediately throw an exception. // Add a handler that will immediately throw an exception.
clientChannel.pipeline().addFirst(new ChannelHandlerAdapter() { clientChannel.pipeline().addFirst(new ChannelHandlerAdapter() {
@ -141,7 +142,7 @@ public class Http2ConnectionRoundtripTest {
}); });
// Wait for the close to occur. // Wait for the close to occur.
assertTrue(closeLatch.await(5, TimeUnit.SECONDS)); assertTrue(closeLatch.await(5, SECONDS));
assertFalse(clientChannel.isOpen()); assertFalse(clientChannel.isOpen());
} }
@ -173,10 +174,10 @@ public class Http2ConnectionRoundtripTest {
}); });
// Wait for the server to create the stream. // Wait for the server to create the stream.
assertTrue(requestLatch.await(5, TimeUnit.SECONDS)); assertTrue(requestLatch.await(5, SECONDS));
// Wait for the close to occur. // Wait for the close to occur.
assertTrue(closeLatch.await(5, TimeUnit.SECONDS)); assertTrue(closeLatch.await(5, SECONDS));
assertFalse(clientChannel.isOpen()); assertFalse(clientChannel.isOpen());
} }
@ -204,7 +205,7 @@ public class Http2ConnectionRoundtripTest {
}); });
// Wait for the server to create the stream. // Wait for the server to create the stream.
assertTrue(requestLatch.await(5, TimeUnit.SECONDS)); assertTrue(requestLatch.await(5, SECONDS));
// Add a handler that will immediately throw an exception. // Add a handler that will immediately throw an exception.
clientChannel.pipeline().addFirst(new ChannelHandlerAdapter() { clientChannel.pipeline().addFirst(new ChannelHandlerAdapter() {
@ -215,7 +216,7 @@ public class Http2ConnectionRoundtripTest {
}); });
// The close should NOT occur. // The close should NOT occur.
assertFalse(closeLatch.await(5, TimeUnit.SECONDS)); assertFalse(closeLatch.await(5, SECONDS));
assertTrue(clientChannel.isOpen()); assertTrue(clientChannel.isOpen());
} }
@ -236,7 +237,7 @@ public class Http2ConnectionRoundtripTest {
}); });
// Wait for the server to create the stream. // Wait for the server to create the stream.
assertTrue(requestLatch.await(5, TimeUnit.SECONDS)); assertTrue(requestLatch.await(5, SECONDS));
verify(serverListener).onGoAwayRead(any(ChannelHandlerContext.class), eq(0), verify(serverListener).onGoAwayRead(any(ChannelHandlerContext.class), eq(0),
eq(Http2Error.PROTOCOL_ERROR.code()), any(ByteBuf.class)); eq(Http2Error.PROTOCOL_ERROR.code()), any(ByteBuf.class));
} }
@ -282,7 +283,7 @@ public class Http2ConnectionRoundtripTest {
}); });
// Wait for the trailers to be received. // Wait for the trailers to be received.
assertTrue(trailersLatch.await(5, TimeUnit.SECONDS)); assertTrue(trailersLatch.await(5, SECONDS));
// Verify that headers and trailers were received. // Verify that headers and trailers were received.
verify(serverListener).onHeadersRead(any(ChannelHandlerContext.class), eq(3), eq(headers), eq(0), verify(serverListener).onHeadersRead(any(ChannelHandlerContext.class), eq(3), eq(headers), eq(0),
@ -400,7 +401,7 @@ public class Http2ConnectionRoundtripTest {
protected void initChannel(Channel ch) throws Exception { protected void initChannel(Channel ch) throws Exception {
ChannelPipeline p = ch.pipeline(); ChannelPipeline p = ch.pipeline();
serverFrameCountDown = serverFrameCountDown =
new Http2TestUtil.FrameCountDown(serverListener, requestLatch, dataLatch, new FrameCountDown(serverListener, requestLatch, dataLatch,
trailersLatch); trailersLatch);
p.addLast(new Http2ConnectionHandler(true, serverFrameCountDown)); p.addLast(new Http2ConnectionHandler(true, serverFrameCountDown));
p.addLast(Http2CodecUtil.ignoreSettingsHandler()); p.addLast(Http2CodecUtil.ignoreSettingsHandler());
@ -435,7 +436,7 @@ public class Http2ConnectionRoundtripTest {
return ctx().newPromise(); return ctx().newPromise();
} }
private Http2Headers dummyHeaders() { private static Http2Headers dummyHeaders() {
return new DefaultHttp2Headers().method(as("GET")).scheme(as("https")) return new DefaultHttp2Headers().method(as("GET")).scheme(as("https"))
.authority(as("example.org")).path(as("/some/path/resource2")).add(randomString(), randomString()); .authority(as("example.org")).path(as("/some/path/resource2")).add(randomString(), randomString());
} }

View File

@ -394,7 +394,7 @@ public class Http2FrameRoundtripTest {
return ctx().newPromise(); return ctx().newPromise();
} }
private Http2Headers headers() { private static Http2Headers headers() {
return new DefaultHttp2Headers().method(as("GET")).scheme(as("https")) return new DefaultHttp2Headers().method(as("GET")).scheme(as("https"))
.authority(as("example.org")).path(as("/some/path/resource2")).add(randomString(), randomString()); .authority(as("example.org")).path(as("/some/path/resource2")).add(randomString(), randomString());
} }

View File

@ -90,7 +90,7 @@ public class Http2HeaderBlockIOTest {
assertEquals(in, out); assertEquals(in, out);
} }
private Http2Headers headers() { private static Http2Headers headers() {
return new DefaultHttp2Headers().method(as("GET")).scheme(as("https")) return new DefaultHttp2Headers().method(as("GET")).scheme(as("https"))
.authority(as("example.org")).path(as("/some/path/resource2")) .authority(as("example.org")).path(as("/some/path/resource2"))
.add(as("accept"), as("image/png")).add(as("cache-control"), as("no-cache")) .add(as("accept"), as("image/png")).add(as("cache-control"), as("no-cache"))

View File

@ -115,7 +115,7 @@ final class Http2TestUtil {
if (connection != null) { if (connection != null) {
Http2Stream stream = connection.stream(streamId); Http2Stream stream = connection.stream(streamId);
if (stream == null) { if (stream == null) {
if ((connection.isServer() && streamId % 2 == 0) || (!connection.isServer() && streamId % 2 != 0)) { if (connection.isServer() && streamId % 2 == 0 || !connection.isServer() && streamId % 2 != 0) {
stream = connection.local().createStream(streamId, halfClosed); stream = connection.local().createStream(streamId, halfClosed);
} else { } else {
stream = connection.remote().createStream(streamId, halfClosed); stream = connection.remote().createStream(streamId, halfClosed);
@ -264,15 +264,15 @@ final class Http2TestUtil {
private final CountDownLatch dataLatch; private final CountDownLatch dataLatch;
private final CountDownLatch trailersLatch; private final CountDownLatch trailersLatch;
public FrameCountDown(Http2FrameListener listener, CountDownLatch messageLatch) { FrameCountDown(Http2FrameListener listener, CountDownLatch messageLatch) {
this(listener, messageLatch, null); this(listener, messageLatch, null);
} }
public FrameCountDown(Http2FrameListener listener, CountDownLatch messageLatch, CountDownLatch dataLatch) { FrameCountDown(Http2FrameListener listener, CountDownLatch messageLatch, CountDownLatch dataLatch) {
this(listener, messageLatch, dataLatch, null); this(listener, messageLatch, dataLatch, null);
} }
public FrameCountDown(Http2FrameListener listener, CountDownLatch messageLatch, FrameCountDown(Http2FrameListener listener, CountDownLatch messageLatch,
CountDownLatch dataLatch, CountDownLatch trailersLatch) { CountDownLatch dataLatch, CountDownLatch trailersLatch) {
this.listener = listener; this.listener = listener;
this.messageLatch = messageLatch; this.messageLatch = messageLatch;

View File

@ -15,6 +15,7 @@
package io.netty.example.http2.server; package io.netty.example.http2.server;
import io.netty.channel.ChannelHandler; import io.netty.channel.ChannelHandler;
import io.netty.handler.codec.http2.Http2ConnectionHandler;
import io.netty.handler.codec.http2.Http2OrHttpChooser; import io.netty.handler.codec.http2.Http2OrHttpChooser;
import javax.net.ssl.SSLEngine; import javax.net.ssl.SSLEngine;
@ -51,7 +52,7 @@ public class Http2OrHttpHandler extends Http2OrHttpChooser {
} }
@Override @Override
protected ChannelHandler createHttp2RequestHandler() { protected Http2ConnectionHandler createHttp2RequestHandler() {
return new HelloWorldHttp2Handler(); return new HelloWorldHttp2Handler();
} }
} }