diff --git a/codec-http2/src/main/java/io/netty/handler/codec/http2/DefaultHttp2PriorityFrame.java b/codec-http2/src/main/java/io/netty/handler/codec/http2/DefaultHttp2PriorityFrame.java index e131936e24..5e073d56af 100644 --- a/codec-http2/src/main/java/io/netty/handler/codec/http2/DefaultHttp2PriorityFrame.java +++ b/codec-http2/src/main/java/io/netty/handler/codec/http2/DefaultHttp2PriorityFrame.java @@ -21,12 +21,11 @@ import io.netty.util.internal.UnstableApi; * Default implementation of {@linkplain Http2PriorityFrame} */ @UnstableApi -public final class DefaultHttp2PriorityFrame implements Http2PriorityFrame { +public final class DefaultHttp2PriorityFrame extends AbstractHttp2StreamFrame implements Http2PriorityFrame { private final int streamDependency; private final short weight; private final boolean exclusive; - private Http2FrameStream http2FrameStream; public DefaultHttp2PriorityFrame(int streamDependency, short weight, boolean exclusive) { this.streamDependency = streamDependency; @@ -50,25 +49,40 @@ public final class DefaultHttp2PriorityFrame implements Http2PriorityFrame { } @Override - public Http2PriorityFrame stream(Http2FrameStream stream) { - http2FrameStream = stream; + public DefaultHttp2PriorityFrame stream(Http2FrameStream stream) { + super.stream(stream); return this; } - @Override - public Http2FrameStream stream() { - return http2FrameStream; - } - @Override public String name() { return "PRIORITY_FRAME"; } + @Override + public boolean equals(Object o) { + if (!(o instanceof DefaultHttp2PriorityFrame)) { + return false; + } + DefaultHttp2PriorityFrame other = (DefaultHttp2PriorityFrame) o; + boolean same = super.equals(other); + return same && streamDependency == other.streamDependency + && weight == other.weight && exclusive == other.exclusive; + } + + @Override + public int hashCode() { + int hash = super.hashCode(); + hash = hash * 31 + streamDependency; + hash = hash * 31 + weight; + hash = hash * 31 + (exclusive ? 1 : 0); + return hash; + } + @Override public String toString() { return "DefaultHttp2PriorityFrame(" + - "stream=" + http2FrameStream + + "stream=" + stream() + ", streamDependency=" + streamDependency + ", weight=" + weight + ", exclusive=" + exclusive + diff --git a/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2FrameCodec.java b/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2FrameCodec.java index 9f08858448..dc9e8218f3 100644 --- a/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2FrameCodec.java +++ b/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2FrameCodec.java @@ -657,6 +657,12 @@ public class Http2FrameCodec extends Http2ConnectionHandler { @Override public void onPriorityRead(ChannelHandlerContext ctx, int streamId, int streamDependency, short weight, boolean exclusive) { + + Http2Stream stream = connection().stream(streamId); + if (stream == null) { + // The stream was not opened yet, let's just ignore this for now. + return; + } onHttp2Frame(ctx, new DefaultHttp2PriorityFrame(streamDependency, weight, exclusive) .stream(requireStream(streamId))); } diff --git a/codec-http2/src/test/java/io/netty/handler/codec/http2/Http2FrameCodecTest.java b/codec-http2/src/test/java/io/netty/handler/codec/http2/Http2FrameCodecTest.java index b40486babc..b17fe8c92f 100644 --- a/codec-http2/src/test/java/io/netty/handler/codec/http2/Http2FrameCodecTest.java +++ b/codec-http2/src/test/java/io/netty/handler/codec/http2/Http2FrameCodecTest.java @@ -896,6 +896,40 @@ public class Http2FrameCodecTest { channel.pipeline().fireUserEventTriggered(upgradeEvent); } + @Test + public void priorityForNonExistingStream() { + writeHeaderAndAssert(1); + + frameInboundWriter.writeInboundPriority(3, 1, (short) 31, true); + } + + @Test + public void priorityForExistingStream() { + writeHeaderAndAssert(1); + writeHeaderAndAssert(3); + frameInboundWriter.writeInboundPriority(3, 1, (short) 31, true); + + assertInboundStreamFrame(3, new DefaultHttp2PriorityFrame(1, (short) 31, true)); + } + + private void writeHeaderAndAssert(int streamId) { + frameInboundWriter.writeInboundHeaders(streamId, request, 31, false); + + Http2Stream stream = frameCodec.connection().stream(streamId); + assertNotNull(stream); + assertEquals(State.OPEN, stream.state()); + + assertInboundStreamFrame(streamId, new DefaultHttp2HeadersFrame(request, false, 31)); + } + + private void assertInboundStreamFrame(int expectedId, Http2StreamFrame streamFrame) { + Http2StreamFrame inboundFrame = inboundHandler.readInbound(); + Http2FrameStream stream2 = inboundFrame.stream(); + assertNotNull(stream2); + assertEquals(expectedId, stream2.id()); + assertEquals(inboundFrame, streamFrame.stream(stream2)); + } + private ChannelHandlerContext eqFrameCodecCtx() { return eq(frameCodec.ctx); }