Remove dead code and fix warnings in the http2 module (#11593)
Motivation: Opportunities for clean up found while working on a different PR. Modification: * Dead code has been removed. * Unnecessary parenthesis, qualifiers, etc. removed. * Unused imports removed. * Override annotations added where missing. Result: Cleaner code
This commit is contained in:
parent
9eb4f0ee85
commit
4a7fa3777e
@ -18,7 +18,6 @@ package io.netty.handler.codec.http2;
|
|||||||
|
|
||||||
import io.netty.channel.Channel;
|
import io.netty.channel.Channel;
|
||||||
import io.netty.handler.codec.http2.Http2HeadersEncoder.SensitivityDetector;
|
import io.netty.handler.codec.http2.Http2HeadersEncoder.SensitivityDetector;
|
||||||
import io.netty.util.internal.ObjectUtil;
|
|
||||||
import io.netty.util.internal.UnstableApi;
|
import io.netty.util.internal.UnstableApi;
|
||||||
|
|
||||||
import static io.netty.handler.codec.http2.Http2CodecUtil.DEFAULT_HEADER_LIST_SIZE;
|
import static io.netty.handler.codec.http2.Http2CodecUtil.DEFAULT_HEADER_LIST_SIZE;
|
||||||
@ -347,7 +346,7 @@ public abstract class AbstractHttp2ConnectionHandlerBuilder<T extends Http2Conne
|
|||||||
*/
|
*/
|
||||||
protected B encoderEnforceMaxQueuedControlFrames(int maxQueuedControlFrames) {
|
protected B encoderEnforceMaxQueuedControlFrames(int maxQueuedControlFrames) {
|
||||||
enforceNonCodecConstraints("encoderEnforceMaxQueuedControlFrames");
|
enforceNonCodecConstraints("encoderEnforceMaxQueuedControlFrames");
|
||||||
this.maxQueuedControlFrames = ObjectUtil.checkPositiveOrZero(maxQueuedControlFrames, "maxQueuedControlFrames");
|
this.maxQueuedControlFrames = checkPositiveOrZero(maxQueuedControlFrames, "maxQueuedControlFrames");
|
||||||
return self();
|
return self();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -376,7 +375,7 @@ public abstract class AbstractHttp2ConnectionHandlerBuilder<T extends Http2Conne
|
|||||||
*/
|
*/
|
||||||
protected B encoderIgnoreMaxHeaderListSize(boolean ignoreMaxHeaderListSize) {
|
protected B encoderIgnoreMaxHeaderListSize(boolean ignoreMaxHeaderListSize) {
|
||||||
enforceNonCodecConstraints("encoderIgnoreMaxHeaderListSize");
|
enforceNonCodecConstraints("encoderIgnoreMaxHeaderListSize");
|
||||||
this.encoderIgnoreMaxHeaderListSize = ignoreMaxHeaderListSize;
|
encoderIgnoreMaxHeaderListSize = ignoreMaxHeaderListSize;
|
||||||
return self();
|
return self();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -428,7 +427,7 @@ public abstract class AbstractHttp2ConnectionHandlerBuilder<T extends Http2Conne
|
|||||||
*/
|
*/
|
||||||
protected B decoderEnforceMaxConsecutiveEmptyDataFrames(int maxConsecutiveEmptyFrames) {
|
protected B decoderEnforceMaxConsecutiveEmptyDataFrames(int maxConsecutiveEmptyFrames) {
|
||||||
enforceNonCodecConstraints("maxConsecutiveEmptyFrames");
|
enforceNonCodecConstraints("maxConsecutiveEmptyFrames");
|
||||||
this.maxConsecutiveEmptyFrames = ObjectUtil.checkPositiveOrZero(
|
this.maxConsecutiveEmptyFrames = checkPositiveOrZero(
|
||||||
maxConsecutiveEmptyFrames, "maxConsecutiveEmptyFrames");
|
maxConsecutiveEmptyFrames, "maxConsecutiveEmptyFrames");
|
||||||
return self();
|
return self();
|
||||||
}
|
}
|
||||||
@ -439,7 +438,7 @@ public abstract class AbstractHttp2ConnectionHandlerBuilder<T extends Http2Conne
|
|||||||
*/
|
*/
|
||||||
protected B autoAckSettingsFrame(boolean autoAckSettings) {
|
protected B autoAckSettingsFrame(boolean autoAckSettings) {
|
||||||
enforceNonCodecConstraints("autoAckSettingsFrame");
|
enforceNonCodecConstraints("autoAckSettingsFrame");
|
||||||
this.autoAckSettingsFrame = autoAckSettings;
|
autoAckSettingsFrame = autoAckSettings;
|
||||||
return self();
|
return self();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,7 +102,7 @@ abstract class AbstractHttp2StreamChannel extends DefaultAttributeMap implements
|
|||||||
if (cause != null) {
|
if (cause != null) {
|
||||||
Throwable unwrappedCause;
|
Throwable unwrappedCause;
|
||||||
// Unwrap if needed
|
// Unwrap if needed
|
||||||
if (cause instanceof Http2FrameStreamException && ((unwrappedCause = cause.getCause()) != null)) {
|
if (cause instanceof Http2FrameStreamException && (unwrappedCause = cause.getCause()) != null) {
|
||||||
cause = unwrappedCause;
|
cause = unwrappedCause;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -656,7 +656,7 @@ abstract class AbstractHttp2StreamChannel extends DefaultAttributeMap implements
|
|||||||
|
|
||||||
// Only ever send a reset frame if the connection is still alive and if the stream was created before
|
// Only ever send a reset frame if the connection is still alive and if the stream was created before
|
||||||
// as otherwise we may send a RST on a stream in an invalid state and cause a connection error.
|
// as otherwise we may send a RST on a stream in an invalid state and cause a connection error.
|
||||||
if (parent().isActive() && !readEOS && Http2CodecUtil.isStreamIdValid(stream.id())) {
|
if (parent().isActive() && !readEOS && isStreamIdValid(stream.id())) {
|
||||||
Http2StreamFrame resetFrame = new DefaultHttp2ResetFrame(Http2Error.CANCEL).stream(stream());
|
Http2StreamFrame resetFrame = new DefaultHttp2ResetFrame(Http2Error.CANCEL).stream(stream());
|
||||||
write(resetFrame, newPromise());
|
write(resetFrame, newPromise());
|
||||||
flush();
|
flush();
|
||||||
|
@ -45,7 +45,7 @@ public abstract class AbstractHttp2StreamFrame implements Http2StreamFrame {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
Http2StreamFrame other = (Http2StreamFrame) o;
|
Http2StreamFrame other = (Http2StreamFrame) o;
|
||||||
return stream == other.stream() || (stream != null && stream.equals(other.stream()));
|
return stream == other.stream() || stream != null && stream.equals(other.stream());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -675,7 +675,7 @@ public class DefaultHttp2Connection implements Http2Connection {
|
|||||||
*/
|
*/
|
||||||
private int nextReservationStreamId;
|
private int nextReservationStreamId;
|
||||||
private int lastStreamKnownByPeer = -1;
|
private int lastStreamKnownByPeer = -1;
|
||||||
private boolean pushToAllowed = true;
|
private boolean pushToAllowed;
|
||||||
private F flowController;
|
private F flowController;
|
||||||
private int maxStreams;
|
private int maxStreams;
|
||||||
private int maxActiveStreams;
|
private int maxActiveStreams;
|
||||||
@ -840,7 +840,7 @@ public class DefaultHttp2Connection implements Http2Connection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void lastStreamKnownByPeer(int lastKnownStream) {
|
private void lastStreamKnownByPeer(int lastKnownStream) {
|
||||||
this.lastStreamKnownByPeer = lastKnownStream;
|
lastStreamKnownByPeer = lastKnownStream;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -163,11 +163,6 @@ public class DefaultHttp2ConnectionDecoder implements Http2ConnectionDecoder {
|
|||||||
return listener;
|
return listener;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Visible for testing
|
|
||||||
Http2FrameListener internalFrameListener() {
|
|
||||||
return internalFrameListener;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean prefaceReceived() {
|
public boolean prefaceReceived() {
|
||||||
return FrameReadListener.class == internalFrameListener.getClass();
|
return FrameReadListener.class == internalFrameListener.getClass();
|
||||||
@ -625,7 +620,8 @@ public class DefaultHttp2ConnectionDecoder implements Http2ConnectionDecoder {
|
|||||||
// sent). We don't have enough information to know for sure, so we choose the lesser of the two errors.
|
// sent). We don't have enough information to know for sure, so we choose the lesser of the two errors.
|
||||||
throw streamError(streamId, STREAM_CLOSED, "Received %s frame for an unknown stream %d",
|
throw streamError(streamId, STREAM_CLOSED, "Received %s frame for an unknown stream %d",
|
||||||
frameName, streamId);
|
frameName, streamId);
|
||||||
} else if (stream.isResetSent() || streamCreatedAfterGoAwaySent(streamId)) {
|
}
|
||||||
|
if (stream.isResetSent() || streamCreatedAfterGoAwaySent(streamId)) {
|
||||||
// If we have sent a reset stream it is assumed the stream will be closed after the write completes.
|
// If we have sent a reset stream it is assumed the stream will be closed after the write completes.
|
||||||
// If we have not sent a reset, but the stream was created after a GoAway this is not supported by
|
// If we have not sent a reset, but the stream was created after a GoAway this is not supported by
|
||||||
// DefaultHttp2Connection and if a custom Http2Connection is used it is assumed the lifetime is managed
|
// DefaultHttp2Connection and if a custom Http2Connection is used it is assumed the lifetime is managed
|
||||||
@ -634,8 +630,8 @@ public class DefaultHttp2ConnectionDecoder implements Http2ConnectionDecoder {
|
|||||||
if (logger.isInfoEnabled()) {
|
if (logger.isInfoEnabled()) {
|
||||||
logger.info("{} ignoring {} frame for stream {}", ctx.channel(), frameName,
|
logger.info("{} ignoring {} frame for stream {}", ctx.channel(), frameName,
|
||||||
stream.isResetSent() ? "RST_STREAM sent." :
|
stream.isResetSent() ? "RST_STREAM sent." :
|
||||||
("Stream created after GOAWAY sent. Last known stream by peer " +
|
"Stream created after GOAWAY sent. Last known stream by peer " +
|
||||||
connection.remote().lastStreamKnownByPeer()));
|
connection.remote().lastStreamKnownByPeer());
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -539,7 +539,7 @@ public class DefaultHttp2ConnectionEncoder implements Http2ConnectionEncoder, Ht
|
|||||||
*/
|
*/
|
||||||
private final class FlowControlledHeaders extends FlowControlledBase {
|
private final class FlowControlledHeaders extends FlowControlledBase {
|
||||||
private final Http2Headers headers;
|
private final Http2Headers headers;
|
||||||
private final boolean hasPriorty;
|
private final boolean hasPriority;
|
||||||
private final int streamDependency;
|
private final int streamDependency;
|
||||||
private final short weight;
|
private final short weight;
|
||||||
private final boolean exclusive;
|
private final boolean exclusive;
|
||||||
@ -549,7 +549,7 @@ public class DefaultHttp2ConnectionEncoder implements Http2ConnectionEncoder, Ht
|
|||||||
int padding, boolean endOfStream, ChannelPromise promise) {
|
int padding, boolean endOfStream, ChannelPromise promise) {
|
||||||
super(stream, padding, endOfStream, promise);
|
super(stream, padding, endOfStream, promise);
|
||||||
this.headers = headers;
|
this.headers = headers;
|
||||||
this.hasPriorty = hasPriority;
|
this.hasPriority = hasPriority;
|
||||||
this.streamDependency = streamDependency;
|
this.streamDependency = streamDependency;
|
||||||
this.weight = weight;
|
this.weight = weight;
|
||||||
this.exclusive = exclusive;
|
this.exclusive = exclusive;
|
||||||
@ -575,7 +575,7 @@ public class DefaultHttp2ConnectionEncoder implements Http2ConnectionEncoder, Ht
|
|||||||
// closeStreamLocal().
|
// closeStreamLocal().
|
||||||
promise.addListener(this);
|
promise.addListener(this);
|
||||||
|
|
||||||
ChannelFuture f = sendHeaders(frameWriter, ctx, stream.id(), headers, hasPriorty, streamDependency,
|
ChannelFuture f = sendHeaders(frameWriter, ctx, stream.id(), headers, hasPriority, streamDependency,
|
||||||
weight, exclusive, padding, endOfStream, promise);
|
weight, exclusive, padding, endOfStream, promise);
|
||||||
// Writing headers may fail during the encode state if they violate HPACK limits.
|
// Writing headers may fail during the encode state if they violate HPACK limits.
|
||||||
Throwable failureCause = f.cause();
|
Throwable failureCause = f.cause();
|
||||||
|
@ -26,7 +26,6 @@ import static io.netty.handler.codec.http2.Http2CodecUtil.INT_FIELD_LENGTH;
|
|||||||
import static io.netty.handler.codec.http2.Http2CodecUtil.PING_FRAME_PAYLOAD_LENGTH;
|
import static io.netty.handler.codec.http2.Http2CodecUtil.PING_FRAME_PAYLOAD_LENGTH;
|
||||||
import static io.netty.handler.codec.http2.Http2CodecUtil.PRIORITY_ENTRY_LENGTH;
|
import static io.netty.handler.codec.http2.Http2CodecUtil.PRIORITY_ENTRY_LENGTH;
|
||||||
import static io.netty.handler.codec.http2.Http2CodecUtil.SETTINGS_INITIAL_WINDOW_SIZE;
|
import static io.netty.handler.codec.http2.Http2CodecUtil.SETTINGS_INITIAL_WINDOW_SIZE;
|
||||||
import static io.netty.handler.codec.http2.Http2CodecUtil.SETTINGS_MAX_FRAME_SIZE;
|
|
||||||
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.headerListSizeExceeded;
|
import static io.netty.handler.codec.http2.Http2CodecUtil.headerListSizeExceeded;
|
||||||
import static io.netty.handler.codec.http2.Http2CodecUtil.isMaxFrameSizeValid;
|
import static io.netty.handler.codec.http2.Http2CodecUtil.isMaxFrameSizeValid;
|
||||||
@ -519,14 +518,10 @@ public class DefaultHttp2FrameReader implements Http2FrameReader, Http2FrameSize
|
|||||||
try {
|
try {
|
||||||
settings.put(id, Long.valueOf(value));
|
settings.put(id, Long.valueOf(value));
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
switch(id) {
|
if (id == SETTINGS_INITIAL_WINDOW_SIZE) {
|
||||||
case SETTINGS_MAX_FRAME_SIZE:
|
|
||||||
throw connectionError(PROTOCOL_ERROR, e, e.getMessage());
|
|
||||||
case SETTINGS_INITIAL_WINDOW_SIZE:
|
|
||||||
throw connectionError(FLOW_CONTROL_ERROR, e, e.getMessage());
|
throw connectionError(FLOW_CONTROL_ERROR, e, e.getMessage());
|
||||||
default:
|
|
||||||
throw connectionError(PROTOCOL_ERROR, e, e.getMessage());
|
|
||||||
}
|
}
|
||||||
|
throw connectionError(PROTOCOL_ERROR, e, e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
listener.onSettingsRead(ctx, settings);
|
listener.onSettingsRead(ctx, settings);
|
||||||
|
@ -203,7 +203,7 @@ public class DefaultHttp2FrameWriter implements Http2FrameWriter, Http2FrameSize
|
|||||||
|
|
||||||
do {
|
do {
|
||||||
int frameDataBytes = min(remainingData, maxFrameSize);
|
int frameDataBytes = min(remainingData, maxFrameSize);
|
||||||
int framePaddingBytes = min(padding, max(0, (maxFrameSize - 1) - frameDataBytes));
|
int framePaddingBytes = min(padding, max(0, maxFrameSize - 1 - frameDataBytes));
|
||||||
|
|
||||||
// Decrement the remaining counters.
|
// Decrement the remaining counters.
|
||||||
padding -= framePaddingBytes;
|
padding -= framePaddingBytes;
|
||||||
@ -623,10 +623,4 @@ public class DefaultHttp2FrameWriter implements Http2FrameWriter, Http2FrameSize
|
|||||||
private static void verifyWindowSizeIncrement(int windowSizeIncrement) {
|
private static void verifyWindowSizeIncrement(int windowSizeIncrement) {
|
||||||
checkPositiveOrZero(windowSizeIncrement, "windowSizeIncrement");
|
checkPositiveOrZero(windowSizeIncrement, "windowSizeIncrement");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void verifyPingPayload(ByteBuf data) {
|
|
||||||
if (data == null || data.readableBytes() != PING_FRAME_PAYLOAD_LENGTH) {
|
|
||||||
throw new IllegalArgumentException("Opaque data must be " + PING_FRAME_PAYLOAD_LENGTH + " bytes");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -166,7 +166,7 @@ public final class DefaultHttp2GoAwayFrame extends DefaultByteBufHolder implemen
|
|||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
int hash = super.hashCode();
|
int hash = super.hashCode();
|
||||||
hash = hash * 31 + (int) (errorCode ^ (errorCode >>> 32));
|
hash = hash * 31 + (int) (errorCode ^ errorCode >>> 32);
|
||||||
hash = hash * 31 + extraStreamIds;
|
hash = hash * 31 + extraStreamIds;
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
@ -184,7 +184,7 @@ public class DefaultHttp2Headers
|
|||||||
}
|
}
|
||||||
|
|
||||||
private final class Http2HeaderEntry extends HeaderEntry<CharSequence, CharSequence> {
|
private final class Http2HeaderEntry extends HeaderEntry<CharSequence, CharSequence> {
|
||||||
protected Http2HeaderEntry(int hash, CharSequence key, CharSequence value,
|
Http2HeaderEntry(int hash, CharSequence key, CharSequence value,
|
||||||
HeaderEntry<CharSequence, CharSequence> next) {
|
HeaderEntry<CharSequence, CharSequence> next) {
|
||||||
super(hash, key);
|
super(hash, key);
|
||||||
this.value = value;
|
this.value = value;
|
||||||
|
@ -80,7 +80,7 @@ public class DefaultHttp2HeadersDecoder implements Http2HeadersDecoder, Http2Hea
|
|||||||
DefaultHttp2HeadersDecoder(boolean validateHeaders, HpackDecoder hpackDecoder) {
|
DefaultHttp2HeadersDecoder(boolean validateHeaders, HpackDecoder hpackDecoder) {
|
||||||
this.hpackDecoder = requireNonNull(hpackDecoder, "hpackDecoder");
|
this.hpackDecoder = requireNonNull(hpackDecoder, "hpackDecoder");
|
||||||
this.validateHeaders = validateHeaders;
|
this.validateHeaders = validateHeaders;
|
||||||
this.maxHeaderListSizeGoAway =
|
maxHeaderListSizeGoAway =
|
||||||
Http2CodecUtil.calculateMaxHeaderListSizeGoAway(hpackDecoder.getMaxHeaderListSize());
|
Http2CodecUtil.calculateMaxHeaderListSizeGoAway(hpackDecoder.getMaxHeaderListSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -101,7 +101,7 @@ public class DefaultHttp2HeadersDecoder implements Http2HeadersDecoder, Http2Hea
|
|||||||
goAwayMax, max);
|
goAwayMax, max);
|
||||||
}
|
}
|
||||||
hpackDecoder.setMaxHeaderListSize(max);
|
hpackDecoder.setMaxHeaderListSize(max);
|
||||||
this.maxHeaderListSizeGoAway = goAwayMax;
|
maxHeaderListSizeGoAway = goAwayMax;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -411,7 +411,7 @@ public class DefaultHttp2LocalFlowController implements Http2LocalFlowController
|
|||||||
|
|
||||||
window += delta;
|
window += delta;
|
||||||
processedWindow += delta;
|
processedWindow += delta;
|
||||||
lowerBound = Math.min(delta, 0);
|
lowerBound = min(delta, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -108,7 +108,7 @@ public class DefaultHttp2RemoteFlowController implements Http2RemoteFlowControll
|
|||||||
@Override
|
@Override
|
||||||
public void onStreamHalfClosed(Http2Stream stream) {
|
public void onStreamHalfClosed(Http2Stream stream) {
|
||||||
if (HALF_CLOSED_LOCAL == stream.state()) {
|
if (HALF_CLOSED_LOCAL == stream.state()) {
|
||||||
/**
|
/*
|
||||||
* When this method is called there should not be any
|
* When this method is called there should not be any
|
||||||
* pending frames left if the API is used correctly. However,
|
* pending frames left if the API is used correctly. However,
|
||||||
* it is possible that a erroneous application can sneak
|
* it is possible that a erroneous application can sneak
|
||||||
|
@ -79,7 +79,7 @@ public final class DefaultHttp2ResetFrame extends AbstractHttp2StreamFrame imple
|
|||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
int hash = super.hashCode();
|
int hash = super.hashCode();
|
||||||
hash = hash * 31 + (int) (errorCode ^ (errorCode >>> 32));
|
hash = hash * 31 + (int) (errorCode ^ errorCode >>> 32);
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -189,7 +189,7 @@ final class HpackDecoder {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Literal Header Field without Indexing / never Indexed
|
// Literal Header Field without Indexing / never Indexed
|
||||||
indexType = ((b & 0x10) == 0x10) ? IndexType.NEVER : IndexType.NONE;
|
indexType = (b & 0x10) == 0x10 ? IndexType.NEVER : IndexType.NONE;
|
||||||
index = b & 0x0F;
|
index = b & 0x0F;
|
||||||
switch (index) {
|
switch (index) {
|
||||||
case 0:
|
case 0:
|
||||||
@ -560,7 +560,7 @@ final class HpackDecoder {
|
|||||||
|
|
||||||
if (validate) {
|
if (validate) {
|
||||||
try {
|
try {
|
||||||
previousType = HpackDecoder.validate(streamId, name, previousType);
|
previousType = validate(streamId, name, previousType);
|
||||||
} catch (Http2Exception ex) {
|
} catch (Http2Exception ex) {
|
||||||
validationException = ex;
|
validationException = ex;
|
||||||
return;
|
return;
|
||||||
|
@ -245,14 +245,14 @@ final class HpackEncoder {
|
|||||||
*/
|
*/
|
||||||
private static void encodeInteger(ByteBuf out, int mask, int n, long i) {
|
private static void encodeInteger(ByteBuf out, int mask, int n, long i) {
|
||||||
assert n >= 0 && n <= 8 : "N: " + n;
|
assert n >= 0 && n <= 8 : "N: " + n;
|
||||||
int nbits = 0xFF >>> (8 - n);
|
int nbits = 0xFF >>> 8 - n;
|
||||||
if (i < nbits) {
|
if (i < nbits) {
|
||||||
out.writeByte((int) (mask | i));
|
out.writeByte((int) (mask | i));
|
||||||
} else {
|
} else {
|
||||||
out.writeByte(mask | nbits);
|
out.writeByte(mask | nbits);
|
||||||
long length = i - nbits;
|
long length = i - nbits;
|
||||||
for (; (length & ~0x7F) != 0; length >>>= 7) {
|
for (; (length & ~0x7F) != 0; length >>>= 7) {
|
||||||
out.writeByte((int) ((length & 0x7F) | 0x80));
|
out.writeByte((int) (length & 0x7F | 0x80));
|
||||||
}
|
}
|
||||||
out.writeByte((int) length);
|
out.writeByte((int) length);
|
||||||
}
|
}
|
||||||
|
@ -199,7 +199,7 @@ final class HpackStaticTable {
|
|||||||
/**
|
/**
|
||||||
* Returns the last position in the array that contains multiple
|
* Returns the last position in the array that contains multiple
|
||||||
* fields with the same name. Starting from this position, all
|
* fields with the same name. Starting from this position, all
|
||||||
* names are unique. Similary to {@link getIndexInsensitive} method
|
* names are unique. Similary to {@link #getIndexInsensitive(CharSequence, CharSequence)} method
|
||||||
* assumes all entries for a given header field are sequential
|
* assumes all entries for a given header field are sequential
|
||||||
*/
|
*/
|
||||||
private static int maxSameNameFieldIndex() {
|
private static int maxSameNameFieldIndex() {
|
||||||
|
@ -89,7 +89,7 @@ public interface Http2Connection {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when a {@code GOAWAY} was received from the remote endpoint. This event handler duplicates {@link
|
* Called when a {@code GOAWAY} was received from the remote endpoint. This event handler duplicates {@link
|
||||||
* Http2FrameListener#onGoAwayRead(io.netty.channel.ChannelHandlerContext, int, long, io.netty.buffer.ByteBuf)}
|
* Http2FrameListener#onGoAwayRead(io.netty.channel.ChannelHandlerContext, int, long, ByteBuf)}
|
||||||
* but is added here in order to simplify application logic for handling {@code GOAWAY} in a uniform way. An
|
* but is added here in order to simplify application logic for handling {@code GOAWAY} in a uniform way. An
|
||||||
* application should generally not handle both events, but if it does this method is called second, after
|
* application should generally not handle both events, but if it does this method is called second, after
|
||||||
* notifying the {@link Http2FrameListener}.
|
* notifying the {@link Http2FrameListener}.
|
||||||
|
@ -40,7 +40,7 @@ public enum Http2Error {
|
|||||||
private final long code;
|
private final long code;
|
||||||
private static final Http2Error[] INT_TO_ENUM_MAP;
|
private static final Http2Error[] INT_TO_ENUM_MAP;
|
||||||
static {
|
static {
|
||||||
Http2Error[] errors = Http2Error.values();
|
Http2Error[] errors = values();
|
||||||
Http2Error[] map = new Http2Error[errors.length];
|
Http2Error[] map = new Http2Error[errors.length];
|
||||||
for (Http2Error error : errors) {
|
for (Http2Error error : errors) {
|
||||||
map[(int) error.code()] = error;
|
map[(int) error.code()] = error;
|
||||||
|
@ -127,25 +127,25 @@ public class Http2Exception extends Exception {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Use if an error which can be isolated to a single stream has occurred. If the {@code id} is not
|
* Use if an error which can be isolated to a single stream has occurred. If the {@code id} is not
|
||||||
* {@link Http2CodecUtil#CONNECTION_STREAM_ID} then a {@link Http2Exception.StreamException} will be returned.
|
* {@link Http2CodecUtil#CONNECTION_STREAM_ID} then a {@link StreamException} will be returned.
|
||||||
* Otherwise the error is considered a connection error and a {@link Http2Exception} is returned.
|
* Otherwise the error is considered a connection error and a {@link Http2Exception} is returned.
|
||||||
* @param id The stream id for which the error is isolated to.
|
* @param id The stream id for which the error is isolated to.
|
||||||
* @param error The type of error as defined by the HTTP/2 specification.
|
* @param error The type of error as defined by the HTTP/2 specification.
|
||||||
* @param fmt String with the content and format for the additional debug data.
|
* @param fmt String with the content and format for the additional debug data.
|
||||||
* @param args Objects which fit into the format defined by {@code fmt}.
|
* @param args Objects which fit into the format defined by {@code fmt}.
|
||||||
* @return If the {@code id} is not
|
* @return If the {@code id} is not
|
||||||
* {@link Http2CodecUtil#CONNECTION_STREAM_ID} then a {@link Http2Exception.StreamException} will be returned.
|
* {@link Http2CodecUtil#CONNECTION_STREAM_ID} then a {@link StreamException} will be returned.
|
||||||
* Otherwise the error is considered a connection error and a {@link Http2Exception} is returned.
|
* Otherwise the error is considered a connection error and a {@link Http2Exception} is returned.
|
||||||
*/
|
*/
|
||||||
public static Http2Exception streamError(int id, Http2Error error, String fmt, Object... args) {
|
public static Http2Exception streamError(int id, Http2Error error, String fmt, Object... args) {
|
||||||
return CONNECTION_STREAM_ID == id ?
|
return CONNECTION_STREAM_ID == id ?
|
||||||
Http2Exception.connectionError(error, fmt, args) :
|
connectionError(error, fmt, args) :
|
||||||
new StreamException(id, error, String.format(fmt, args));
|
new StreamException(id, error, String.format(fmt, args));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use if an error which can be isolated to a single stream has occurred. If the {@code id} is not
|
* Use if an error which can be isolated to a single stream has occurred. If the {@code id} is not
|
||||||
* {@link Http2CodecUtil#CONNECTION_STREAM_ID} then a {@link Http2Exception.StreamException} will be returned.
|
* {@link Http2CodecUtil#CONNECTION_STREAM_ID} then a {@link StreamException} will be returned.
|
||||||
* Otherwise the error is considered a connection error and a {@link Http2Exception} is returned.
|
* Otherwise the error is considered a connection error and a {@link Http2Exception} is returned.
|
||||||
* @param id The stream id for which the error is isolated to.
|
* @param id The stream id for which the error is isolated to.
|
||||||
* @param error The type of error as defined by the HTTP/2 specification.
|
* @param error The type of error as defined by the HTTP/2 specification.
|
||||||
@ -153,20 +153,20 @@ public class Http2Exception extends Exception {
|
|||||||
* @param fmt String with the content and format for the additional debug data.
|
* @param fmt String with the content and format for the additional debug data.
|
||||||
* @param args Objects which fit into the format defined by {@code fmt}.
|
* @param args Objects which fit into the format defined by {@code fmt}.
|
||||||
* @return If the {@code id} is not
|
* @return If the {@code id} is not
|
||||||
* {@link Http2CodecUtil#CONNECTION_STREAM_ID} then a {@link Http2Exception.StreamException} will be returned.
|
* {@link Http2CodecUtil#CONNECTION_STREAM_ID} then a {@link StreamException} will be returned.
|
||||||
* Otherwise the error is considered a connection error and a {@link Http2Exception} is returned.
|
* Otherwise the error is considered a connection error and a {@link Http2Exception} is returned.
|
||||||
*/
|
*/
|
||||||
public static Http2Exception streamError(int id, Http2Error error, Throwable cause,
|
public static Http2Exception streamError(int id, Http2Error error, Throwable cause,
|
||||||
String fmt, Object... args) {
|
String fmt, Object... args) {
|
||||||
return CONNECTION_STREAM_ID == id ?
|
return CONNECTION_STREAM_ID == id ?
|
||||||
Http2Exception.connectionError(error, cause, fmt, args) :
|
connectionError(error, cause, fmt, args) :
|
||||||
new StreamException(id, error, String.format(fmt, args), cause);
|
new StreamException(id, error, String.format(fmt, args), cause);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A specific stream error resulting from failing to decode headers that exceeds the max header size list.
|
* A specific stream error resulting from failing to decode headers that exceeds the max header size list.
|
||||||
* If the {@code id} is not {@link Http2CodecUtil#CONNECTION_STREAM_ID} then a
|
* If the {@code id} is not {@link Http2CodecUtil#CONNECTION_STREAM_ID} then a
|
||||||
* {@link Http2Exception.StreamException} will be returned. Otherwise the error is considered a
|
* {@link StreamException} will be returned. Otherwise the error is considered a
|
||||||
* connection error and a {@link Http2Exception} is returned.
|
* connection error and a {@link Http2Exception} is returned.
|
||||||
* @param id The stream id for which the error is isolated to.
|
* @param id The stream id for which the error is isolated to.
|
||||||
* @param error The type of error as defined by the HTTP/2 specification.
|
* @param error The type of error as defined by the HTTP/2 specification.
|
||||||
@ -181,14 +181,14 @@ public class Http2Exception extends Exception {
|
|||||||
public static Http2Exception headerListSizeError(int id, Http2Error error, boolean onDecode,
|
public static Http2Exception headerListSizeError(int id, Http2Error error, boolean onDecode,
|
||||||
String fmt, Object... args) {
|
String fmt, Object... args) {
|
||||||
return CONNECTION_STREAM_ID == id ?
|
return CONNECTION_STREAM_ID == id ?
|
||||||
Http2Exception.connectionError(error, fmt, args) :
|
connectionError(error, fmt, args) :
|
||||||
new HeaderListSizeException(id, error, String.format(fmt, args), onDecode);
|
new HeaderListSizeException(id, error, String.format(fmt, args), onDecode);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if an exception is isolated to a single stream or the entire connection.
|
* Check if an exception is isolated to a single stream or the entire connection.
|
||||||
* @param e The exception to check.
|
* @param e The exception to check.
|
||||||
* @return {@code true} if {@code e} is an instance of {@link Http2Exception.StreamException}.
|
* @return {@code true} if {@code e} is an instance of {@link StreamException}.
|
||||||
* {@code false} otherwise.
|
* {@code false} otherwise.
|
||||||
*/
|
*/
|
||||||
public static boolean isStreamError(Http2Exception e) {
|
public static boolean isStreamError(Http2Exception e) {
|
||||||
|
@ -71,7 +71,7 @@ public interface Http2Headers extends Headers<CharSequence, CharSequence, Http2H
|
|||||||
private static final CharSequenceMap<PseudoHeaderName> PSEUDO_HEADERS = new CharSequenceMap<>();
|
private static final CharSequenceMap<PseudoHeaderName> PSEUDO_HEADERS = new CharSequenceMap<>();
|
||||||
|
|
||||||
static {
|
static {
|
||||||
for (PseudoHeaderName pseudoHeader : PseudoHeaderName.values()) {
|
for (PseudoHeaderName pseudoHeader : values()) {
|
||||||
PSEUDO_HEADERS.add(pseudoHeader.value(), pseudoHeader);
|
PSEUDO_HEADERS.add(pseudoHeader.value(), pseudoHeader);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,7 @@ public class Http2MultiplexCodecBuilder
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static ChannelHandler checkSharable(ChannelHandler handler) {
|
private static ChannelHandler checkSharable(ChannelHandler handler) {
|
||||||
if ((handler instanceof ChannelHandlerAdapter && !((ChannelHandlerAdapter) handler).isSharable()) &&
|
if (handler instanceof ChannelHandlerAdapter && !((ChannelHandlerAdapter) handler).isSharable() &&
|
||||||
!handler.getClass().isAnnotationPresent(ChannelHandler.Sharable.class)) {
|
!handler.getClass().isAnnotationPresent(ChannelHandler.Sharable.class)) {
|
||||||
throw new IllegalArgumentException("The handler must be Sharable");
|
throw new IllegalArgumentException("The handler must be Sharable");
|
||||||
}
|
}
|
||||||
@ -77,7 +77,7 @@ public class Http2MultiplexCodecBuilder
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Http2MultiplexCodecBuilder withUpgradeStreamHandler(ChannelHandler upgradeStreamHandler) {
|
public Http2MultiplexCodecBuilder withUpgradeStreamHandler(ChannelHandler upgradeStreamHandler) {
|
||||||
if (this.isServer()) {
|
if (isServer()) {
|
||||||
throw new IllegalArgumentException("Server codecs don't use an extra handler for the upgrade stream");
|
throw new IllegalArgumentException("Server codecs don't use an extra handler for the upgrade stream");
|
||||||
}
|
}
|
||||||
this.upgradeStreamHandler = upgradeStreamHandler;
|
this.upgradeStreamHandler = upgradeStreamHandler;
|
||||||
|
@ -64,7 +64,6 @@ public final class Http2StreamChannelBootstrap {
|
|||||||
* Allow to specify a {@link ChannelOption} which is used for the {@link Http2StreamChannel} instances once they got
|
* Allow to specify a {@link ChannelOption} which is used for the {@link Http2StreamChannel} instances once they got
|
||||||
* created. Use a value of {@code null} to remove a previous set {@link ChannelOption}.
|
* created. Use a value of {@code null} to remove a previous set {@link ChannelOption}.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public <T> Http2StreamChannelBootstrap option(ChannelOption<T> option, T value) {
|
public <T> Http2StreamChannelBootstrap option(ChannelOption<T> option, T value) {
|
||||||
requireNonNull(option, "option");
|
requireNonNull(option, "option");
|
||||||
|
|
||||||
@ -82,7 +81,6 @@ public final class Http2StreamChannelBootstrap {
|
|||||||
* Allow to specify an initial attribute of the newly created {@link Http2StreamChannel}. If the {@code value} is
|
* Allow to specify an initial attribute of the newly created {@link Http2StreamChannel}. If the {@code value} is
|
||||||
* {@code null}, the attribute of the specified {@code key} is removed.
|
* {@code null}, the attribute of the specified {@code key} is removed.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public <T> Http2StreamChannelBootstrap attr(AttributeKey<T> key, T value) {
|
public <T> Http2StreamChannelBootstrap attr(AttributeKey<T> key, T value) {
|
||||||
requireNonNull(key, "key");
|
requireNonNull(key, "key");
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
@ -113,7 +111,6 @@ public final class Http2StreamChannelBootstrap {
|
|||||||
* Open a new {@link Http2StreamChannel} to use and notifies the given {@link Promise}.
|
* Open a new {@link Http2StreamChannel} to use and notifies the given {@link Promise}.
|
||||||
* @return the {@link Future} that will be notified once the channel was opened successfully or it failed.
|
* @return the {@link Future} that will be notified once the channel was opened successfully or it failed.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
public Future<Http2StreamChannel> open(final Promise<Http2StreamChannel> promise) {
|
public Future<Http2StreamChannel> open(final Promise<Http2StreamChannel> promise) {
|
||||||
try {
|
try {
|
||||||
ChannelHandlerContext ctx = findCtx();
|
ChannelHandlerContext ctx = findCtx();
|
||||||
@ -136,9 +133,10 @@ public final class Http2StreamChannelBootstrap {
|
|||||||
return promise;
|
return promise;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
private ChannelHandlerContext findCtx() throws ClosedChannelException {
|
private ChannelHandlerContext findCtx() throws ClosedChannelException {
|
||||||
// First try to use cached context and if this not work lets try to lookup the context.
|
// First try to use cached context and if this not work lets try to lookup the context.
|
||||||
ChannelHandlerContext ctx = this.multiplexCtx;
|
ChannelHandlerContext ctx = multiplexCtx;
|
||||||
if (ctx != null && !ctx.isRemoved()) {
|
if (ctx != null && !ctx.isRemoved()) {
|
||||||
return ctx;
|
return ctx;
|
||||||
}
|
}
|
||||||
@ -156,7 +154,7 @@ public final class Http2StreamChannelBootstrap {
|
|||||||
throw new ClosedChannelException();
|
throw new ClosedChannelException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.multiplexCtx = ctx;
|
multiplexCtx = ctx;
|
||||||
return ctx;
|
return ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,7 +78,7 @@ public class Http2StreamFrameToHttpObjectCodec extends MessageToMessageCodec<Htt
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean acceptInboundMessage(Object msg) throws Exception {
|
public boolean acceptInboundMessage(Object msg) throws Exception {
|
||||||
return (msg instanceof Http2HeadersFrame) || (msg instanceof Http2DataFrame);
|
return msg instanceof Http2HeadersFrame || msg instanceof Http2DataFrame;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -443,7 +443,7 @@ public final class HttpConversionUtil {
|
|||||||
if (!isOriginForm(requestTargetUri) && !isAsteriskForm(requestTargetUri)) {
|
if (!isOriginForm(requestTargetUri) && !isAsteriskForm(requestTargetUri)) {
|
||||||
// Attempt to take from HOST header before taking from the request-line
|
// Attempt to take from HOST header before taking from the request-line
|
||||||
String host = inHeaders.getAsString(HttpHeaderNames.HOST);
|
String host = inHeaders.getAsString(HttpHeaderNames.HOST);
|
||||||
setHttp2Authority((host == null || host.isEmpty()) ? requestTargetUri.getAuthority() : host, out);
|
setHttp2Authority(host == null || host.isEmpty() ? requestTargetUri.getAuthority() : host, out);
|
||||||
}
|
}
|
||||||
} else if (in instanceof HttpResponse) {
|
} else if (in instanceof HttpResponse) {
|
||||||
HttpResponse response = (HttpResponse) in;
|
HttpResponse response = (HttpResponse) in;
|
||||||
|
@ -485,7 +485,7 @@ public final class ReadOnlyHttp2Headers implements Http2Headers {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int size() {
|
public int size() {
|
||||||
return (pseudoHeaders.length + otherHeaders.length) >>> 1;
|
return pseudoHeaders.length + otherHeaders.length >>> 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -126,7 +126,7 @@ public class StreamBufferingEncoder extends DecoratingHttp2ConnectionEncoder {
|
|||||||
|
|
||||||
public StreamBufferingEncoder(Http2ConnectionEncoder delegate, int initialMaxConcurrentStreams) {
|
public StreamBufferingEncoder(Http2ConnectionEncoder delegate, int initialMaxConcurrentStreams) {
|
||||||
super(delegate);
|
super(delegate);
|
||||||
this.maxConcurrentStreams = initialMaxConcurrentStreams;
|
maxConcurrentStreams = initialMaxConcurrentStreams;
|
||||||
connection().addListener(new Http2ConnectionAdapter() {
|
connection().addListener(new Http2ConnectionAdapter() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -159,7 +159,7 @@ public final class UniformStreamByteDistributor implements StreamByteDistributor
|
|||||||
// we gave the state a chance to write zero length frames. We wait until updateStreamableBytes is
|
// we gave the state a chance to write zero length frames. We wait until updateStreamableBytes is
|
||||||
// called again before this state is allowed to write.
|
// called again before this state is allowed to write.
|
||||||
windowNegative = windowSize < 0;
|
windowNegative = windowSize < 0;
|
||||||
if (hasFrame && (windowSize > 0 || (windowSize == 0 && !writing))) {
|
if (hasFrame && (windowSize > 0 || windowSize == 0 && !writing)) {
|
||||||
addToQueue();
|
addToQueue();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -233,7 +233,7 @@ public final class WeightedFairQueueByteDistributor implements StreamByteDistrib
|
|||||||
}
|
}
|
||||||
state.weight = weight;
|
state.weight = weight;
|
||||||
|
|
||||||
if (newParent != state.parent || (exclusive && newParent.children.size() != 1)) {
|
if (newParent != state.parent || exclusive && newParent.children.size() != 1) {
|
||||||
final List<ParentChangedEvent> events;
|
final List<ParentChangedEvent> events;
|
||||||
if (newParent.isDescendantOf(state)) {
|
if (newParent.isDescendantOf(state)) {
|
||||||
events = new ArrayList<>(2 + (exclusive ? newParent.children.size() : 0));
|
events = new ArrayList<>(2 + (exclusive ? newParent.children.size() : 0));
|
||||||
@ -320,7 +320,7 @@ public final class WeightedFairQueueByteDistributor implements StreamByteDistrib
|
|||||||
try {
|
try {
|
||||||
assert nextChildState == null || nextChildState.pseudoTimeToWrite >= childState.pseudoTimeToWrite :
|
assert nextChildState == null || nextChildState.pseudoTimeToWrite >= childState.pseudoTimeToWrite :
|
||||||
"nextChildState[" + nextChildState.streamId + "].pseudoTime(" + nextChildState.pseudoTimeToWrite +
|
"nextChildState[" + nextChildState.streamId + "].pseudoTime(" + nextChildState.pseudoTimeToWrite +
|
||||||
") < " + " childState[" + childState.streamId + "].pseudoTime(" + childState.pseudoTimeToWrite + ")";
|
") < " + " childState[" + childState.streamId + "].pseudoTime(" + childState.pseudoTimeToWrite + ')';
|
||||||
int nsent = distribute(nextChildState == null ? maxBytes :
|
int nsent = distribute(nextChildState == null ? maxBytes :
|
||||||
min(maxBytes, (int) min((nextChildState.pseudoTimeToWrite - childState.pseudoTimeToWrite) *
|
min(maxBytes, (int) min((nextChildState.pseudoTimeToWrite - childState.pseudoTimeToWrite) *
|
||||||
childState.weight / oldTotalQueuedWeights + allocationQuantum, MAX_VALUE)
|
childState.weight / oldTotalQueuedWeights + allocationQuantum, MAX_VALUE)
|
||||||
@ -396,9 +396,6 @@ public final class WeightedFairQueueByteDistributor implements StreamByteDistrib
|
|||||||
|
|
||||||
static final StateOnlyComparator INSTANCE = new StateOnlyComparator();
|
static final StateOnlyComparator INSTANCE = new StateOnlyComparator();
|
||||||
|
|
||||||
private StateOnlyComparator() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int compare(State o1, State o2) {
|
public int compare(State o1, State o2) {
|
||||||
// "priority only streams" (which have not been activated) are higher priority than streams used for data.
|
// "priority only streams" (which have not been activated) are higher priority than streams used for data.
|
||||||
@ -425,9 +422,6 @@ public final class WeightedFairQueueByteDistributor implements StreamByteDistrib
|
|||||||
|
|
||||||
static final StatePseudoTimeComparator INSTANCE = new StatePseudoTimeComparator();
|
static final StatePseudoTimeComparator INSTANCE = new StatePseudoTimeComparator();
|
||||||
|
|
||||||
private StatePseudoTimeComparator() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int compare(State o1, State o2) {
|
public int compare(State o1, State o2) {
|
||||||
return Long.compare(o1.pseudoTimeToWrite, o2.pseudoTimeToWrite);
|
return Long.compare(o1.pseudoTimeToWrite, o2.pseudoTimeToWrite);
|
||||||
@ -556,7 +550,7 @@ public final class WeightedFairQueueByteDistributor implements StreamByteDistrib
|
|||||||
do {
|
do {
|
||||||
// Redistribute the weight of child to its dependency proportionally.
|
// Redistribute the weight of child to its dependency proportionally.
|
||||||
State dependency = itr.next().value();
|
State dependency = itr.next().value();
|
||||||
dependency.weight = (short) Math.max(1, dependency.weight * child.weight / totalWeight);
|
dependency.weight = (short) max(1, dependency.weight * child.weight / totalWeight);
|
||||||
takeChild(itr, dependency, false, events);
|
takeChild(itr, dependency, false, events);
|
||||||
} while (itr.hasNext());
|
} while (itr.hasNext());
|
||||||
}
|
}
|
||||||
|
@ -468,6 +468,7 @@ public class DefaultHttp2ConnectionDecoderTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
public void headersReadForUnknownStreamShouldThrow() throws Exception {
|
public void headersReadForUnknownStreamShouldThrow() throws Exception {
|
||||||
when(connection.stream(STREAM_ID)).thenReturn(null);
|
when(connection.stream(STREAM_ID)).thenReturn(null);
|
||||||
assertThrows(Http2Exception.class, new Executable() {
|
assertThrows(Http2Exception.class, new Executable() {
|
||||||
@ -612,7 +613,7 @@ public class DefaultHttp2ConnectionDecoderTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test()
|
@Test
|
||||||
public void headersReadForPromisedStreamShouldCloseStream() throws Exception {
|
public void headersReadForPromisedStreamShouldCloseStream() throws Exception {
|
||||||
when(stream.state()).thenReturn(RESERVED_REMOTE);
|
when(stream.state()).thenReturn(RESERVED_REMOTE);
|
||||||
decode().onHeadersRead(ctx, STREAM_ID, EmptyHttp2Headers.INSTANCE, 0, true);
|
decode().onHeadersRead(ctx, STREAM_ID, EmptyHttp2Headers.INSTANCE, 0, true);
|
||||||
|
@ -107,19 +107,19 @@ public class DefaultHttp2ConnectionTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void removeAllStreamsWithJustOneLocalStream() throws InterruptedException, Http2Exception {
|
public void removeAllStreamsWithJustOneLocalStream() throws Exception {
|
||||||
client.local().createStream(3, false);
|
client.local().createStream(3, false);
|
||||||
testRemoveAllStreams();
|
testRemoveAllStreams();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void removeAllStreamsWithJustOneRemoveStream() throws InterruptedException, Http2Exception {
|
public void removeAllStreamsWithJustOneRemoveStream() throws Exception {
|
||||||
client.remote().createStream(2, false);
|
client.remote().createStream(2, false);
|
||||||
testRemoveAllStreams();
|
testRemoveAllStreams();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void removeAllStreamsWithManyActiveStreams() throws InterruptedException, Http2Exception {
|
public void removeAllStreamsWithManyActiveStreams() throws Exception {
|
||||||
Endpoint<Http2RemoteFlowController> remote = client.remote();
|
Endpoint<Http2RemoteFlowController> remote = client.remote();
|
||||||
Endpoint<Http2LocalFlowController> local = client.local();
|
Endpoint<Http2LocalFlowController> local = client.local();
|
||||||
for (int c = 3, s = 2; c < 5000; c += 2, s += 2) {
|
for (int c = 3, s = 2; c < 5000; c += 2, s += 2) {
|
||||||
@ -130,7 +130,7 @@ public class DefaultHttp2ConnectionTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void removeIndividualStreamsWhileCloseDoesNotNPE() throws InterruptedException, Http2Exception {
|
public void removeIndividualStreamsWhileCloseDoesNotNPE() throws Exception {
|
||||||
final Http2Stream streamA = client.local().createStream(3, false);
|
final Http2Stream streamA = client.local().createStream(3, false);
|
||||||
final Http2Stream streamB = client.remote().createStream(2, false);
|
final Http2Stream streamB = client.remote().createStream(2, false);
|
||||||
doAnswer((Answer<Void>) invocation -> {
|
doAnswer((Answer<Void>) invocation -> {
|
||||||
@ -147,7 +147,7 @@ public class DefaultHttp2ConnectionTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void removeAllStreamsWhileIteratingActiveStreams() throws InterruptedException, Http2Exception {
|
public void removeAllStreamsWhileIteratingActiveStreams() throws Exception {
|
||||||
final Endpoint<Http2RemoteFlowController> remote = client.remote();
|
final Endpoint<Http2RemoteFlowController> remote = client.remote();
|
||||||
final Endpoint<Http2LocalFlowController> local = client.local();
|
final Endpoint<Http2LocalFlowController> local = client.local();
|
||||||
for (int c = 3, s = 2; c < 5000; c += 2, s += 2) {
|
for (int c = 3, s = 2; c < 5000; c += 2, s += 2) {
|
||||||
@ -168,7 +168,7 @@ public class DefaultHttp2ConnectionTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void removeAllStreamsWhileIteratingActiveStreamsAndExceptionOccurs()
|
public void removeAllStreamsWhileIteratingActiveStreamsAndExceptionOccurs()
|
||||||
throws InterruptedException, Http2Exception {
|
throws Exception {
|
||||||
final Endpoint<Http2RemoteFlowController> remote = client.remote();
|
final Endpoint<Http2RemoteFlowController> remote = client.remote();
|
||||||
final Endpoint<Http2LocalFlowController> local = client.local();
|
final Endpoint<Http2LocalFlowController> local = client.local();
|
||||||
for (int c = 3, s = 2; c < 5000; c += 2, s += 2) {
|
for (int c = 3, s = 2; c < 5000; c += 2, s += 2) {
|
||||||
|
@ -158,7 +158,7 @@ public class DefaultHttp2FrameWriterTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test large headers that exceed {@link DefaultHttp2FrameWriter#maxFrameSize}
|
* Test large headers that exceed {@link DefaultHttp2FrameWriter#maxFrameSize()}
|
||||||
* the remaining headers will be sent in a CONTINUATION frame
|
* the remaining headers will be sent in a CONTINUATION frame
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
|
@ -185,7 +185,7 @@ public class DefaultHttp2HeadersTest {
|
|||||||
if (entry.getKey().length() == 0 || entry.getKey().charAt(0) != ':') {
|
if (entry.getKey().length() == 0 || entry.getKey().charAt(0) != ':') {
|
||||||
lastNonPseudoName = entry.getKey();
|
lastNonPseudoName = entry.getKey();
|
||||||
} else if (lastNonPseudoName != null) {
|
} else if (lastNonPseudoName != null) {
|
||||||
fail("All pseudo headers must be fist in iteration. Pseudo header " + entry.getKey() +
|
fail("All pseudo headers must be first in iteration. Pseudo header " + entry.getKey() +
|
||||||
" is after a non pseudo header " + lastNonPseudoName);
|
" is after a non pseudo header " + lastNonPseudoName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -98,7 +98,7 @@ public class HpackDynamicTableTest {
|
|||||||
table.add(entry2);
|
table.add(entry2);
|
||||||
assertEquals(2, table.length());
|
assertEquals(2, table.length());
|
||||||
assertEquals(size1 + size2, table.size());
|
assertEquals(size1 + size2, table.size());
|
||||||
table.setCapacity((size1 + size2) * 2); //larger capacity
|
table.setCapacity(((long) size1 + size2) * 2); //larger capacity
|
||||||
assertEquals(2, table.length());
|
assertEquals(2, table.length());
|
||||||
assertEquals(size1 + size2, table.size());
|
assertEquals(size1 + size2, table.size());
|
||||||
table.setCapacity(size2); //smaller capacity
|
table.setCapacity(size2); //smaller capacity
|
||||||
|
@ -249,8 +249,8 @@ public class Http2ConnectionHandlerTest {
|
|||||||
Http2ConnectionPrefaceAndSettingsFrameWrittenEvent.INSTANCE;
|
Http2ConnectionPrefaceAndSettingsFrameWrittenEvent.INSTANCE;
|
||||||
|
|
||||||
final AtomicBoolean verified = new AtomicBoolean(false);
|
final AtomicBoolean verified = new AtomicBoolean(false);
|
||||||
final Answer verifier = in -> {
|
final Answer<Object> verifier = in -> {
|
||||||
assertTrue(in.getArgument(0).equals(evt)); // sanity check...
|
assertEquals(in.getArgument(0), evt); // sanity check...
|
||||||
verify(ctx).write(eq(connectionPrefaceBuf()));
|
verify(ctx).write(eq(connectionPrefaceBuf()));
|
||||||
verify(encoder).writeSettings(eq(ctx), any(Http2Settings.class), any(ChannelPromise.class));
|
verify(encoder).writeSettings(eq(ctx), any(Http2Settings.class), any(ChannelPromise.class));
|
||||||
verified.set(true);
|
verified.set(true);
|
||||||
@ -492,7 +492,7 @@ public class Http2ConnectionHandlerTest {
|
|||||||
when(stream.isHeadersSent()).thenReturn(false);
|
when(stream.isHeadersSent()).thenReturn(false);
|
||||||
when(remote.lastStreamCreated()).thenReturn(STREAM_ID);
|
when(remote.lastStreamCreated()).thenReturn(STREAM_ID);
|
||||||
when(frameWriter.writeRstStream(eq(ctx), eq(STREAM_ID),
|
when(frameWriter.writeRstStream(eq(ctx), eq(STREAM_ID),
|
||||||
eq(Http2Error.PROTOCOL_ERROR.code()), eq(promise))).thenReturn(future);
|
eq(PROTOCOL_ERROR.code()), eq(promise))).thenReturn(future);
|
||||||
handler.exceptionCaught(ctx, e);
|
handler.exceptionCaught(ctx, e);
|
||||||
|
|
||||||
verify(remote).createStream(STREAM_ID, true);
|
verify(remote).createStream(STREAM_ID, true);
|
||||||
|
@ -44,7 +44,7 @@ final class Http2FrameInboundWriter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Http2FrameInboundWriter(EmbeddedChannel channel, Http2FrameWriter writer) {
|
Http2FrameInboundWriter(EmbeddedChannel channel, Http2FrameWriter writer) {
|
||||||
this.ctx = new WriteInboundChannelHandlerContext(channel);
|
ctx = new WriteInboundChannelHandlerContext(channel);
|
||||||
this.writer = writer;
|
this.writer = writer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,7 +24,6 @@ import io.netty.channel.ChannelFutureListener;
|
|||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
import io.netty.channel.ChannelPromise;
|
import io.netty.channel.ChannelPromise;
|
||||||
import io.netty.channel.DefaultChannelPromise;
|
import io.netty.channel.DefaultChannelPromise;
|
||||||
import io.netty.handler.codec.ByteToMessageDecoder;
|
|
||||||
import io.netty.util.AsciiString;
|
import io.netty.util.AsciiString;
|
||||||
import io.netty.util.ReferenceCountUtil;
|
import io.netty.util.ReferenceCountUtil;
|
||||||
import io.netty.util.concurrent.Future;
|
import io.netty.util.concurrent.Future;
|
||||||
@ -143,170 +142,6 @@ public final class Http2TestUtil {
|
|||||||
private Http2TestUtil() {
|
private Http2TestUtil() {
|
||||||
}
|
}
|
||||||
|
|
||||||
static class FrameAdapter extends ByteToMessageDecoder {
|
|
||||||
private final Http2Connection connection;
|
|
||||||
private final Http2FrameListener listener;
|
|
||||||
private final DefaultHttp2FrameReader reader;
|
|
||||||
private final CountDownLatch latch;
|
|
||||||
|
|
||||||
FrameAdapter(Http2FrameListener listener, CountDownLatch latch) {
|
|
||||||
this(null, listener, latch);
|
|
||||||
}
|
|
||||||
|
|
||||||
FrameAdapter(Http2Connection connection, Http2FrameListener listener, CountDownLatch latch) {
|
|
||||||
this(connection, new DefaultHttp2FrameReader(false), listener, latch);
|
|
||||||
}
|
|
||||||
|
|
||||||
FrameAdapter(Http2Connection connection, DefaultHttp2FrameReader reader, Http2FrameListener listener,
|
|
||||||
CountDownLatch latch) {
|
|
||||||
this.connection = connection;
|
|
||||||
this.listener = listener;
|
|
||||||
this.reader = reader;
|
|
||||||
this.latch = latch;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Http2Stream getOrCreateStream(int streamId, boolean halfClosed) throws Http2Exception {
|
|
||||||
return getOrCreateStream(connection, streamId, halfClosed);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Http2Stream getOrCreateStream(Http2Connection connection, int streamId, boolean halfClosed)
|
|
||||||
throws Http2Exception {
|
|
||||||
if (connection != null) {
|
|
||||||
Http2Stream stream = connection.stream(streamId);
|
|
||||||
if (stream == null) {
|
|
||||||
if (connection.isServer() && streamId % 2 == 0 || !connection.isServer() && streamId % 2 != 0) {
|
|
||||||
stream = connection.local().createStream(streamId, halfClosed);
|
|
||||||
} else {
|
|
||||||
stream = connection.remote().createStream(streamId, halfClosed);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return stream;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void closeStream(Http2Stream stream) {
|
|
||||||
closeStream(stream, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void closeStream(Http2Stream stream, boolean dataRead) {
|
|
||||||
if (stream != null) {
|
|
||||||
stream.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception {
|
|
||||||
reader.readFrame(ctx, in, new Http2FrameListener() {
|
|
||||||
@Override
|
|
||||||
public int onDataRead(ChannelHandlerContext ctx, int streamId, ByteBuf data, int padding,
|
|
||||||
boolean endOfStream) throws Http2Exception {
|
|
||||||
Http2Stream stream = getOrCreateStream(streamId, endOfStream);
|
|
||||||
int processed = listener.onDataRead(ctx, streamId, data, padding, endOfStream);
|
|
||||||
if (endOfStream) {
|
|
||||||
closeStream(stream, true);
|
|
||||||
}
|
|
||||||
latch.countDown();
|
|
||||||
return processed;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onHeadersRead(ChannelHandlerContext ctx, int streamId, Http2Headers headers, int padding,
|
|
||||||
boolean endStream) throws Http2Exception {
|
|
||||||
Http2Stream stream = getOrCreateStream(streamId, endStream);
|
|
||||||
listener.onHeadersRead(ctx, streamId, headers, padding, endStream);
|
|
||||||
if (endStream) {
|
|
||||||
closeStream(stream);
|
|
||||||
}
|
|
||||||
latch.countDown();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onHeadersRead(ChannelHandlerContext ctx, int streamId, Http2Headers headers,
|
|
||||||
int streamDependency, short weight, boolean exclusive, int padding, boolean endStream)
|
|
||||||
throws Http2Exception {
|
|
||||||
Http2Stream stream = getOrCreateStream(streamId, endStream);
|
|
||||||
listener.onHeadersRead(ctx, streamId, headers, streamDependency, weight, exclusive, padding,
|
|
||||||
endStream);
|
|
||||||
if (endStream) {
|
|
||||||
closeStream(stream);
|
|
||||||
}
|
|
||||||
latch.countDown();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onPriorityRead(ChannelHandlerContext ctx, int streamId, int streamDependency, short weight,
|
|
||||||
boolean exclusive) throws Http2Exception {
|
|
||||||
listener.onPriorityRead(ctx, streamId, streamDependency, weight, exclusive);
|
|
||||||
latch.countDown();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onRstStreamRead(ChannelHandlerContext ctx, int streamId, long errorCode)
|
|
||||||
throws Http2Exception {
|
|
||||||
Http2Stream stream = getOrCreateStream(streamId, false);
|
|
||||||
listener.onRstStreamRead(ctx, streamId, errorCode);
|
|
||||||
closeStream(stream);
|
|
||||||
latch.countDown();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onSettingsAckRead(ChannelHandlerContext ctx) throws Http2Exception {
|
|
||||||
listener.onSettingsAckRead(ctx);
|
|
||||||
latch.countDown();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onSettingsRead(ChannelHandlerContext ctx, Http2Settings settings) throws Http2Exception {
|
|
||||||
listener.onSettingsRead(ctx, settings);
|
|
||||||
latch.countDown();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onPingRead(ChannelHandlerContext ctx, long data) throws Http2Exception {
|
|
||||||
listener.onPingRead(ctx, data);
|
|
||||||
latch.countDown();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onPingAckRead(ChannelHandlerContext ctx, long data) throws Http2Exception {
|
|
||||||
listener.onPingAckRead(ctx, data);
|
|
||||||
latch.countDown();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onPushPromiseRead(ChannelHandlerContext ctx, int streamId, int promisedStreamId,
|
|
||||||
Http2Headers headers, int padding) throws Http2Exception {
|
|
||||||
getOrCreateStream(promisedStreamId, false);
|
|
||||||
listener.onPushPromiseRead(ctx, streamId, promisedStreamId, headers, padding);
|
|
||||||
latch.countDown();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onGoAwayRead(ChannelHandlerContext ctx, int lastStreamId, long errorCode, ByteBuf debugData)
|
|
||||||
throws Http2Exception {
|
|
||||||
listener.onGoAwayRead(ctx, lastStreamId, errorCode, debugData);
|
|
||||||
latch.countDown();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onWindowUpdateRead(ChannelHandlerContext ctx, int streamId, int windowSizeIncrement)
|
|
||||||
throws Http2Exception {
|
|
||||||
getOrCreateStream(streamId, false);
|
|
||||||
listener.onWindowUpdateRead(ctx, streamId, windowSizeIncrement);
|
|
||||||
latch.countDown();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onUnknownFrame(ChannelHandlerContext ctx, byte frameType, int streamId, Http2Flags flags,
|
|
||||||
ByteBuf payload) throws Http2Exception {
|
|
||||||
listener.onUnknownFrame(ctx, frameType, streamId, flags, payload);
|
|
||||||
latch.countDown();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A decorator around a {@link Http2FrameListener} that counts down the latch so that we can await the completion of
|
* A decorator around a {@link Http2FrameListener} that counts down the latch so that we can await the completion of
|
||||||
* the request.
|
* the request.
|
||||||
@ -319,10 +154,6 @@ public final class Http2TestUtil {
|
|||||||
private final CountDownLatch trailersLatch;
|
private final CountDownLatch trailersLatch;
|
||||||
private final CountDownLatch goAwayLatch;
|
private final CountDownLatch goAwayLatch;
|
||||||
|
|
||||||
FrameCountDown(Http2FrameListener listener, CountDownLatch settingsAckLatch, CountDownLatch messageLatch) {
|
|
||||||
this(listener, settingsAckLatch, messageLatch, null, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
FrameCountDown(Http2FrameListener listener, CountDownLatch settingsAckLatch, CountDownLatch messageLatch,
|
FrameCountDown(Http2FrameListener listener, CountDownLatch settingsAckLatch, CountDownLatch messageLatch,
|
||||||
CountDownLatch dataLatch, CountDownLatch trailersLatch) {
|
CountDownLatch dataLatch, CountDownLatch trailersLatch) {
|
||||||
this(listener, settingsAckLatch, messageLatch, dataLatch, trailersLatch, messageLatch);
|
this(listener, settingsAckLatch, messageLatch, dataLatch, trailersLatch, messageLatch);
|
||||||
|
@ -145,7 +145,7 @@ public class HttpConversionUtilTest {
|
|||||||
@Test
|
@Test
|
||||||
public void stripTEHeadersAccountsForOWS() {
|
public void stripTEHeadersAccountsForOWS() {
|
||||||
HttpHeaders inHeaders = new DefaultHttpHeaders();
|
HttpHeaders inHeaders = new DefaultHttpHeaders();
|
||||||
inHeaders.add(TE, " " + TRAILERS + " ");
|
inHeaders.add(TE, " " + TRAILERS + ' ');
|
||||||
Http2Headers out = new DefaultHttp2Headers();
|
Http2Headers out = new DefaultHttp2Headers();
|
||||||
HttpConversionUtil.toHttp2Headers(inHeaders, out);
|
HttpConversionUtil.toHttp2Headers(inHeaders, out);
|
||||||
assertSame(TRAILERS, out.get(TE));
|
assertSame(TRAILERS, out.get(TE));
|
||||||
|
@ -244,11 +244,10 @@ public class ReadOnlyHttp2HeadersTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testIteratorMultipleValues() {
|
public void testIteratorMultipleValues() {
|
||||||
Http2Headers headers = ReadOnlyHttp2Headers.serverHeaders(false, new AsciiString("200"), new AsciiString[] {
|
Http2Headers headers = ReadOnlyHttp2Headers.serverHeaders(false, new AsciiString("200"),
|
||||||
new AsciiString("name2"), new AsciiString("value1"),
|
new AsciiString("name2"), new AsciiString("value1"),
|
||||||
new AsciiString("name1"), new AsciiString("value2"),
|
new AsciiString("name1"), new AsciiString("value2"),
|
||||||
new AsciiString("name2"), new AsciiString("value3")
|
new AsciiString("name2"), new AsciiString("value3"));
|
||||||
});
|
|
||||||
Iterator<CharSequence> itr = headers.valueIterator("name2");
|
Iterator<CharSequence> itr = headers.valueIterator("name2");
|
||||||
assertTrue(itr.hasNext());
|
assertTrue(itr.hasNext());
|
||||||
assertTrue(AsciiString.contentEqualsIgnoreCase("value1", itr.next()));
|
assertTrue(AsciiString.contentEqualsIgnoreCase("value1", itr.next()));
|
||||||
|
Loading…
Reference in New Issue
Block a user