Migrate codec-http2 to junit5 (#11422)
Motivation: We should update to use junit5 in all modules. Modifications: Adjust codec-http2 tests to use junit5 Result: Part of https://github.com/netty/netty/issues/10757
This commit is contained in:
parent
d8ad931488
commit
8c73dbe9bd
@ -36,17 +36,17 @@ import io.netty.handler.codec.http2.CleartextHttp2ServerUpgradeHandler.PriorKnow
|
|||||||
import io.netty.handler.codec.http2.Http2Stream.State;
|
import io.netty.handler.codec.http2.Http2Stream.State;
|
||||||
import io.netty.util.CharsetUtil;
|
import io.netty.util.CharsetUtil;
|
||||||
import io.netty.util.ReferenceCountUtil;
|
import io.netty.util.ReferenceCountUtil;
|
||||||
import org.junit.After;
|
import org.junit.jupiter.api.AfterEach;
|
||||||
import org.junit.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
import static org.junit.Assert.assertNotNull;
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
import static org.junit.Assert.assertNull;
|
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
import static org.mockito.Mockito.any;
|
import static org.mockito.Mockito.any;
|
||||||
import static org.mockito.Mockito.eq;
|
import static org.mockito.Mockito.eq;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
@ -92,7 +92,7 @@ public class CleartextHttp2ServerUpgradeHandlerTest {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@After
|
@AfterEach
|
||||||
public void tearDown() throws Exception {
|
public void tearDown() throws Exception {
|
||||||
channel.finishAndReleaseAll();
|
channel.finishAndReleaseAll();
|
||||||
}
|
}
|
||||||
|
@ -35,9 +35,9 @@ import io.netty.util.AsciiString;
|
|||||||
import io.netty.util.CharsetUtil;
|
import io.netty.util.CharsetUtil;
|
||||||
import io.netty.util.NetUtil;
|
import io.netty.util.NetUtil;
|
||||||
import io.netty.util.concurrent.Future;
|
import io.netty.util.concurrent.Future;
|
||||||
import org.junit.After;
|
import org.junit.jupiter.api.AfterEach;
|
||||||
import org.junit.Before;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.MockitoAnnotations;
|
import org.mockito.MockitoAnnotations;
|
||||||
import org.mockito.invocation.InvocationOnMock;
|
import org.mockito.invocation.InvocationOnMock;
|
||||||
@ -53,8 +53,8 @@ import static io.netty.handler.codec.http2.Http2CodecUtil.DEFAULT_PRIORITY_WEIGH
|
|||||||
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.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
import static org.mockito.Mockito.any;
|
import static org.mockito.Mockito.any;
|
||||||
import static org.mockito.Mockito.anyBoolean;
|
import static org.mockito.Mockito.anyBoolean;
|
||||||
import static org.mockito.Mockito.anyInt;
|
import static org.mockito.Mockito.anyInt;
|
||||||
@ -88,7 +88,7 @@ public class DataCompressionHttp2Test {
|
|||||||
private Http2ConnectionHandler clientHandler;
|
private Http2ConnectionHandler clientHandler;
|
||||||
private ByteArrayOutputStream serverOut;
|
private ByteArrayOutputStream serverOut;
|
||||||
|
|
||||||
@Before
|
@BeforeEach
|
||||||
public void setup() throws InterruptedException, Http2Exception {
|
public void setup() throws InterruptedException, Http2Exception {
|
||||||
MockitoAnnotations.initMocks(this);
|
MockitoAnnotations.initMocks(this);
|
||||||
doAnswer(new Answer<Void>() {
|
doAnswer(new Answer<Void>() {
|
||||||
@ -113,12 +113,12 @@ public class DataCompressionHttp2Test {
|
|||||||
anyInt(), anyShort(), anyBoolean(), anyInt(), anyBoolean());
|
anyInt(), anyShort(), anyBoolean(), anyInt(), anyBoolean());
|
||||||
}
|
}
|
||||||
|
|
||||||
@After
|
@AfterEach
|
||||||
public void cleanup() throws IOException {
|
public void cleanup() throws IOException {
|
||||||
serverOut.close();
|
serverOut.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@After
|
@AfterEach
|
||||||
public void teardown() throws InterruptedException {
|
public void teardown() throws InterruptedException {
|
||||||
if (clientChannel != null) {
|
if (clientChannel != null) {
|
||||||
clientChannel.close().sync();
|
clientChannel.close().sync();
|
||||||
|
@ -14,21 +14,30 @@
|
|||||||
*/
|
*/
|
||||||
package io.netty.handler.codec.http2;
|
package io.netty.handler.codec.http2;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.function.Executable;
|
||||||
|
|
||||||
import static org.mockito.Mockito.eq;
|
import static org.mockito.Mockito.eq;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
import static org.mockito.Mockito.times;
|
import static org.mockito.Mockito.times;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
|
|
||||||
public class DecoratingHttp2ConnectionEncoderTest {
|
public class DecoratingHttp2ConnectionEncoderTest {
|
||||||
|
|
||||||
@Test(expected = IllegalStateException.class)
|
@Test
|
||||||
public void testConsumeReceivedSettingsThrows() {
|
public void testConsumeReceivedSettingsThrows() {
|
||||||
Http2ConnectionEncoder encoder = mock(Http2ConnectionEncoder.class);
|
Http2ConnectionEncoder encoder = mock(Http2ConnectionEncoder.class);
|
||||||
DecoratingHttp2ConnectionEncoder decoratingHttp2ConnectionEncoder =
|
final DecoratingHttp2ConnectionEncoder decoratingHttp2ConnectionEncoder =
|
||||||
new DecoratingHttp2ConnectionEncoder(encoder);
|
new DecoratingHttp2ConnectionEncoder(encoder);
|
||||||
|
assertThrows(IllegalStateException.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() {
|
||||||
decoratingHttp2ConnectionEncoder.consumeReceivedSettings(Http2Settings.defaultSettings());
|
decoratingHttp2ConnectionEncoder.consumeReceivedSettings(Http2Settings.defaultSettings());
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testConsumeReceivedSettingsDelegate() {
|
public void testConsumeReceivedSettingsDelegate() {
|
||||||
|
@ -24,8 +24,9 @@ import io.netty.channel.DefaultChannelPromise;
|
|||||||
import io.netty.handler.codec.http.HttpHeaderNames;
|
import io.netty.handler.codec.http.HttpHeaderNames;
|
||||||
import io.netty.handler.codec.http.HttpResponseStatus;
|
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||||
import junit.framework.AssertionFailedError;
|
import junit.framework.AssertionFailedError;
|
||||||
import org.junit.Before;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.function.Executable;
|
||||||
import org.mockito.ArgumentCaptor;
|
import org.mockito.ArgumentCaptor;
|
||||||
import org.mockito.ArgumentMatchers;
|
import org.mockito.ArgumentMatchers;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
@ -51,9 +52,9 @@ import static org.hamcrest.MatcherAssert.assertThat;
|
|||||||
import static org.hamcrest.Matchers.instanceOf;
|
import static org.hamcrest.Matchers.instanceOf;
|
||||||
import static org.hamcrest.Matchers.not;
|
import static org.hamcrest.Matchers.not;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
import static org.junit.Assert.fail;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
import static org.mockito.Mockito.any;
|
import static org.mockito.Mockito.any;
|
||||||
import static org.mockito.Mockito.anyBoolean;
|
import static org.mockito.Mockito.anyBoolean;
|
||||||
import static org.mockito.Mockito.anyInt;
|
import static org.mockito.Mockito.anyInt;
|
||||||
@ -127,7 +128,7 @@ public class DefaultHttp2ConnectionDecoderTest {
|
|||||||
@Mock
|
@Mock
|
||||||
private Http2LifecycleManager lifecycleManager;
|
private Http2LifecycleManager lifecycleManager;
|
||||||
|
|
||||||
@Before
|
@BeforeEach
|
||||||
public void setup() throws Exception {
|
public void setup() throws Exception {
|
||||||
MockitoAnnotations.initMocks(this);
|
MockitoAnnotations.initMocks(this);
|
||||||
|
|
||||||
@ -273,16 +274,19 @@ public class DefaultHttp2ConnectionDecoderTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = Http2Exception.StreamException.class)
|
@Test
|
||||||
public void dataReadForUnknownStreamShouldApplyFlowControlAndFail() throws Exception {
|
public void dataReadForUnknownStreamShouldApplyFlowControlAndFail() throws Exception {
|
||||||
when(connection.streamMayHaveExisted(STREAM_ID)).thenReturn(true);
|
when(connection.streamMayHaveExisted(STREAM_ID)).thenReturn(true);
|
||||||
when(connection.stream(STREAM_ID)).thenReturn(null);
|
when(connection.stream(STREAM_ID)).thenReturn(null);
|
||||||
final ByteBuf data = dummyData();
|
final ByteBuf data = dummyData();
|
||||||
int padding = 10;
|
final int padding = 10;
|
||||||
int processedBytes = data.readableBytes() + padding;
|
int processedBytes = data.readableBytes() + padding;
|
||||||
try {
|
assertThrows(Http2Exception.StreamException.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
decode().onDataRead(ctx, STREAM_ID, data, padding, true);
|
decode().onDataRead(ctx, STREAM_ID, data, padding, true);
|
||||||
} finally {
|
}
|
||||||
|
});
|
||||||
try {
|
try {
|
||||||
verify(localFlow)
|
verify(localFlow)
|
||||||
.receiveFlowControlledFrame(eq((Http2Stream) null), eq(data), eq(padding), eq(true));
|
.receiveFlowControlledFrame(eq((Http2Stream) null), eq(data), eq(padding), eq(true));
|
||||||
@ -294,21 +298,25 @@ public class DefaultHttp2ConnectionDecoderTest {
|
|||||||
data.release();
|
data.release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = Http2Exception.class)
|
@Test
|
||||||
public void dataReadForUnknownStreamThatCouldntExistFail() throws Exception {
|
public void dataReadForUnknownStreamThatCouldntExistFail() throws Exception {
|
||||||
when(connection.streamMayHaveExisted(STREAM_ID)).thenReturn(false);
|
when(connection.streamMayHaveExisted(STREAM_ID)).thenReturn(false);
|
||||||
when(connection.stream(STREAM_ID)).thenReturn(null);
|
when(connection.stream(STREAM_ID)).thenReturn(null);
|
||||||
final ByteBuf data = dummyData();
|
final ByteBuf data = dummyData();
|
||||||
int padding = 10;
|
final int padding = 10;
|
||||||
int processedBytes = data.readableBytes() + padding;
|
int processedBytes = data.readableBytes() + padding;
|
||||||
|
assertThrows(Http2Exception.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
try {
|
try {
|
||||||
decode().onDataRead(ctx, STREAM_ID, data, padding, true);
|
decode().onDataRead(ctx, STREAM_ID, data, padding, true);
|
||||||
} catch (Http2Exception ex) {
|
} catch (Http2Exception ex) {
|
||||||
assertThat(ex, not(instanceOf(Http2Exception.StreamException.class)));
|
assertThat(ex, not(instanceOf(Http2Exception.StreamException.class)));
|
||||||
throw ex;
|
throw ex;
|
||||||
} finally {
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
try {
|
try {
|
||||||
verify(localFlow)
|
verify(localFlow)
|
||||||
.receiveFlowControlledFrame(eq((Http2Stream) null), eq(data), eq(padding), eq(true));
|
.receiveFlowControlledFrame(eq((Http2Stream) null), eq(data), eq(padding), eq(true));
|
||||||
@ -320,19 +328,20 @@ public class DefaultHttp2ConnectionDecoderTest {
|
|||||||
data.release();
|
data.release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void dataReadForUnknownStreamShouldApplyFlowControl() throws Exception {
|
public void dataReadForUnknownStreamShouldApplyFlowControl() throws Exception {
|
||||||
when(connection.stream(STREAM_ID)).thenReturn(null);
|
when(connection.stream(STREAM_ID)).thenReturn(null);
|
||||||
final ByteBuf data = dummyData();
|
final ByteBuf data = dummyData();
|
||||||
int padding = 10;
|
final int padding = 10;
|
||||||
int processedBytes = data.readableBytes() + padding;
|
int processedBytes = data.readableBytes() + padding;
|
||||||
try {
|
try {
|
||||||
try {
|
assertThrows(Http2Exception.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
decode().onDataRead(ctx, STREAM_ID, data, padding, true);
|
decode().onDataRead(ctx, STREAM_ID, data, padding, true);
|
||||||
fail();
|
}
|
||||||
} catch (Http2Exception e) {
|
});
|
||||||
verify(localFlow)
|
verify(localFlow)
|
||||||
.receiveFlowControlledFrame(eq((Http2Stream) null), eq(data), eq(padding), eq(true));
|
.receiveFlowControlledFrame(eq((Http2Stream) null), eq(data), eq(padding), eq(true));
|
||||||
verify(localFlow).consumeBytes(eq((Http2Stream) null), eq(processedBytes));
|
verify(localFlow).consumeBytes(eq((Http2Stream) null), eq(processedBytes));
|
||||||
@ -341,7 +350,6 @@ public class DefaultHttp2ConnectionDecoderTest {
|
|||||||
|
|
||||||
// Verify that the event was absorbed and not propagated to the observer.
|
// Verify that the event was absorbed and not propagated to the observer.
|
||||||
verify(listener, never()).onDataRead(eq(ctx), anyInt(), any(ByteBuf.class), anyInt(), anyBoolean());
|
verify(listener, never()).onDataRead(eq(ctx), anyInt(), any(ByteBuf.class), anyInt(), anyBoolean());
|
||||||
}
|
|
||||||
} finally {
|
} finally {
|
||||||
data.release();
|
data.release();
|
||||||
}
|
}
|
||||||
@ -366,16 +374,18 @@ public class DefaultHttp2ConnectionDecoderTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = Http2Exception.class)
|
@Test
|
||||||
public void dataReadForStreamInInvalidStateShouldThrow() throws Exception {
|
public void dataReadForStreamInInvalidStateShouldThrow() throws Exception {
|
||||||
// Throw an exception when checking stream state.
|
// Throw an exception when checking stream state.
|
||||||
when(stream.state()).thenReturn(Http2Stream.State.CLOSED);
|
when(stream.state()).thenReturn(Http2Stream.State.CLOSED);
|
||||||
final ByteBuf data = dummyData();
|
final ByteBuf data = dummyData();
|
||||||
try {
|
assertThrows(Http2Exception.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
decode().onDataRead(ctx, STREAM_ID, data, 10, true);
|
decode().onDataRead(ctx, STREAM_ID, data, 10, true);
|
||||||
} finally {
|
|
||||||
data.release();
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
data.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -467,9 +477,12 @@ public class DefaultHttp2ConnectionDecoderTest {
|
|||||||
}
|
}
|
||||||
}).when(listener).onDataRead(eq(ctx), eq(STREAM_ID), any(ByteBuf.class), eq(10), eq(true));
|
}).when(listener).onDataRead(eq(ctx), eq(STREAM_ID), any(ByteBuf.class), eq(10), eq(true));
|
||||||
try {
|
try {
|
||||||
|
assertThrows(RuntimeException.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
decode().onDataRead(ctx, STREAM_ID, data, padding, true);
|
decode().onDataRead(ctx, STREAM_ID, data, padding, true);
|
||||||
fail("Expected exception");
|
}
|
||||||
} catch (RuntimeException cause) {
|
});
|
||||||
verify(localFlow)
|
verify(localFlow)
|
||||||
.receiveFlowControlledFrame(eq(stream), eq(data), eq(padding), eq(true));
|
.receiveFlowControlledFrame(eq(stream), eq(data), eq(padding), eq(true));
|
||||||
verify(listener).onDataRead(eq(ctx), eq(STREAM_ID), eq(data), eq(padding), eq(true));
|
verify(listener).onDataRead(eq(ctx), eq(STREAM_ID), eq(data), eq(padding), eq(true));
|
||||||
@ -479,11 +492,15 @@ public class DefaultHttp2ConnectionDecoderTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = Http2Exception.class)
|
|
||||||
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() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
decode().onHeadersRead(ctx, STREAM_ID, EmptyHttp2Headers.INSTANCE, 0, false);
|
decode().onHeadersRead(ctx, STREAM_ID, EmptyHttp2Headers.INSTANCE, 0, false);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void headersReadForStreamThatAlreadySentResetShouldBeIgnored() throws Exception {
|
public void headersReadForStreamThatAlreadySentResetShouldBeIgnored() throws Exception {
|
||||||
@ -541,29 +558,39 @@ public class DefaultHttp2ConnectionDecoderTest {
|
|||||||
eq(DEFAULT_PRIORITY_WEIGHT), eq(false), eq(0), eq(false));
|
eq(DEFAULT_PRIORITY_WEIGHT), eq(false), eq(0), eq(false));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = Http2Exception.class)
|
@Test
|
||||||
public void trailersDoNotEndStreamThrows() throws Exception {
|
public void trailersDoNotEndStreamThrows() throws Exception {
|
||||||
decode().onHeadersRead(ctx, STREAM_ID, EmptyHttp2Headers.INSTANCE, 0, false);
|
decode().onHeadersRead(ctx, STREAM_ID, EmptyHttp2Headers.INSTANCE, 0, false);
|
||||||
// Trailers must end the stream!
|
// Trailers must end the stream!
|
||||||
|
assertThrows(Http2Exception.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
decode().onHeadersRead(ctx, STREAM_ID, EmptyHttp2Headers.INSTANCE, 0, false);
|
decode().onHeadersRead(ctx, STREAM_ID, EmptyHttp2Headers.INSTANCE, 0, false);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Test(expected = Http2Exception.class)
|
@Test
|
||||||
public void tooManyHeadersEOSThrows() throws Exception {
|
public void tooManyHeadersEOSThrows() throws Exception {
|
||||||
tooManyHeaderThrows(true);
|
tooManyHeaderThrows(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = Http2Exception.class)
|
@Test
|
||||||
public void tooManyHeadersNoEOSThrows() throws Exception {
|
public void tooManyHeadersNoEOSThrows() throws Exception {
|
||||||
tooManyHeaderThrows(false);
|
tooManyHeaderThrows(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void tooManyHeaderThrows(boolean eos) throws Exception {
|
private void tooManyHeaderThrows(final boolean eos) throws Exception {
|
||||||
decode().onHeadersRead(ctx, STREAM_ID, EmptyHttp2Headers.INSTANCE, 0, false);
|
decode().onHeadersRead(ctx, STREAM_ID, EmptyHttp2Headers.INSTANCE, 0, false);
|
||||||
decode().onHeadersRead(ctx, STREAM_ID, EmptyHttp2Headers.INSTANCE, 0, true);
|
decode().onHeadersRead(ctx, STREAM_ID, EmptyHttp2Headers.INSTANCE, 0, true);
|
||||||
// We already received the trailers!
|
// We already received the trailers!
|
||||||
|
assertThrows(Http2Exception.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
decode().onHeadersRead(ctx, STREAM_ID, EmptyHttp2Headers.INSTANCE, 0, eos);
|
decode().onHeadersRead(ctx, STREAM_ID, EmptyHttp2Headers.INSTANCE, 0, eos);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private static Http2Headers informationalHeaders() {
|
private static Http2Headers informationalHeaders() {
|
||||||
Http2Headers headers = new DefaultHttp2Headers();
|
Http2Headers headers = new DefaultHttp2Headers();
|
||||||
@ -581,22 +608,32 @@ public class DefaultHttp2ConnectionDecoderTest {
|
|||||||
infoHeadersAndTrailersAllowed(true, 10);
|
infoHeadersAndTrailersAllowed(true, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = Http2Exception.class)
|
@Test
|
||||||
public void infoHeadersAndTrailersNoEOSThrows() throws Exception {
|
public void infoHeadersAndTrailersNoEOSThrows() throws Exception {
|
||||||
infoHeadersAndTrailersAllowed(false, 1);
|
infoHeadersAndTrailersAllowed(false, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = Http2Exception.class)
|
@Test
|
||||||
public void multipleInfoHeadersAndTrailersNoEOSThrows() throws Exception {
|
public void multipleInfoHeadersAndTrailersNoEOSThrows() throws Exception {
|
||||||
infoHeadersAndTrailersAllowed(false, 10);
|
infoHeadersAndTrailersAllowed(false, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void infoHeadersAndTrailersAllowed(boolean eos, int infoHeaderCount) throws Exception {
|
private void infoHeadersAndTrailersAllowed(final boolean eos, int infoHeaderCount)
|
||||||
|
throws Exception {
|
||||||
for (int i = 0; i < infoHeaderCount; ++i) {
|
for (int i = 0; i < infoHeaderCount; ++i) {
|
||||||
decode().onHeadersRead(ctx, STREAM_ID, informationalHeaders(), 0, false);
|
decode().onHeadersRead(ctx, STREAM_ID, informationalHeaders(), 0, false);
|
||||||
}
|
}
|
||||||
decode().onHeadersRead(ctx, STREAM_ID, EmptyHttp2Headers.INSTANCE, 0, false);
|
decode().onHeadersRead(ctx, STREAM_ID, EmptyHttp2Headers.INSTANCE, 0, false);
|
||||||
|
if (eos) {
|
||||||
decode().onHeadersRead(ctx, STREAM_ID, EmptyHttp2Headers.INSTANCE, 0, eos);
|
decode().onHeadersRead(ctx, STREAM_ID, EmptyHttp2Headers.INSTANCE, 0, eos);
|
||||||
|
} else {
|
||||||
|
assertThrows(Http2Exception.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
|
decode().onHeadersRead(ctx, STREAM_ID, EmptyHttp2Headers.INSTANCE, 0, eos);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test()
|
@Test()
|
||||||
@ -636,11 +673,16 @@ public class DefaultHttp2ConnectionDecoderTest {
|
|||||||
verify(listener).onPushPromiseRead(eq(ctx), anyInt(), anyInt(), any(Http2Headers.class), anyInt());
|
verify(listener).onPushPromiseRead(eq(ctx), anyInt(), anyInt(), any(Http2Headers.class), anyInt());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = Http2Exception.class)
|
@Test
|
||||||
public void pushPromiseReadForUnknownStreamShouldThrow() throws Exception {
|
public void pushPromiseReadForUnknownStreamShouldThrow() throws Exception {
|
||||||
when(connection.stream(STREAM_ID)).thenReturn(null);
|
when(connection.stream(STREAM_ID)).thenReturn(null);
|
||||||
|
assertThrows(Http2Exception.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
decode().onPushPromiseRead(ctx, STREAM_ID, PUSH_STREAM_ID, EmptyHttp2Headers.INSTANCE, 0);
|
decode().onPushPromiseRead(ctx, STREAM_ID, PUSH_STREAM_ID, EmptyHttp2Headers.INSTANCE, 0);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void pushPromiseReadShouldSucceed() throws Exception {
|
public void pushPromiseReadShouldSucceed() throws Exception {
|
||||||
@ -693,12 +735,17 @@ public class DefaultHttp2ConnectionDecoderTest {
|
|||||||
verify(listener).onWindowUpdateRead(eq(ctx), anyInt(), anyInt());
|
verify(listener).onWindowUpdateRead(eq(ctx), anyInt(), anyInt());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = Http2Exception.class)
|
@Test
|
||||||
public void windowUpdateReadForUnknownStreamShouldThrow() throws Exception {
|
public void windowUpdateReadForUnknownStreamShouldThrow() throws Exception {
|
||||||
when(connection.streamMayHaveExisted(STREAM_ID)).thenReturn(false);
|
when(connection.streamMayHaveExisted(STREAM_ID)).thenReturn(false);
|
||||||
when(connection.stream(STREAM_ID)).thenReturn(null);
|
when(connection.stream(STREAM_ID)).thenReturn(null);
|
||||||
|
assertThrows(Http2Exception.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
decode().onWindowUpdateRead(ctx, STREAM_ID, 10);
|
decode().onWindowUpdateRead(ctx, STREAM_ID, 10);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void windowUpdateReadForUnknownStreamShouldBeIgnored() throws Exception {
|
public void windowUpdateReadForUnknownStreamShouldBeIgnored() throws Exception {
|
||||||
@ -723,12 +770,17 @@ public class DefaultHttp2ConnectionDecoderTest {
|
|||||||
verify(listener).onRstStreamRead(eq(ctx), anyInt(), anyLong());
|
verify(listener).onRstStreamRead(eq(ctx), anyInt(), anyLong());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = Http2Exception.class)
|
@Test
|
||||||
public void rstStreamReadForUnknownStreamShouldThrow() throws Exception {
|
public void rstStreamReadForUnknownStreamShouldThrow() throws Exception {
|
||||||
when(connection.streamMayHaveExisted(STREAM_ID)).thenReturn(false);
|
when(connection.streamMayHaveExisted(STREAM_ID)).thenReturn(false);
|
||||||
when(connection.stream(STREAM_ID)).thenReturn(null);
|
when(connection.stream(STREAM_ID)).thenReturn(null);
|
||||||
|
assertThrows(Http2Exception.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
decode().onRstStreamRead(ctx, STREAM_ID, PROTOCOL_ERROR.code());
|
decode().onRstStreamRead(ctx, STREAM_ID, PROTOCOL_ERROR.code());
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void rstStreamReadForUnknownStreamShouldBeIgnored() throws Exception {
|
public void rstStreamReadForUnknownStreamShouldBeIgnored() throws Exception {
|
||||||
@ -745,11 +797,15 @@ public class DefaultHttp2ConnectionDecoderTest {
|
|||||||
verify(listener).onRstStreamRead(eq(ctx), eq(STREAM_ID), eq(PROTOCOL_ERROR.code()));
|
verify(listener).onRstStreamRead(eq(ctx), eq(STREAM_ID), eq(PROTOCOL_ERROR.code()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = Http2Exception.class)
|
@Test
|
||||||
public void rstStreamOnIdleStreamShouldThrow() throws Exception {
|
public void rstStreamOnIdleStreamShouldThrow() throws Exception {
|
||||||
when(stream.state()).thenReturn(IDLE);
|
when(stream.state()).thenReturn(IDLE);
|
||||||
|
assertThrows(Http2Exception.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
decode().onRstStreamRead(ctx, STREAM_ID, PROTOCOL_ERROR.code());
|
decode().onRstStreamRead(ctx, STREAM_ID, PROTOCOL_ERROR.code());
|
||||||
verify(lifecycleManager).closeStream(eq(stream), eq(future));
|
}
|
||||||
|
});
|
||||||
verify(listener, never()).onRstStreamRead(any(ChannelHandlerContext.class), anyInt(), anyLong());
|
verify(listener, never()).onRstStreamRead(any(ChannelHandlerContext.class), anyInt(), anyLong());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -792,31 +848,46 @@ public class DefaultHttp2ConnectionDecoderTest {
|
|||||||
verify(listener).onGoAwayRead(eq(ctx), eq(1), eq(2L), eq(EMPTY_BUFFER));
|
verify(listener).onGoAwayRead(eq(ctx), eq(1), eq(2L), eq(EMPTY_BUFFER));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = Http2Exception.StreamException.class)
|
@Test
|
||||||
public void dataContentLengthMissmatch() throws Exception {
|
public void dataContentLengthMissmatch() throws Exception {
|
||||||
dataContentLengthInvalid(false);
|
dataContentLengthInvalid(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = Http2Exception.StreamException.class)
|
@Test
|
||||||
public void dataContentLengthInvalid() throws Exception {
|
public void dataContentLengthInvalid() throws Exception {
|
||||||
dataContentLengthInvalid(true);
|
dataContentLengthInvalid(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void dataContentLengthInvalid(boolean negative) throws Exception {
|
private void dataContentLengthInvalid(boolean negative) throws Exception {
|
||||||
final ByteBuf data = dummyData();
|
final ByteBuf data = dummyData();
|
||||||
int padding = 10;
|
final int padding = 10;
|
||||||
int processedBytes = data.readableBytes() + padding;
|
int processedBytes = data.readableBytes() + padding;
|
||||||
mockFlowControl(processedBytes);
|
mockFlowControl(processedBytes);
|
||||||
try {
|
try {
|
||||||
|
if (negative) {
|
||||||
|
assertThrows(Http2Exception.StreamException.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
decode().onHeadersRead(ctx, STREAM_ID, new DefaultHttp2Headers()
|
decode().onHeadersRead(ctx, STREAM_ID, new DefaultHttp2Headers()
|
||||||
.setLong(HttpHeaderNames.CONTENT_LENGTH, negative ? -1L : 1L), padding, false);
|
.setLong(HttpHeaderNames.CONTENT_LENGTH, -1L), padding, false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
decode().onHeadersRead(ctx, STREAM_ID, new DefaultHttp2Headers()
|
||||||
|
.setLong(HttpHeaderNames.CONTENT_LENGTH, 1L), padding, false);
|
||||||
|
assertThrows(Http2Exception.StreamException.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
decode().onDataRead(ctx, STREAM_ID, data, padding, true);
|
decode().onDataRead(ctx, STREAM_ID, data, padding, true);
|
||||||
|
}
|
||||||
|
});
|
||||||
verify(localFlow).receiveFlowControlledFrame(eq(stream), eq(data), eq(padding), eq(true));
|
verify(localFlow).receiveFlowControlledFrame(eq(stream), eq(data), eq(padding), eq(true));
|
||||||
verify(localFlow).consumeBytes(eq(stream), eq(processedBytes));
|
verify(localFlow).consumeBytes(eq(stream), eq(processedBytes));
|
||||||
|
|
||||||
verify(listener, times(1)).onHeadersRead(eq(ctx), anyInt(),
|
verify(listener, times(1)).onHeadersRead(eq(ctx), anyInt(),
|
||||||
any(Http2Headers.class), eq(0), eq(DEFAULT_PRIORITY_WEIGHT), eq(false),
|
any(Http2Headers.class), eq(0), eq(DEFAULT_PRIORITY_WEIGHT), eq(false),
|
||||||
eq(padding), eq(false));
|
eq(padding), eq(false));
|
||||||
|
}
|
||||||
// Verify that the event was absorbed and not propagated to the observer.
|
// Verify that the event was absorbed and not propagated to the observer.
|
||||||
verify(listener, never()).onDataRead(eq(ctx), anyInt(), any(ByteBuf.class), anyInt(), anyBoolean());
|
verify(listener, never()).onDataRead(eq(ctx), anyInt(), any(ByteBuf.class), anyInt(), anyBoolean());
|
||||||
} finally {
|
} finally {
|
||||||
@ -824,42 +895,53 @@ public class DefaultHttp2ConnectionDecoderTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = Http2Exception.StreamException.class)
|
@Test
|
||||||
public void headersContentLengthPositiveSign() throws Exception {
|
public void headersContentLengthPositiveSign() throws Exception {
|
||||||
headersContentLengthSign("+1");
|
headersContentLengthSign("+1");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = Http2Exception.StreamException.class)
|
@Test
|
||||||
public void headersContentLengthNegativeSign() throws Exception {
|
public void headersContentLengthNegativeSign() throws Exception {
|
||||||
headersContentLengthSign("-1");
|
headersContentLengthSign("-1");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void headersContentLengthSign(String length) throws Exception {
|
private void headersContentLengthSign(final String length) throws Exception {
|
||||||
int padding = 10;
|
final int padding = 10;
|
||||||
when(connection.isServer()).thenReturn(true);
|
when(connection.isServer()).thenReturn(true);
|
||||||
|
|
||||||
|
assertThrows(Http2Exception.StreamException.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
decode().onHeadersRead(ctx, STREAM_ID, new DefaultHttp2Headers()
|
decode().onHeadersRead(ctx, STREAM_ID, new DefaultHttp2Headers()
|
||||||
.set(HttpHeaderNames.CONTENT_LENGTH, length), padding, false);
|
.set(HttpHeaderNames.CONTENT_LENGTH, length), padding, false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Verify that the event was absorbed and not propagated to the observer.
|
// Verify that the event was absorbed and not propagated to the observer.
|
||||||
verify(listener, never()).onHeadersRead(eq(ctx), anyInt(),
|
verify(listener, never()).onHeadersRead(eq(ctx), anyInt(),
|
||||||
any(Http2Headers.class), anyInt(), anyShort(), anyBoolean(), anyInt(), anyBoolean());
|
any(Http2Headers.class), anyInt(), anyShort(), anyBoolean(), anyInt(), anyBoolean());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = Http2Exception.StreamException.class)
|
@Test
|
||||||
public void headersContentLengthMissmatch() throws Exception {
|
public void headersContentLengthMissmatch() throws Exception {
|
||||||
headersContentLength(false);
|
headersContentLength(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = Http2Exception.StreamException.class)
|
@Test
|
||||||
public void headersContentLengthInvalid() throws Exception {
|
public void headersContentLengthInvalid() throws Exception {
|
||||||
headersContentLength(true);
|
headersContentLength(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void headersContentLength(boolean negative) throws Exception {
|
private void headersContentLength(final boolean negative) throws Exception {
|
||||||
int padding = 10;
|
final int padding = 10;
|
||||||
when(connection.isServer()).thenReturn(true);
|
when(connection.isServer()).thenReturn(true);
|
||||||
|
assertThrows(Http2Exception.StreamException.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
decode().onHeadersRead(ctx, STREAM_ID, new DefaultHttp2Headers()
|
decode().onHeadersRead(ctx, STREAM_ID, new DefaultHttp2Headers()
|
||||||
.setLong(HttpHeaderNames.CONTENT_LENGTH, negative ? -1L : 1L), padding, true);
|
.setLong(HttpHeaderNames.CONTENT_LENGTH, negative ? -1L : 1L), padding, true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Verify that the event was absorbed and not propagated to the observer.
|
// Verify that the event was absorbed and not propagated to the observer.
|
||||||
verify(listener, never()).onHeadersRead(eq(ctx), anyInt(),
|
verify(listener, never()).onHeadersRead(eq(ctx), anyInt(),
|
||||||
@ -871,15 +953,15 @@ public class DefaultHttp2ConnectionDecoderTest {
|
|||||||
multipleHeadersContentLength(true);
|
multipleHeadersContentLength(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = Http2Exception.StreamException.class)
|
@Test
|
||||||
public void multipleHeadersContentLengthDifferent() throws Exception {
|
public void multipleHeadersContentLengthDifferent() throws Exception {
|
||||||
multipleHeadersContentLength(false);
|
multipleHeadersContentLength(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void multipleHeadersContentLength(boolean same) throws Exception {
|
private void multipleHeadersContentLength(boolean same) throws Exception {
|
||||||
int padding = 10;
|
final int padding = 10;
|
||||||
when(connection.isServer()).thenReturn(true);
|
when(connection.isServer()).thenReturn(true);
|
||||||
Http2Headers headers = new DefaultHttp2Headers();
|
final Http2Headers headers = new DefaultHttp2Headers();
|
||||||
if (same) {
|
if (same) {
|
||||||
headers.addLong(HttpHeaderNames.CONTENT_LENGTH, 0);
|
headers.addLong(HttpHeaderNames.CONTENT_LENGTH, 0);
|
||||||
headers.addLong(HttpHeaderNames.CONTENT_LENGTH, 0);
|
headers.addLong(HttpHeaderNames.CONTENT_LENGTH, 0);
|
||||||
@ -888,13 +970,19 @@ public class DefaultHttp2ConnectionDecoderTest {
|
|||||||
headers.addLong(HttpHeaderNames.CONTENT_LENGTH, 1);
|
headers.addLong(HttpHeaderNames.CONTENT_LENGTH, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
decode().onHeadersRead(ctx, STREAM_ID, headers, padding, true);
|
|
||||||
|
|
||||||
if (same) {
|
if (same) {
|
||||||
|
decode().onHeadersRead(ctx, STREAM_ID, headers, padding, true);
|
||||||
verify(listener, times(1)).onHeadersRead(eq(ctx), anyInt(),
|
verify(listener, times(1)).onHeadersRead(eq(ctx), anyInt(),
|
||||||
any(Http2Headers.class), anyInt(), anyShort(), anyBoolean(), anyInt(), anyBoolean());
|
any(Http2Headers.class), anyInt(), anyShort(), anyBoolean(), anyInt(), anyBoolean());
|
||||||
assertEquals(1, headers.getAll(HttpHeaderNames.CONTENT_LENGTH).size());
|
assertEquals(1, headers.getAll(HttpHeaderNames.CONTENT_LENGTH).size());
|
||||||
} else {
|
} else {
|
||||||
|
assertThrows(Http2Exception.StreamException.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
|
decode().onHeadersRead(ctx, STREAM_ID, headers, padding, true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Verify that the event was absorbed and not propagated to the observer.
|
// Verify that the event was absorbed and not propagated to the observer.
|
||||||
verify(listener, never()).onHeadersRead(eq(ctx), anyInt(),
|
verify(listener, never()).onHeadersRead(eq(ctx), anyInt(),
|
||||||
any(Http2Headers.class), anyInt(), anyShort(), anyBoolean(), anyInt(), anyBoolean());
|
any(Http2Headers.class), anyInt(), anyShort(), anyBoolean(), anyInt(), anyBoolean());
|
||||||
|
@ -31,8 +31,8 @@ import io.netty.handler.codec.http.HttpResponseStatus;
|
|||||||
import io.netty.handler.codec.http2.Http2RemoteFlowController.FlowControlled;
|
import io.netty.handler.codec.http2.Http2RemoteFlowController.FlowControlled;
|
||||||
import io.netty.util.concurrent.ImmediateEventExecutor;
|
import io.netty.util.concurrent.ImmediateEventExecutor;
|
||||||
import junit.framework.AssertionFailedError;
|
import junit.framework.AssertionFailedError;
|
||||||
import org.junit.Before;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.mockito.ArgumentCaptor;
|
import org.mockito.ArgumentCaptor;
|
||||||
import org.mockito.InOrder;
|
import org.mockito.InOrder;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
@ -53,12 +53,12 @@ import static io.netty.handler.codec.http2.Http2TestUtil.newVoidPromise;
|
|||||||
import static io.netty.util.CharsetUtil.UTF_8;
|
import static io.netty.util.CharsetUtil.UTF_8;
|
||||||
import static org.hamcrest.MatcherAssert.assertThat;
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
import static org.hamcrest.CoreMatchers.instanceOf;
|
import static org.hamcrest.CoreMatchers.instanceOf;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
import static org.junit.Assert.assertNull;
|
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||||
import static org.junit.Assert.assertSame;
|
import static org.junit.jupiter.api.Assertions.assertSame;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
import static org.junit.Assert.fail;
|
import static org.junit.jupiter.api.Assertions.fail;
|
||||||
import static org.mockito.Mockito.any;
|
import static org.mockito.Mockito.any;
|
||||||
import static org.mockito.Mockito.anyBoolean;
|
import static org.mockito.Mockito.anyBoolean;
|
||||||
import static org.mockito.Mockito.anyInt;
|
import static org.mockito.Mockito.anyInt;
|
||||||
@ -116,7 +116,7 @@ public class DefaultHttp2ConnectionEncoderTest {
|
|||||||
private List<Integer> writtenPadding;
|
private List<Integer> writtenPadding;
|
||||||
private boolean streamClosed;
|
private boolean streamClosed;
|
||||||
|
|
||||||
@Before
|
@BeforeEach
|
||||||
public void setup() throws Exception {
|
public void setup() throws Exception {
|
||||||
MockitoAnnotations.initMocks(this);
|
MockitoAnnotations.initMocks(this);
|
||||||
|
|
||||||
|
@ -23,12 +23,11 @@ import io.netty.handler.codec.http2.Http2Stream.State;
|
|||||||
import io.netty.util.concurrent.Future;
|
import io.netty.util.concurrent.Future;
|
||||||
import io.netty.util.concurrent.FutureListener;
|
import io.netty.util.concurrent.FutureListener;
|
||||||
import io.netty.util.concurrent.Promise;
|
import io.netty.util.concurrent.Promise;
|
||||||
import org.junit.AfterClass;
|
import org.junit.jupiter.api.AfterAll;
|
||||||
import org.junit.Before;
|
import org.junit.jupiter.api.BeforeAll;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.Rule;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.Test;
|
import org.junit.jupiter.api.function.Executable;
|
||||||
import org.junit.rules.ExpectedException;
|
|
||||||
import org.mockito.ArgumentMatchers;
|
import org.mockito.ArgumentMatchers;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.MockitoAnnotations;
|
import org.mockito.MockitoAnnotations;
|
||||||
@ -39,11 +38,12 @@ import java.util.concurrent.CountDownLatch;
|
|||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import static java.lang.Integer.MAX_VALUE;
|
import static java.lang.Integer.MAX_VALUE;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.Assert.assertNotNull;
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
import static org.junit.Assert.assertNull;
|
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
import static org.junit.Assert.fail;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
import static org.junit.jupiter.api.Assertions.fail;
|
||||||
import static org.mockito.Mockito.any;
|
import static org.mockito.Mockito.any;
|
||||||
import static org.mockito.Mockito.anyInt;
|
import static org.mockito.Mockito.anyInt;
|
||||||
import static org.mockito.Mockito.anyLong;
|
import static org.mockito.Mockito.anyLong;
|
||||||
@ -56,8 +56,6 @@ import static org.mockito.Mockito.verify;
|
|||||||
* Tests for {@link DefaultHttp2Connection}.
|
* Tests for {@link DefaultHttp2Connection}.
|
||||||
*/
|
*/
|
||||||
public class DefaultHttp2ConnectionTest {
|
public class DefaultHttp2ConnectionTest {
|
||||||
@Rule
|
|
||||||
public ExpectedException thrown = ExpectedException.none();
|
|
||||||
|
|
||||||
private DefaultHttp2Connection server;
|
private DefaultHttp2Connection server;
|
||||||
private DefaultHttp2Connection client;
|
private DefaultHttp2Connection client;
|
||||||
@ -69,17 +67,17 @@ public class DefaultHttp2ConnectionTest {
|
|||||||
@Mock
|
@Mock
|
||||||
private Http2Connection.Listener clientListener2;
|
private Http2Connection.Listener clientListener2;
|
||||||
|
|
||||||
@BeforeClass
|
@BeforeAll
|
||||||
public static void beforeClass() {
|
public static void beforeClass() {
|
||||||
group = new DefaultEventLoopGroup(2);
|
group = new DefaultEventLoopGroup(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@AfterClass
|
@AfterAll
|
||||||
public static void afterClass() {
|
public static void afterClass() {
|
||||||
group.shutdownGracefully();
|
group.shutdownGracefully();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Before
|
@BeforeEach
|
||||||
public void setup() {
|
public void setup() {
|
||||||
MockitoAnnotations.initMocks(this);
|
MockitoAnnotations.initMocks(this);
|
||||||
|
|
||||||
@ -350,22 +348,22 @@ public class DefaultHttp2ConnectionTest {
|
|||||||
incrementAndGetStreamShouldSucceed(client.local());
|
incrementAndGetStreamShouldSucceed(client.local());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = Http2NoMoreStreamIdsException.class)
|
@Test
|
||||||
public void serverRemoteIncrementAndGetStreamShouldRespectOverflow() throws Http2Exception {
|
public void serverRemoteIncrementAndGetStreamShouldRespectOverflow() throws Http2Exception {
|
||||||
incrementAndGetStreamShouldRespectOverflow(server.remote(), MAX_VALUE);
|
incrementAndGetStreamShouldRespectOverflow(server.remote(), MAX_VALUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = Http2NoMoreStreamIdsException.class)
|
@Test
|
||||||
public void serverLocalIncrementAndGetStreamShouldRespectOverflow() throws Http2Exception {
|
public void serverLocalIncrementAndGetStreamShouldRespectOverflow() throws Http2Exception {
|
||||||
incrementAndGetStreamShouldRespectOverflow(server.local(), MAX_VALUE - 1);
|
incrementAndGetStreamShouldRespectOverflow(server.local(), MAX_VALUE - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = Http2NoMoreStreamIdsException.class)
|
@Test
|
||||||
public void clientRemoteIncrementAndGetStreamShouldRespectOverflow() throws Http2Exception {
|
public void clientRemoteIncrementAndGetStreamShouldRespectOverflow() throws Http2Exception {
|
||||||
incrementAndGetStreamShouldRespectOverflow(client.remote(), MAX_VALUE - 1);
|
incrementAndGetStreamShouldRespectOverflow(client.remote(), MAX_VALUE - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = Http2NoMoreStreamIdsException.class)
|
@Test
|
||||||
public void clientLocalIncrementAndGetStreamShouldRespectOverflow() throws Http2Exception {
|
public void clientLocalIncrementAndGetStreamShouldRespectOverflow() throws Http2Exception {
|
||||||
incrementAndGetStreamShouldRespectOverflow(client.local(), MAX_VALUE);
|
incrementAndGetStreamShouldRespectOverflow(client.local(), MAX_VALUE);
|
||||||
}
|
}
|
||||||
@ -373,51 +371,82 @@ public class DefaultHttp2ConnectionTest {
|
|||||||
@Test
|
@Test
|
||||||
public void clientLocalCreateStreamExhaustedSpace() throws Http2Exception {
|
public void clientLocalCreateStreamExhaustedSpace() throws Http2Exception {
|
||||||
client.local().createStream(MAX_VALUE, true);
|
client.local().createStream(MAX_VALUE, true);
|
||||||
try {
|
Http2Exception expected = assertThrows(Http2Exception.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
client.local().createStream(MAX_VALUE, true);
|
client.local().createStream(MAX_VALUE, true);
|
||||||
fail();
|
}
|
||||||
} catch (Http2Exception expected) {
|
});
|
||||||
assertEquals(Http2Error.REFUSED_STREAM, expected.error());
|
assertEquals(Http2Error.REFUSED_STREAM, expected.error());
|
||||||
assertEquals(Http2Exception.ShutdownHint.GRACEFUL_SHUTDOWN, expected.shutdownHint());
|
assertEquals(Http2Exception.ShutdownHint.GRACEFUL_SHUTDOWN, expected.shutdownHint());
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = Http2Exception.class)
|
@Test
|
||||||
public void newStreamBehindExpectedShouldThrow() throws Http2Exception {
|
public void newStreamBehindExpectedShouldThrow() throws Http2Exception {
|
||||||
|
assertThrows(Http2Exception.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
server.local().createStream(0, true);
|
server.local().createStream(0, true);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Test(expected = Http2Exception.class)
|
@Test
|
||||||
public void newStreamNotForServerShouldThrow() throws Http2Exception {
|
public void newStreamNotForServerShouldThrow() throws Http2Exception {
|
||||||
|
assertThrows(Http2Exception.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
server.local().createStream(11, true);
|
server.local().createStream(11, true);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Test(expected = Http2Exception.class)
|
@Test
|
||||||
public void newStreamNotForClientShouldThrow() throws Http2Exception {
|
public void newStreamNotForClientShouldThrow() throws Http2Exception {
|
||||||
|
assertThrows(Http2Exception.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
client.local().createStream(10, true);
|
client.local().createStream(10, true);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
@Test(expected = Http2Exception.class)
|
|
||||||
public void createShouldThrowWhenMaxAllowedStreamsOpenExceeded() throws Http2Exception {
|
|
||||||
server.local().maxActiveStreams(0);
|
|
||||||
server.local().createStream(2, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = Http2Exception.class)
|
@Test
|
||||||
|
public void createShouldThrowWhenMaxAllowedStreamsOpenExceeded() throws Http2Exception {
|
||||||
|
server.local().maxActiveStreams(0);
|
||||||
|
assertThrows(Http2Exception.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
|
server.local().createStream(2, true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
public void serverCreatePushShouldFailOnRemoteEndpointWhenMaxAllowedStreamsExceeded() throws Http2Exception {
|
public void serverCreatePushShouldFailOnRemoteEndpointWhenMaxAllowedStreamsExceeded() throws Http2Exception {
|
||||||
server = new DefaultHttp2Connection(true, 0);
|
server = new DefaultHttp2Connection(true, 0);
|
||||||
server.remote().maxActiveStreams(1);
|
server.remote().maxActiveStreams(1);
|
||||||
Http2Stream requestStream = server.remote().createStream(3, false);
|
final Http2Stream requestStream = server.remote().createStream(3, false);
|
||||||
|
assertThrows(Http2Exception.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
server.remote().reservePushStream(2, requestStream);
|
server.remote().reservePushStream(2, requestStream);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Test(expected = Http2Exception.class)
|
@Test
|
||||||
public void clientCreatePushShouldFailOnRemoteEndpointWhenMaxAllowedStreamsExceeded() throws Http2Exception {
|
public void clientCreatePushShouldFailOnRemoteEndpointWhenMaxAllowedStreamsExceeded() throws Http2Exception {
|
||||||
client = new DefaultHttp2Connection(false, 0);
|
client = new DefaultHttp2Connection(false, 0);
|
||||||
client.remote().maxActiveStreams(1);
|
client.remote().maxActiveStreams(1);
|
||||||
Http2Stream requestStream = client.remote().createStream(2, false);
|
final Http2Stream requestStream = client.remote().createStream(2, false);
|
||||||
|
assertThrows(Http2Exception.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
client.remote().reservePushStream(4, requestStream);
|
client.remote().reservePushStream(4, requestStream);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void serverCreatePushShouldSucceedOnLocalEndpointWhenMaxAllowedStreamsExceeded() throws Http2Exception {
|
public void serverCreatePushShouldSucceedOnLocalEndpointWhenMaxAllowedStreamsExceeded() throws Http2Exception {
|
||||||
@ -427,18 +456,28 @@ public class DefaultHttp2ConnectionTest {
|
|||||||
assertNotNull(server.local().reservePushStream(2, requestStream));
|
assertNotNull(server.local().reservePushStream(2, requestStream));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = Http2Exception.class)
|
@Test
|
||||||
public void reserveWithPushDisallowedShouldThrow() throws Http2Exception {
|
public void reserveWithPushDisallowedShouldThrow() throws Http2Exception {
|
||||||
Http2Stream stream = server.remote().createStream(3, true);
|
final Http2Stream stream = server.remote().createStream(3, true);
|
||||||
server.remote().allowPushTo(false);
|
server.remote().allowPushTo(false);
|
||||||
|
assertThrows(Http2Exception.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
server.local().reservePushStream(2, stream);
|
server.local().reservePushStream(2, stream);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Test(expected = Http2Exception.class)
|
@Test
|
||||||
public void goAwayReceivedShouldDisallowLocalCreation() throws Http2Exception {
|
public void goAwayReceivedShouldDisallowLocalCreation() throws Http2Exception {
|
||||||
server.goAwayReceived(0, 1L, Unpooled.EMPTY_BUFFER);
|
server.goAwayReceived(0, 1L, Unpooled.EMPTY_BUFFER);
|
||||||
|
assertThrows(Http2Exception.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
server.local().createStream(3, true);
|
server.local().createStream(3, true);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void goAwayReceivedShouldAllowRemoteCreation() throws Http2Exception {
|
public void goAwayReceivedShouldAllowRemoteCreation() throws Http2Exception {
|
||||||
@ -446,11 +485,17 @@ public class DefaultHttp2ConnectionTest {
|
|||||||
server.remote().createStream(3, true);
|
server.remote().createStream(3, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = Http2Exception.class)
|
@Test
|
||||||
public void goAwaySentShouldDisallowRemoteCreation() throws Http2Exception {
|
public void goAwaySentShouldDisallowRemoteCreation() throws Http2Exception {
|
||||||
server.goAwaySent(0, 1L, Unpooled.EMPTY_BUFFER);
|
server.goAwaySent(0, 1L, Unpooled.EMPTY_BUFFER);
|
||||||
|
|
||||||
|
assertThrows(Http2Exception.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
server.remote().createStream(2, true);
|
server.remote().createStream(2, true);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void goAwaySentShouldAllowLocalCreation() throws Http2Exception {
|
public void goAwaySentShouldAllowLocalCreation() throws Http2Exception {
|
||||||
@ -491,16 +536,26 @@ public class DefaultHttp2ConnectionTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("NumericOverflow")
|
@SuppressWarnings("NumericOverflow")
|
||||||
@Test(expected = Http2Exception.class)
|
@Test
|
||||||
public void localStreamInvalidStreamIdShouldThrow() throws Http2Exception {
|
public void localStreamInvalidStreamIdShouldThrow() {
|
||||||
|
assertThrows(Http2Exception.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
client.local().createStream(MAX_VALUE + 2, false);
|
client.local().createStream(MAX_VALUE + 2, false);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressWarnings("NumericOverflow")
|
@SuppressWarnings("NumericOverflow")
|
||||||
@Test(expected = Http2Exception.class)
|
@Test
|
||||||
public void remoteStreamInvalidStreamIdShouldThrow() throws Http2Exception {
|
public void remoteStreamInvalidStreamIdShouldThrow() {
|
||||||
|
assertThrows(Http2Exception.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
client.remote().createStream(MAX_VALUE + 1, false);
|
client.remote().createStream(MAX_VALUE + 1, false);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* We force {@link #clientListener} methods to all throw a {@link RuntimeException} and verify the following:
|
* We force {@link #clientListener} methods to all throw a {@link RuntimeException} and verify the following:
|
||||||
@ -610,17 +665,22 @@ public class DefaultHttp2ConnectionTest {
|
|||||||
assertTrue(latch.await(5, TimeUnit.SECONDS));
|
assertTrue(latch.await(5, TimeUnit.SECONDS));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void incrementAndGetStreamShouldRespectOverflow(Endpoint<?> endpoint, int streamId)
|
private static void incrementAndGetStreamShouldRespectOverflow(final Endpoint<?> endpoint, int streamId) {
|
||||||
throws Http2Exception {
|
|
||||||
assertTrue(streamId > 0);
|
assertTrue(streamId > 0);
|
||||||
try {
|
try {
|
||||||
endpoint.createStream(streamId, true);
|
endpoint.createStream(streamId, true);
|
||||||
streamId = endpoint.incrementAndGetNextStreamId();
|
streamId = endpoint.incrementAndGetNextStreamId();
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
fail();
|
fail(t);
|
||||||
}
|
}
|
||||||
assertTrue(streamId < 0);
|
assertTrue(streamId < 0);
|
||||||
endpoint.createStream(streamId, true);
|
final int finalStreamId = streamId;
|
||||||
|
assertThrows(Http2NoMoreStreamIdsException.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
|
endpoint.createStream(finalStreamId, true);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void incrementAndGetStreamShouldSucceed(Endpoint<?> endpoint) throws Http2Exception {
|
private static void incrementAndGetStreamShouldSucceed(Endpoint<?> endpoint) throws Http2Exception {
|
||||||
|
@ -18,14 +18,16 @@ import io.netty.buffer.ByteBuf;
|
|||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
import io.netty.buffer.UnpooledByteBufAllocator;
|
import io.netty.buffer.UnpooledByteBufAllocator;
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
import org.junit.After;
|
import org.junit.jupiter.api.AfterEach;
|
||||||
import org.junit.Before;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.function.Executable;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.MockitoAnnotations;
|
import org.mockito.MockitoAnnotations;
|
||||||
|
|
||||||
import static io.netty.handler.codec.http2.Http2CodecUtil.*;
|
import static io.netty.handler.codec.http2.Http2CodecUtil.*;
|
||||||
import static io.netty.handler.codec.http2.Http2FrameTypes.*;
|
import static io.netty.handler.codec.http2.Http2FrameTypes.*;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
import static org.mockito.Mockito.*;
|
import static org.mockito.Mockito.*;
|
||||||
|
|
||||||
|
|
||||||
@ -44,7 +46,7 @@ public class DefaultHttp2FrameReaderTest {
|
|||||||
// Used to generate frame
|
// Used to generate frame
|
||||||
private HpackEncoder hpackEncoder;
|
private HpackEncoder hpackEncoder;
|
||||||
|
|
||||||
@Before
|
@BeforeEach
|
||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
MockitoAnnotations.initMocks(this);
|
MockitoAnnotations.initMocks(this);
|
||||||
|
|
||||||
@ -54,7 +56,7 @@ public class DefaultHttp2FrameReaderTest {
|
|||||||
hpackEncoder = new HpackEncoder();
|
hpackEncoder = new HpackEncoder();
|
||||||
}
|
}
|
||||||
|
|
||||||
@After
|
@AfterEach
|
||||||
public void tearDown() {
|
public void tearDown() {
|
||||||
frameReader.close();
|
frameReader.close();
|
||||||
}
|
}
|
||||||
@ -123,11 +125,11 @@ public class DefaultHttp2FrameReaderTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = Http2Exception.class)
|
@Test
|
||||||
public void failedWhenUnknownFrameInMiddleOfHeaderBlock() throws Http2Exception {
|
public void failedWhenUnknownFrameInMiddleOfHeaderBlock() throws Http2Exception {
|
||||||
final int streamId = 1;
|
final int streamId = 1;
|
||||||
|
|
||||||
ByteBuf input = Unpooled.buffer();
|
final ByteBuf input = Unpooled.buffer();
|
||||||
try {
|
try {
|
||||||
Http2Headers headers = new DefaultHttp2Headers()
|
Http2Headers headers = new DefaultHttp2Headers()
|
||||||
.authority("foo")
|
.authority("foo")
|
||||||
@ -137,15 +139,21 @@ public class DefaultHttp2FrameReaderTest {
|
|||||||
Http2Flags flags = new Http2Flags().endOfHeaders(false).endOfStream(true);
|
Http2Flags flags = new Http2Flags().endOfHeaders(false).endOfStream(true);
|
||||||
writeHeaderFrame(input, streamId, headers, flags);
|
writeHeaderFrame(input, streamId, headers, flags);
|
||||||
writeFrameHeader(input, 0, (byte) 0xff, new Http2Flags(), streamId);
|
writeFrameHeader(input, 0, (byte) 0xff, new Http2Flags(), streamId);
|
||||||
|
|
||||||
|
assertThrows(Http2Exception.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
frameReader.readFrame(ctx, input, listener);
|
frameReader.readFrame(ctx, input, listener);
|
||||||
|
}
|
||||||
|
});
|
||||||
} finally {
|
} finally {
|
||||||
input.release();
|
input.release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = Http2Exception.class)
|
@Test
|
||||||
public void failedWhenContinuationFrameStreamIdMismatch() throws Http2Exception {
|
public void failedWhenContinuationFrameStreamIdMismatch() throws Http2Exception {
|
||||||
ByteBuf input = Unpooled.buffer();
|
final ByteBuf input = Unpooled.buffer();
|
||||||
try {
|
try {
|
||||||
Http2Headers headers = new DefaultHttp2Headers()
|
Http2Headers headers = new DefaultHttp2Headers()
|
||||||
.authority("foo")
|
.authority("foo")
|
||||||
@ -156,27 +164,38 @@ public class DefaultHttp2FrameReaderTest {
|
|||||||
new Http2Flags().endOfHeaders(false).endOfStream(true));
|
new Http2Flags().endOfHeaders(false).endOfStream(true));
|
||||||
writeContinuationFrame(input, 3, new DefaultHttp2Headers().add("foo", "bar"),
|
writeContinuationFrame(input, 3, new DefaultHttp2Headers().add("foo", "bar"),
|
||||||
new Http2Flags().endOfHeaders(true));
|
new Http2Flags().endOfHeaders(true));
|
||||||
|
|
||||||
|
assertThrows(Http2Exception.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
frameReader.readFrame(ctx, input, listener);
|
frameReader.readFrame(ctx, input, listener);
|
||||||
|
}
|
||||||
|
});
|
||||||
} finally {
|
} finally {
|
||||||
input.release();
|
input.release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = Http2Exception.class)
|
@Test
|
||||||
public void failedWhenContinuationFrameNotFollowHeaderFrame() throws Http2Exception {
|
public void failedWhenContinuationFrameNotFollowHeaderFrame() throws Http2Exception {
|
||||||
ByteBuf input = Unpooled.buffer();
|
final ByteBuf input = Unpooled.buffer();
|
||||||
try {
|
try {
|
||||||
writeContinuationFrame(input, 1, new DefaultHttp2Headers().add("foo", "bar"),
|
writeContinuationFrame(input, 1, new DefaultHttp2Headers().add("foo", "bar"),
|
||||||
new Http2Flags().endOfHeaders(true));
|
new Http2Flags().endOfHeaders(true));
|
||||||
|
assertThrows(Http2Exception.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
frameReader.readFrame(ctx, input, listener);
|
frameReader.readFrame(ctx, input, listener);
|
||||||
|
}
|
||||||
|
});
|
||||||
} finally {
|
} finally {
|
||||||
input.release();
|
input.release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = Http2Exception.class)
|
@Test
|
||||||
public void failedWhenHeaderFrameDependsOnItself() throws Http2Exception {
|
public void failedWhenHeaderFrameDependsOnItself() throws Http2Exception {
|
||||||
ByteBuf input = Unpooled.buffer();
|
final ByteBuf input = Unpooled.buffer();
|
||||||
try {
|
try {
|
||||||
Http2Headers headers = new DefaultHttp2Headers()
|
Http2Headers headers = new DefaultHttp2Headers()
|
||||||
.authority("foo")
|
.authority("foo")
|
||||||
@ -187,7 +206,12 @@ public class DefaultHttp2FrameReaderTest {
|
|||||||
input, 1, headers,
|
input, 1, headers,
|
||||||
new Http2Flags().endOfHeaders(true).endOfStream(true).priorityPresent(true),
|
new Http2Flags().endOfHeaders(true).endOfStream(true).priorityPresent(true),
|
||||||
1, 10);
|
1, 10);
|
||||||
|
assertThrows(Http2Exception.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
frameReader.readFrame(ctx, input, listener);
|
frameReader.readFrame(ctx, input, listener);
|
||||||
|
}
|
||||||
|
});
|
||||||
} finally {
|
} finally {
|
||||||
input.release();
|
input.release();
|
||||||
}
|
}
|
||||||
@ -216,16 +240,21 @@ public class DefaultHttp2FrameReaderTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = Http2Exception.class)
|
@Test
|
||||||
public void failedWhenDataFrameNotAssociateWithStream() throws Http2Exception {
|
public void failedWhenDataFrameNotAssociateWithStream() throws Http2Exception {
|
||||||
ByteBuf input = Unpooled.buffer();
|
final ByteBuf input = Unpooled.buffer();
|
||||||
ByteBuf payload = Unpooled.buffer();
|
ByteBuf payload = Unpooled.buffer();
|
||||||
try {
|
try {
|
||||||
payload.writeByte(1);
|
payload.writeByte(1);
|
||||||
|
|
||||||
writeFrameHeader(input, payload.readableBytes(), DATA, new Http2Flags().endOfStream(true), 0);
|
writeFrameHeader(input, payload.readableBytes(), DATA, new Http2Flags().endOfStream(true), 0);
|
||||||
input.writeBytes(payload);
|
input.writeBytes(payload);
|
||||||
|
assertThrows(Http2Exception.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
frameReader.readFrame(ctx, input, listener);
|
frameReader.readFrame(ctx, input, listener);
|
||||||
|
}
|
||||||
|
});
|
||||||
} finally {
|
} finally {
|
||||||
payload.release();
|
payload.release();
|
||||||
input.release();
|
input.release();
|
||||||
@ -243,24 +272,34 @@ public class DefaultHttp2FrameReaderTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = Http2Exception.class)
|
@Test
|
||||||
public void failedWhenPriorityFrameDependsOnItself() throws Http2Exception {
|
public void failedWhenPriorityFrameDependsOnItself() throws Http2Exception {
|
||||||
ByteBuf input = Unpooled.buffer();
|
final ByteBuf input = Unpooled.buffer();
|
||||||
try {
|
try {
|
||||||
writePriorityFrame(input, 1, 1, 10);
|
writePriorityFrame(input, 1, 1, 10);
|
||||||
|
assertThrows(Http2Exception.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
frameReader.readFrame(ctx, input, listener);
|
frameReader.readFrame(ctx, input, listener);
|
||||||
|
}
|
||||||
|
});
|
||||||
} finally {
|
} finally {
|
||||||
input.release();
|
input.release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = Http2Exception.class)
|
@Test
|
||||||
public void failedWhenWindowUpdateFrameWithZeroDelta() throws Http2Exception {
|
public void failedWhenWindowUpdateFrameWithZeroDelta() throws Http2Exception {
|
||||||
ByteBuf input = Unpooled.buffer();
|
final ByteBuf input = Unpooled.buffer();
|
||||||
try {
|
try {
|
||||||
writeFrameHeader(input, 4, WINDOW_UPDATE, new Http2Flags(), 0);
|
writeFrameHeader(input, 4, WINDOW_UPDATE, new Http2Flags(), 0);
|
||||||
input.writeInt(0);
|
input.writeInt(0);
|
||||||
|
assertThrows(Http2Exception.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
frameReader.readFrame(ctx, input, listener);
|
frameReader.readFrame(ctx, input, listener);
|
||||||
|
}
|
||||||
|
});
|
||||||
} finally {
|
} finally {
|
||||||
input.release();
|
input.release();
|
||||||
}
|
}
|
||||||
@ -294,39 +333,54 @@ public class DefaultHttp2FrameReaderTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = Http2Exception.class)
|
@Test
|
||||||
public void failedWhenSettingsFrameOnNonZeroStream() throws Http2Exception {
|
public void failedWhenSettingsFrameOnNonZeroStream() throws Http2Exception {
|
||||||
ByteBuf input = Unpooled.buffer();
|
final ByteBuf input = Unpooled.buffer();
|
||||||
try {
|
try {
|
||||||
writeFrameHeader(input, 6, SETTINGS, new Http2Flags(), 1);
|
writeFrameHeader(input, 6, SETTINGS, new Http2Flags(), 1);
|
||||||
input.writeShort(SETTINGS_MAX_HEADER_LIST_SIZE);
|
input.writeShort(SETTINGS_MAX_HEADER_LIST_SIZE);
|
||||||
input.writeInt(1024);
|
input.writeInt(1024);
|
||||||
|
assertThrows(Http2Exception.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
frameReader.readFrame(ctx, input, listener);
|
frameReader.readFrame(ctx, input, listener);
|
||||||
|
}
|
||||||
|
});
|
||||||
} finally {
|
} finally {
|
||||||
input.release();
|
input.release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = Http2Exception.class)
|
@Test
|
||||||
public void failedWhenAckSettingsFrameWithPayload() throws Http2Exception {
|
public void failedWhenAckSettingsFrameWithPayload() throws Http2Exception {
|
||||||
ByteBuf input = Unpooled.buffer();
|
final ByteBuf input = Unpooled.buffer();
|
||||||
try {
|
try {
|
||||||
writeFrameHeader(input, 1, SETTINGS, new Http2Flags().ack(true), 0);
|
writeFrameHeader(input, 1, SETTINGS, new Http2Flags().ack(true), 0);
|
||||||
input.writeByte(1);
|
input.writeByte(1);
|
||||||
|
assertThrows(Http2Exception.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
frameReader.readFrame(ctx, input, listener);
|
frameReader.readFrame(ctx, input, listener);
|
||||||
|
}
|
||||||
|
});
|
||||||
} finally {
|
} finally {
|
||||||
input.release();
|
input.release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = Http2Exception.class)
|
@Test
|
||||||
public void failedWhenSettingsFrameWithWrongPayloadLength() throws Http2Exception {
|
public void failedWhenSettingsFrameWithWrongPayloadLength() throws Http2Exception {
|
||||||
ByteBuf input = Unpooled.buffer();
|
final ByteBuf input = Unpooled.buffer();
|
||||||
try {
|
try {
|
||||||
writeFrameHeader(input, 8, SETTINGS, new Http2Flags(), 0);
|
writeFrameHeader(input, 8, SETTINGS, new Http2Flags(), 0);
|
||||||
input.writeInt(SETTINGS_MAX_HEADER_LIST_SIZE);
|
input.writeInt(SETTINGS_MAX_HEADER_LIST_SIZE);
|
||||||
input.writeInt(1024);
|
input.writeInt(1024);
|
||||||
|
assertThrows(Http2Exception.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
frameReader.readFrame(ctx, input, listener);
|
frameReader.readFrame(ctx, input, listener);
|
||||||
|
}
|
||||||
|
});
|
||||||
} finally {
|
} finally {
|
||||||
input.release();
|
input.release();
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,6 @@
|
|||||||
package io.netty.handler.codec.http2;
|
package io.netty.handler.codec.http2;
|
||||||
|
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.buffer.ByteBufUtil;
|
|
||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
import io.netty.buffer.UnpooledByteBufAllocator;
|
import io.netty.buffer.UnpooledByteBufAllocator;
|
||||||
import io.netty.channel.Channel;
|
import io.netty.channel.Channel;
|
||||||
@ -25,9 +24,9 @@ import io.netty.channel.ChannelPromise;
|
|||||||
import io.netty.channel.DefaultChannelPromise;
|
import io.netty.channel.DefaultChannelPromise;
|
||||||
import io.netty.util.ReferenceCountUtil;
|
import io.netty.util.ReferenceCountUtil;
|
||||||
import io.netty.util.concurrent.ImmediateEventExecutor;
|
import io.netty.util.concurrent.ImmediateEventExecutor;
|
||||||
import org.junit.After;
|
import org.junit.jupiter.api.AfterEach;
|
||||||
import org.junit.Before;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.MockitoAnnotations;
|
import org.mockito.MockitoAnnotations;
|
||||||
import org.mockito.invocation.InvocationOnMock;
|
import org.mockito.invocation.InvocationOnMock;
|
||||||
@ -37,7 +36,9 @@ import java.io.ByteArrayOutputStream;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
import static org.mockito.Mockito.*;
|
import static org.mockito.Mockito.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -63,7 +64,7 @@ public class DefaultHttp2FrameWriterTest {
|
|||||||
@Mock
|
@Mock
|
||||||
private ChannelHandlerContext ctx;
|
private ChannelHandlerContext ctx;
|
||||||
|
|
||||||
@Before
|
@BeforeEach
|
||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
MockitoAnnotations.initMocks(this);
|
MockitoAnnotations.initMocks(this);
|
||||||
http2HeadersEncoder = new DefaultHttp2HeadersEncoder(
|
http2HeadersEncoder = new DefaultHttp2HeadersEncoder(
|
||||||
@ -96,7 +97,7 @@ public class DefaultHttp2FrameWriterTest {
|
|||||||
when(ctx.executor()).thenReturn(ImmediateEventExecutor.INSTANCE);
|
when(ctx.executor()).thenReturn(ImmediateEventExecutor.INSTANCE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@After
|
@AfterEach
|
||||||
public void tearDown() throws Exception {
|
public void tearDown() throws Exception {
|
||||||
outbound.release();
|
outbound.release();
|
||||||
expectedOutbound.release();
|
expectedOutbound.release();
|
||||||
|
@ -18,8 +18,9 @@ package io.netty.handler.codec.http2;
|
|||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
import io.netty.util.AsciiString;
|
import io.netty.util.AsciiString;
|
||||||
import org.junit.Before;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.function.Executable;
|
||||||
|
|
||||||
import static io.netty.handler.codec.http2.Http2CodecUtil.MAX_HEADER_LIST_SIZE;
|
import static io.netty.handler.codec.http2.Http2CodecUtil.MAX_HEADER_LIST_SIZE;
|
||||||
import static io.netty.handler.codec.http2.Http2CodecUtil.MIN_HEADER_LIST_SIZE;
|
import static io.netty.handler.codec.http2.Http2CodecUtil.MIN_HEADER_LIST_SIZE;
|
||||||
@ -27,8 +28,8 @@ import static io.netty.handler.codec.http2.Http2HeadersEncoder.NEVER_SENSITIVE;
|
|||||||
import static io.netty.handler.codec.http2.Http2TestUtil.newTestEncoder;
|
import static io.netty.handler.codec.http2.Http2TestUtil.newTestEncoder;
|
||||||
import static io.netty.handler.codec.http2.Http2TestUtil.randomBytes;
|
import static io.netty.handler.codec.http2.Http2TestUtil.randomBytes;
|
||||||
import static io.netty.util.CharsetUtil.UTF_8;
|
import static io.netty.util.CharsetUtil.UTF_8;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.Assert.fail;
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests for {@link DefaultHttp2HeadersDecoder}.
|
* Tests for {@link DefaultHttp2HeadersDecoder}.
|
||||||
@ -37,7 +38,7 @@ public class DefaultHttp2HeadersDecoderTest {
|
|||||||
|
|
||||||
private DefaultHttp2HeadersDecoder decoder;
|
private DefaultHttp2HeadersDecoder decoder;
|
||||||
|
|
||||||
@Before
|
@BeforeEach
|
||||||
public void setup() {
|
public void setup() {
|
||||||
decoder = new DefaultHttp2HeadersDecoder(false);
|
decoder = new DefaultHttp2HeadersDecoder(false);
|
||||||
}
|
}
|
||||||
@ -55,14 +56,19 @@ public class DefaultHttp2HeadersDecoderTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = Http2Exception.class)
|
@Test
|
||||||
public void testExceedHeaderSize() throws Exception {
|
public void testExceedHeaderSize() throws Exception {
|
||||||
final int maxListSize = 100;
|
final int maxListSize = 100;
|
||||||
decoder.configuration().maxHeaderListSize(maxListSize, maxListSize);
|
decoder.configuration().maxHeaderListSize(maxListSize, maxListSize);
|
||||||
ByteBuf buf = encode(randomBytes(maxListSize), randomBytes(1));
|
final ByteBuf buf = encode(randomBytes(maxListSize), randomBytes(1));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
assertThrows(Http2Exception.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
decoder.decodeHeaders(0, buf);
|
decoder.decodeHeaders(0, buf);
|
||||||
fail();
|
}
|
||||||
|
});
|
||||||
} finally {
|
} finally {
|
||||||
buf.release();
|
buf.release();
|
||||||
}
|
}
|
||||||
@ -71,27 +77,32 @@ public class DefaultHttp2HeadersDecoderTest {
|
|||||||
@Test
|
@Test
|
||||||
public void decodeLargerThanHeaderListSizeButLessThanGoAway() throws Exception {
|
public void decodeLargerThanHeaderListSizeButLessThanGoAway() throws Exception {
|
||||||
decoder.maxHeaderListSize(MIN_HEADER_LIST_SIZE, MAX_HEADER_LIST_SIZE);
|
decoder.maxHeaderListSize(MIN_HEADER_LIST_SIZE, MAX_HEADER_LIST_SIZE);
|
||||||
ByteBuf buf = encode(b(":method"), b("GET"));
|
final ByteBuf buf = encode(b(":method"), b("GET"));
|
||||||
final int streamId = 1;
|
final int streamId = 1;
|
||||||
try {
|
Http2Exception.HeaderListSizeException e =
|
||||||
|
assertThrows(Http2Exception.HeaderListSizeException.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
decoder.decodeHeaders(streamId, buf);
|
decoder.decodeHeaders(streamId, buf);
|
||||||
fail();
|
|
||||||
} catch (Http2Exception.HeaderListSizeException e) {
|
|
||||||
assertEquals(streamId, e.streamId());
|
|
||||||
} finally {
|
|
||||||
buf.release();
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
assertEquals(streamId, e.streamId());
|
||||||
|
buf.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void decodeLargerThanHeaderListSizeButLessThanGoAwayWithInitialDecoderSettings() throws Exception {
|
public void decodeLargerThanHeaderListSizeButLessThanGoAwayWithInitialDecoderSettings() throws Exception {
|
||||||
ByteBuf buf = encode(b(":method"), b("GET"), b("test_header"),
|
final ByteBuf buf = encode(b(":method"), b("GET"), b("test_header"),
|
||||||
b(String.format("%09000d", 0).replace('0', 'A')));
|
b(String.format("%09000d", 0).replace('0', 'A')));
|
||||||
final int streamId = 1;
|
final int streamId = 1;
|
||||||
try {
|
try {
|
||||||
|
Http2Exception.HeaderListSizeException e = assertThrows(Http2Exception.HeaderListSizeException.class,
|
||||||
|
new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
decoder.decodeHeaders(streamId, buf);
|
decoder.decodeHeaders(streamId, buf);
|
||||||
fail();
|
}
|
||||||
} catch (Http2Exception.HeaderListSizeException e) {
|
});
|
||||||
assertEquals(streamId, e.streamId());
|
assertEquals(streamId, e.streamId());
|
||||||
} finally {
|
} finally {
|
||||||
buf.release();
|
buf.release();
|
||||||
@ -101,12 +112,15 @@ public class DefaultHttp2HeadersDecoderTest {
|
|||||||
@Test
|
@Test
|
||||||
public void decodeLargerThanHeaderListSizeGoAway() throws Exception {
|
public void decodeLargerThanHeaderListSizeGoAway() throws Exception {
|
||||||
decoder.maxHeaderListSize(MIN_HEADER_LIST_SIZE, MIN_HEADER_LIST_SIZE);
|
decoder.maxHeaderListSize(MIN_HEADER_LIST_SIZE, MIN_HEADER_LIST_SIZE);
|
||||||
ByteBuf buf = encode(b(":method"), b("GET"));
|
final ByteBuf buf = encode(b(":method"), b("GET"));
|
||||||
final int streamId = 1;
|
final int streamId = 1;
|
||||||
try {
|
try {
|
||||||
|
Http2Exception e = assertThrows(Http2Exception.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
decoder.decodeHeaders(streamId, buf);
|
decoder.decodeHeaders(streamId, buf);
|
||||||
fail();
|
}
|
||||||
} catch (Http2Exception e) {
|
});
|
||||||
assertEquals(Http2Error.PROTOCOL_ERROR, e.error());
|
assertEquals(Http2Error.PROTOCOL_ERROR, e.error());
|
||||||
} finally {
|
} finally {
|
||||||
buf.release();
|
buf.release();
|
||||||
|
@ -19,11 +19,13 @@ import io.netty.buffer.ByteBuf;
|
|||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
import io.netty.handler.codec.http2.Http2Exception.StreamException;
|
import io.netty.handler.codec.http2.Http2Exception.StreamException;
|
||||||
import io.netty.util.AsciiString;
|
import io.netty.util.AsciiString;
|
||||||
import org.junit.Before;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.function.Executable;
|
||||||
|
|
||||||
import static io.netty.handler.codec.http2.Http2TestUtil.newTestEncoder;
|
import static io.netty.handler.codec.http2.Http2TestUtil.newTestEncoder;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests for {@link DefaultHttp2HeadersEncoder}.
|
* Tests for {@link DefaultHttp2HeadersEncoder}.
|
||||||
@ -32,7 +34,7 @@ public class DefaultHttp2HeadersEncoderTest {
|
|||||||
|
|
||||||
private DefaultHttp2HeadersEncoder encoder;
|
private DefaultHttp2HeadersEncoder encoder;
|
||||||
|
|
||||||
@Before
|
@BeforeEach
|
||||||
public void setup() {
|
public void setup() {
|
||||||
encoder = new DefaultHttp2HeadersEncoder(Http2HeadersEncoder.NEVER_SENSITIVE, newTestEncoder());
|
encoder = new DefaultHttp2HeadersEncoder(Http2HeadersEncoder.NEVER_SENSITIVE, newTestEncoder());
|
||||||
}
|
}
|
||||||
@ -49,12 +51,17 @@ public class DefaultHttp2HeadersEncoderTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = StreamException.class)
|
@Test
|
||||||
public void headersExceedMaxSetSizeShouldFail() throws Http2Exception {
|
public void headersExceedMaxSetSizeShouldFail() throws Http2Exception {
|
||||||
Http2Headers headers = headers();
|
final Http2Headers headers = headers();
|
||||||
encoder.maxHeaderListSize(2);
|
encoder.maxHeaderListSize(2);
|
||||||
|
assertThrows(StreamException.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
encoder.encodeHeaders(3 /* randomly chosen */, headers, Unpooled.buffer());
|
encoder.encodeHeaders(3 /* randomly chosen */, headers, Unpooled.buffer());
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private static Http2Headers headers() {
|
private static Http2Headers headers() {
|
||||||
return new DefaultHttp2Headers().method(new AsciiString("GET")).add(new AsciiString("a"), new AsciiString("1"))
|
return new DefaultHttp2Headers().method(new AsciiString("GET")).add(new AsciiString("a"), new AsciiString("1"))
|
||||||
|
@ -18,24 +18,40 @@ package io.netty.handler.codec.http2;
|
|||||||
|
|
||||||
import io.netty.handler.codec.http2.Http2Headers.PseudoHeaderName;
|
import io.netty.handler.codec.http2.Http2Headers.PseudoHeaderName;
|
||||||
import io.netty.util.internal.StringUtil;
|
import io.netty.util.internal.StringUtil;
|
||||||
import org.junit.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.function.Executable;
|
||||||
|
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
import static io.netty.util.AsciiString.*;
|
import static io.netty.util.AsciiString.*;
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
import static org.junit.jupiter.api.Assertions.fail;
|
||||||
|
|
||||||
public class DefaultHttp2HeadersTest {
|
public class DefaultHttp2HeadersTest {
|
||||||
|
|
||||||
@Test(expected = Http2Exception.class)
|
@Test
|
||||||
public void nullHeaderNameNotAllowed() {
|
public void nullHeaderNameNotAllowed() {
|
||||||
|
assertThrows(Http2Exception.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
new DefaultHttp2Headers().add(null, "foo");
|
new DefaultHttp2Headers().add(null, "foo");
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Test(expected = Http2Exception.class)
|
@Test
|
||||||
public void emptyHeaderNameNotAllowed() {
|
public void emptyHeaderNameNotAllowed() {
|
||||||
|
assertThrows(Http2Exception.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
new DefaultHttp2Headers().add(StringUtil.EMPTY_STRING, "foo");
|
new DefaultHttp2Headers().add(StringUtil.EMPTY_STRING, "foo");
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testPseudoHeadersMustComeFirstWhenIterating() {
|
public void testPseudoHeadersMustComeFirstWhenIterating() {
|
||||||
@ -126,12 +142,17 @@ public class DefaultHttp2HeadersTest {
|
|||||||
assertEquals("value2", headers.get("name2"));
|
assertEquals("value2", headers.get("name2"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = Http2Exception.class)
|
@Test
|
||||||
public void testHeaderNameValidation() {
|
public void testHeaderNameValidation() {
|
||||||
Http2Headers headers = newHeaders();
|
final Http2Headers headers = newHeaders();
|
||||||
|
|
||||||
|
assertThrows(Http2Exception.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
headers.add(of("Foo"), of("foo"));
|
headers.add(of("Foo"), of("foo"));
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testClearResetsPseudoHeaderDivision() {
|
public void testClearResetsPseudoHeaderDivision() {
|
||||||
|
@ -18,16 +18,16 @@ package io.netty.handler.codec.http2;
|
|||||||
import static io.netty.handler.codec.http2.DefaultHttp2LocalFlowController.DEFAULT_WINDOW_UPDATE_RATIO;
|
import static io.netty.handler.codec.http2.DefaultHttp2LocalFlowController.DEFAULT_WINDOW_UPDATE_RATIO;
|
||||||
import static io.netty.handler.codec.http2.Http2CodecUtil.CONNECTION_STREAM_ID;
|
import static io.netty.handler.codec.http2.Http2CodecUtil.CONNECTION_STREAM_ID;
|
||||||
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.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
import static org.junit.Assert.assertNull;
|
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
import static org.mockito.Mockito.any;
|
import static org.mockito.Mockito.any;
|
||||||
import static org.mockito.Mockito.anyInt;
|
import static org.mockito.Mockito.anyInt;
|
||||||
import static org.mockito.Mockito.eq;
|
import static org.mockito.Mockito.eq;
|
||||||
import static org.mockito.Mockito.never;
|
import static org.mockito.Mockito.never;
|
||||||
import static org.mockito.Mockito.reset;
|
import static org.mockito.Mockito.reset;
|
||||||
import static org.mockito.Mockito.times;
|
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
@ -39,8 +39,9 @@ import io.netty.channel.ChannelPromise;
|
|||||||
import io.netty.handler.codec.http2.Http2Stream.State;
|
import io.netty.handler.codec.http2.Http2Stream.State;
|
||||||
import io.netty.util.concurrent.EventExecutor;
|
import io.netty.util.concurrent.EventExecutor;
|
||||||
import junit.framework.AssertionFailedError;
|
import junit.framework.AssertionFailedError;
|
||||||
import org.junit.Before;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.function.Executable;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.MockitoAnnotations;
|
import org.mockito.MockitoAnnotations;
|
||||||
import org.mockito.invocation.InvocationOnMock;
|
import org.mockito.invocation.InvocationOnMock;
|
||||||
@ -68,7 +69,7 @@ public class DefaultHttp2LocalFlowControllerTest {
|
|||||||
|
|
||||||
private DefaultHttp2Connection connection;
|
private DefaultHttp2Connection connection;
|
||||||
|
|
||||||
@Before
|
@BeforeEach
|
||||||
public void setup() throws Http2Exception {
|
public void setup() throws Http2Exception {
|
||||||
MockitoAnnotations.initMocks(this);
|
MockitoAnnotations.initMocks(this);
|
||||||
setupChannelHandlerContext(false);
|
setupChannelHandlerContext(false);
|
||||||
@ -136,11 +137,16 @@ public class DefaultHttp2LocalFlowControllerTest {
|
|||||||
verifyNoMoreInteractions(frameWriter);
|
verifyNoMoreInteractions(frameWriter);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = Http2Exception.class)
|
@Test
|
||||||
public void connectionFlowControlExceededShouldThrow() throws Http2Exception {
|
public void connectionFlowControlExceededShouldThrow() throws Http2Exception {
|
||||||
// Window exceeded because of the padding.
|
// Window exceeded because of the padding.
|
||||||
|
assertThrows(Http2Exception.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
receiveFlowControlledFrame(STREAM_ID, DEFAULT_WINDOW_SIZE, 1, true);
|
receiveFlowControlledFrame(STREAM_ID, DEFAULT_WINDOW_SIZE, 1, true);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void windowUpdateShouldNotBeSentAfterEndOfStream() throws Http2Exception {
|
public void windowUpdateShouldNotBeSentAfterEndOfStream() throws Http2Exception {
|
||||||
@ -342,9 +348,14 @@ public class DefaultHttp2LocalFlowControllerTest {
|
|||||||
assertFalse(controller.consumeBytes(connection.stream(STREAM_ID), 0));
|
assertFalse(controller.consumeBytes(connection.stream(STREAM_ID), 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = IllegalArgumentException.class)
|
@Test
|
||||||
public void consumeBytesForNegativeNumBytesShouldFail() throws Http2Exception {
|
public void consumeBytesForNegativeNumBytesShouldFail() throws Http2Exception {
|
||||||
assertFalse(controller.consumeBytes(connection.stream(STREAM_ID), -1));
|
assertThrows(IllegalArgumentException.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
|
controller.consumeBytes(connection.stream(STREAM_ID), -1);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void testRatio(float ratio, int newDefaultWindowSize, int newStreamId, boolean setStreamRatio)
|
private void testRatio(float ratio, int newDefaultWindowSize, int newStreamId, boolean setStreamRatio)
|
||||||
|
@ -30,14 +30,14 @@ import io.netty.channel.socket.nio.NioServerSocketChannel;
|
|||||||
import io.netty.channel.socket.nio.NioSocketChannel;
|
import io.netty.channel.socket.nio.NioSocketChannel;
|
||||||
import io.netty.util.CharsetUtil;
|
import io.netty.util.CharsetUtil;
|
||||||
import io.netty.util.ReferenceCountUtil;
|
import io.netty.util.ReferenceCountUtil;
|
||||||
import org.junit.After;
|
import org.junit.jupiter.api.AfterEach;
|
||||||
import org.junit.Before;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
public class DefaultHttp2PushPromiseFrameTest {
|
public class DefaultHttp2PushPromiseFrameTest {
|
||||||
|
|
||||||
@ -47,7 +47,7 @@ public class DefaultHttp2PushPromiseFrameTest {
|
|||||||
|
|
||||||
private ChannelFuture connectionFuture;
|
private ChannelFuture connectionFuture;
|
||||||
|
|
||||||
@Before
|
@BeforeEach
|
||||||
public void setup() throws InterruptedException {
|
public void setup() throws InterruptedException {
|
||||||
ServerBootstrap serverBootstrap = new ServerBootstrap()
|
ServerBootstrap serverBootstrap = new ServerBootstrap()
|
||||||
.group(eventLoopGroup)
|
.group(eventLoopGroup)
|
||||||
@ -101,7 +101,7 @@ public class DefaultHttp2PushPromiseFrameTest {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@After
|
@AfterEach
|
||||||
public void shutdown() {
|
public void shutdown() {
|
||||||
eventLoopGroup.shutdownGracefully();
|
eventLoopGroup.shutdownGracefully();
|
||||||
}
|
}
|
||||||
|
@ -20,13 +20,14 @@ import io.netty.channel.ChannelConfig;
|
|||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
import io.netty.channel.ChannelPromise;
|
import io.netty.channel.ChannelPromise;
|
||||||
import io.netty.util.concurrent.EventExecutor;
|
import io.netty.util.concurrent.EventExecutor;
|
||||||
import junit.framework.AssertionFailedError;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.Before;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.Test;
|
import org.junit.jupiter.api.function.Executable;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.MockitoAnnotations;
|
import org.mockito.MockitoAnnotations;
|
||||||
import org.mockito.invocation.InvocationOnMock;
|
import org.mockito.invocation.InvocationOnMock;
|
||||||
import org.mockito.stubbing.Answer;
|
import org.mockito.stubbing.Answer;
|
||||||
|
import org.opentest4j.AssertionFailedError;
|
||||||
|
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
@ -35,12 +36,13 @@ 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 io.netty.handler.codec.http2.Http2CodecUtil.MAX_WEIGHT;
|
import static io.netty.handler.codec.http2.Http2CodecUtil.MAX_WEIGHT;
|
||||||
import static io.netty.handler.codec.http2.Http2CodecUtil.MIN_WEIGHT;
|
import static io.netty.handler.codec.http2.Http2CodecUtil.MIN_WEIGHT;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
import static org.junit.Assert.assertNotNull;
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
import static org.junit.Assert.assertSame;
|
import static org.junit.jupiter.api.Assertions.assertSame;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
import static org.junit.Assert.fail;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
import static org.junit.jupiter.api.Assertions.fail;
|
||||||
import static org.mockito.Mockito.any;
|
import static org.mockito.Mockito.any;
|
||||||
import static org.mockito.Mockito.anyInt;
|
import static org.mockito.Mockito.anyInt;
|
||||||
import static org.mockito.Mockito.atLeastOnce;
|
import static org.mockito.Mockito.atLeastOnce;
|
||||||
@ -86,7 +88,7 @@ public abstract class DefaultHttp2RemoteFlowControllerTest {
|
|||||||
|
|
||||||
private DefaultHttp2Connection connection;
|
private DefaultHttp2Connection connection;
|
||||||
|
|
||||||
@Before
|
@BeforeEach
|
||||||
public void setup() throws Http2Exception {
|
public void setup() throws Http2Exception {
|
||||||
MockitoAnnotations.initMocks(this);
|
MockitoAnnotations.initMocks(this);
|
||||||
|
|
||||||
@ -733,15 +735,14 @@ public abstract class DefaultHttp2RemoteFlowControllerTest {
|
|||||||
|
|
||||||
int windowBefore = window(STREAM_A);
|
int windowBefore = window(STREAM_A);
|
||||||
|
|
||||||
try {
|
Http2Exception e = assertThrows(Http2Exception.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
controller.addFlowControlled(stream, flowControlled);
|
controller.addFlowControlled(stream, flowControlled);
|
||||||
controller.writePendingBytes();
|
controller.writePendingBytes();
|
||||||
fail();
|
|
||||||
} catch (Http2Exception e) {
|
|
||||||
assertSame(fakeException, e.getCause());
|
|
||||||
} catch (Throwable t) {
|
|
||||||
fail();
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
assertSame(fakeException, e.getCause());
|
||||||
|
|
||||||
verify(flowControlled, atLeastOnce()).write(any(ChannelHandlerContext.class), anyInt());
|
verify(flowControlled, atLeastOnce()).write(any(ChannelHandlerContext.class), anyInt());
|
||||||
verify(flowControlled).error(any(ChannelHandlerContext.class), any(Throwable.class));
|
verify(flowControlled).error(any(ChannelHandlerContext.class), any(Throwable.class));
|
||||||
@ -908,35 +909,65 @@ public abstract class DefaultHttp2RemoteFlowControllerTest {
|
|||||||
dataA.assertFullyWritten();
|
dataA.assertFullyWritten();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = AssertionError.class)
|
@Test
|
||||||
public void invalidParentStreamIdThrows() {
|
public void invalidParentStreamIdThrows() {
|
||||||
|
assertThrows(AssertionError.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
controller.updateDependencyTree(STREAM_D, -1, DEFAULT_PRIORITY_WEIGHT, true);
|
controller.updateDependencyTree(STREAM_D, -1, DEFAULT_PRIORITY_WEIGHT, true);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Test(expected = AssertionError.class)
|
@Test
|
||||||
public void invalidChildStreamIdThrows() {
|
public void invalidChildStreamIdThrows() {
|
||||||
|
assertThrows(AssertionError.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
controller.updateDependencyTree(-1, STREAM_D, DEFAULT_PRIORITY_WEIGHT, true);
|
controller.updateDependencyTree(-1, STREAM_D, DEFAULT_PRIORITY_WEIGHT, true);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Test(expected = AssertionError.class)
|
@Test
|
||||||
public void connectionChildStreamIdThrows() {
|
public void connectionChildStreamIdThrows() {
|
||||||
|
assertThrows(AssertionError.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
controller.updateDependencyTree(0, STREAM_D, DEFAULT_PRIORITY_WEIGHT, true);
|
controller.updateDependencyTree(0, STREAM_D, DEFAULT_PRIORITY_WEIGHT, true);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Test(expected = AssertionError.class)
|
@Test
|
||||||
public void invalidWeightTooSmallThrows() {
|
public void invalidWeightTooSmallThrows() {
|
||||||
|
assertThrows(AssertionError.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
controller.updateDependencyTree(STREAM_A, STREAM_D, (short) (MIN_WEIGHT - 1), true);
|
controller.updateDependencyTree(STREAM_A, STREAM_D, (short) (MIN_WEIGHT - 1), true);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
@Test(expected = AssertionError.class)
|
|
||||||
public void invalidWeightTooBigThrows() {
|
|
||||||
controller.updateDependencyTree(STREAM_A, STREAM_D, (short) (MAX_WEIGHT + 1), true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = AssertionError.class)
|
@Test
|
||||||
|
public void invalidWeightTooBigThrows() {
|
||||||
|
assertThrows(AssertionError.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
|
controller.updateDependencyTree(STREAM_A, STREAM_D, (short) (MAX_WEIGHT + 1), true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
public void dependencyOnSelfThrows() {
|
public void dependencyOnSelfThrows() {
|
||||||
|
assertThrows(AssertionError.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
controller.updateDependencyTree(STREAM_A, STREAM_A, DEFAULT_PRIORITY_WEIGHT, true);
|
controller.updateDependencyTree(STREAM_A, STREAM_A, DEFAULT_PRIORITY_WEIGHT, true);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private void assertWritabilityChanged(int amt, boolean writable) {
|
private void assertWritabilityChanged(int amt, boolean writable) {
|
||||||
verify(listener, times(amt)).writabilityChanged(stream(STREAM_A));
|
verify(listener, times(amt)).writabilityChanged(stream(STREAM_A));
|
||||||
|
@ -18,7 +18,7 @@ import io.netty.handler.codec.http.HttpHeaderNames;
|
|||||||
import io.netty.handler.codec.http.HttpHeaderValues;
|
import io.netty.handler.codec.http.HttpHeaderValues;
|
||||||
import io.netty.util.AsciiString;
|
import io.netty.util.AsciiString;
|
||||||
import io.netty.util.internal.PlatformDependent;
|
import io.netty.util.internal.PlatformDependent;
|
||||||
import org.junit.Ignore;
|
import org.junit.jupiter.api.Disabled;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
@ -37,7 +37,7 @@ import java.util.Map;
|
|||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
@Ignore
|
@Disabled
|
||||||
public final class HashCollisionTest {
|
public final class HashCollisionTest {
|
||||||
private HashCollisionTest() { }
|
private HashCollisionTest() { }
|
||||||
|
|
||||||
|
@ -34,10 +34,9 @@ package io.netty.handler.codec.http2;
|
|||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
import io.netty.util.internal.StringUtil;
|
import io.netty.util.internal.StringUtil;
|
||||||
import org.junit.Before;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.Rule;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.Test;
|
import org.junit.jupiter.api.function.Executable;
|
||||||
import org.junit.rules.ExpectedException;
|
|
||||||
|
|
||||||
import static io.netty.handler.codec.http2.HpackDecoder.decodeULE128;
|
import static io.netty.handler.codec.http2.HpackDecoder.decodeULE128;
|
||||||
import static io.netty.handler.codec.http2.Http2HeadersEncoder.NEVER_SENSITIVE;
|
import static io.netty.handler.codec.http2.Http2HeadersEncoder.NEVER_SENSITIVE;
|
||||||
@ -47,9 +46,8 @@ import static java.lang.Integer.MAX_VALUE;
|
|||||||
import static org.hamcrest.CoreMatchers.is;
|
import static org.hamcrest.CoreMatchers.is;
|
||||||
import static org.hamcrest.MatcherAssert.assertThat;
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
|
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
import static org.junit.Assert.fail;
|
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.reset;
|
import static org.mockito.Mockito.reset;
|
||||||
import static org.mockito.Mockito.times;
|
import static org.mockito.Mockito.times;
|
||||||
@ -57,8 +55,6 @@ import static org.mockito.Mockito.verify;
|
|||||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||||
|
|
||||||
public class HpackDecoderTest {
|
public class HpackDecoderTest {
|
||||||
@Rule
|
|
||||||
public final ExpectedException expectedException = ExpectedException.none();
|
|
||||||
|
|
||||||
private HpackDecoder hpackDecoder;
|
private HpackDecoder hpackDecoder;
|
||||||
private Http2Headers mockHeaders;
|
private Http2Headers mockHeaders;
|
||||||
@ -77,7 +73,7 @@ public class HpackDecoderTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Before
|
@BeforeEach
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
hpackDecoder = new HpackDecoder(8192);
|
hpackDecoder = new HpackDecoder(8192);
|
||||||
mockHeaders = mock(Http2Headers.class);
|
mockHeaders = mock(Http2Headers.class);
|
||||||
@ -94,26 +90,36 @@ public class HpackDecoderTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = Http2Exception.class)
|
@Test
|
||||||
public void testDecodeULE128IntOverflow1() throws Http2Exception {
|
public void testDecodeULE128IntOverflow1() throws Http2Exception {
|
||||||
byte[] input = {(byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0x07};
|
byte[] input = {(byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0x07};
|
||||||
ByteBuf in = Unpooled.wrappedBuffer(input);
|
final ByteBuf in = Unpooled.wrappedBuffer(input);
|
||||||
final int readerIndex = in.readerIndex();
|
final int readerIndex = in.readerIndex();
|
||||||
try {
|
try {
|
||||||
|
assertThrows(Http2Exception.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
decodeULE128(in, 1);
|
decodeULE128(in, 1);
|
||||||
|
}
|
||||||
|
});
|
||||||
} finally {
|
} finally {
|
||||||
assertEquals(readerIndex, in.readerIndex());
|
assertEquals(readerIndex, in.readerIndex());
|
||||||
in.release();
|
in.release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = Http2Exception.class)
|
@Test
|
||||||
public void testDecodeULE128IntOverflow2() throws Http2Exception {
|
public void testDecodeULE128IntOverflow2() throws Http2Exception {
|
||||||
byte[] input = {(byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0x08};
|
byte[] input = {(byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0x08};
|
||||||
ByteBuf in = Unpooled.wrappedBuffer(input);
|
final ByteBuf in = Unpooled.wrappedBuffer(input);
|
||||||
final int readerIndex = in.readerIndex();
|
final int readerIndex = in.readerIndex();
|
||||||
try {
|
try {
|
||||||
|
assertThrows(Http2Exception.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
decodeULE128(in, 0);
|
decodeULE128(in, 0);
|
||||||
|
}
|
||||||
|
});
|
||||||
} finally {
|
} finally {
|
||||||
assertEquals(readerIndex, in.readerIndex());
|
assertEquals(readerIndex, in.readerIndex());
|
||||||
in.release();
|
in.release();
|
||||||
@ -132,28 +138,38 @@ public class HpackDecoderTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = Http2Exception.class)
|
@Test
|
||||||
public void testDecodeULE128LongOverflow1() throws Http2Exception {
|
public void testDecodeULE128LongOverflow1() throws Http2Exception {
|
||||||
byte[] input = {(byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
|
byte[] input = {(byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
|
||||||
(byte) 0xFF, (byte) 0xFF};
|
(byte) 0xFF, (byte) 0xFF};
|
||||||
ByteBuf in = Unpooled.wrappedBuffer(input);
|
final ByteBuf in = Unpooled.wrappedBuffer(input);
|
||||||
final int readerIndex = in.readerIndex();
|
final int readerIndex = in.readerIndex();
|
||||||
try {
|
try {
|
||||||
|
assertThrows(Http2Exception.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
decodeULE128(in, 0L);
|
decodeULE128(in, 0L);
|
||||||
|
}
|
||||||
|
});
|
||||||
} finally {
|
} finally {
|
||||||
assertEquals(readerIndex, in.readerIndex());
|
assertEquals(readerIndex, in.readerIndex());
|
||||||
in.release();
|
in.release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = Http2Exception.class)
|
@Test
|
||||||
public void testDecodeULE128LongOverflow2() throws Http2Exception {
|
public void testDecodeULE128LongOverflow2() throws Http2Exception {
|
||||||
byte[] input = {(byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
|
byte[] input = {(byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
|
||||||
(byte) 0xFF, (byte) 0x7F};
|
(byte) 0xFF, (byte) 0x7F};
|
||||||
ByteBuf in = Unpooled.wrappedBuffer(input);
|
final ByteBuf in = Unpooled.wrappedBuffer(input);
|
||||||
final int readerIndex = in.readerIndex();
|
final int readerIndex = in.readerIndex();
|
||||||
try {
|
try {
|
||||||
|
assertThrows(Http2Exception.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
decodeULE128(in, 1L);
|
decodeULE128(in, 1L);
|
||||||
|
}
|
||||||
|
});
|
||||||
} finally {
|
} finally {
|
||||||
assertEquals(readerIndex, in.readerIndex());
|
assertEquals(readerIndex, in.readerIndex());
|
||||||
in.release();
|
in.release();
|
||||||
@ -174,13 +190,18 @@ public class HpackDecoderTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = Http2Exception.class)
|
@Test
|
||||||
public void testSetTableSizeOverLimitFails() throws Http2Exception {
|
public void testSetTableSizeOverLimitFails() throws Http2Exception {
|
||||||
byte[] input = {(byte) 0x3F, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0x0E};
|
byte[] input = {(byte) 0x3F, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0x0E};
|
||||||
ByteBuf in = Unpooled.wrappedBuffer(input);
|
final ByteBuf in = Unpooled.wrappedBuffer(input);
|
||||||
try {
|
try {
|
||||||
hpackDecoder.setMaxHeaderTableSize(4026531870L - 1); // based on the input above ... 1 less than is above.
|
hpackDecoder.setMaxHeaderTableSize(4026531870L - 1); // based on the input above ... 1 less than is above.
|
||||||
|
assertThrows(Http2Exception.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
hpackDecoder.decode(0, in, mockHeaders, true);
|
hpackDecoder.decode(0, in, mockHeaders, true);
|
||||||
|
}
|
||||||
|
});
|
||||||
} finally {
|
} finally {
|
||||||
in.release();
|
in.release();
|
||||||
}
|
}
|
||||||
@ -198,69 +219,103 @@ public class HpackDecoderTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = Http2Exception.class)
|
@Test
|
||||||
public void testLiteralHuffmanEncodedWithPaddingGreaterThan7Throws() throws Http2Exception {
|
public void testLiteralHuffmanEncodedWithPaddingGreaterThan7Throws() throws Http2Exception {
|
||||||
byte[] input = {0, (byte) 0x81, -1};
|
byte[] input = {0, (byte) 0x81, -1};
|
||||||
ByteBuf in = Unpooled.wrappedBuffer(input);
|
final ByteBuf in = Unpooled.wrappedBuffer(input);
|
||||||
try {
|
try {
|
||||||
|
assertThrows(Http2Exception.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
hpackDecoder.decode(0, in, mockHeaders, true);
|
hpackDecoder.decode(0, in, mockHeaders, true);
|
||||||
|
}
|
||||||
|
});
|
||||||
} finally {
|
} finally {
|
||||||
in.release();
|
in.release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = Http2Exception.class)
|
@Test
|
||||||
public void testLiteralHuffmanEncodedWithDecodingEOSThrows() throws Http2Exception {
|
public void testLiteralHuffmanEncodedWithDecodingEOSThrows() throws Http2Exception {
|
||||||
byte[] input = {0, (byte) 0x84, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF};
|
byte[] input = {0, (byte) 0x84, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF};
|
||||||
ByteBuf in = Unpooled.wrappedBuffer(input);
|
final ByteBuf in = Unpooled.wrappedBuffer(input);
|
||||||
try {
|
try {
|
||||||
|
assertThrows(Http2Exception.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
hpackDecoder.decode(0, in, mockHeaders, true);
|
hpackDecoder.decode(0, in, mockHeaders, true);
|
||||||
|
}
|
||||||
|
});
|
||||||
} finally {
|
} finally {
|
||||||
in.release();
|
in.release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = Http2Exception.class)
|
@Test
|
||||||
public void testLiteralHuffmanEncodedWithPaddingNotCorrespondingToMSBThrows() throws Http2Exception {
|
public void testLiteralHuffmanEncodedWithPaddingNotCorrespondingToMSBThrows() throws Http2Exception {
|
||||||
byte[] input = {0, (byte) 0x81, 0};
|
byte[] input = {0, (byte) 0x81, 0};
|
||||||
ByteBuf in = Unpooled.wrappedBuffer(input);
|
final ByteBuf in = Unpooled.wrappedBuffer(input);
|
||||||
try {
|
try {
|
||||||
|
assertThrows(Http2Exception.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
hpackDecoder.decode(0, in, mockHeaders, true);
|
hpackDecoder.decode(0, in, mockHeaders, true);
|
||||||
|
}
|
||||||
|
});
|
||||||
} finally {
|
} finally {
|
||||||
in.release();
|
in.release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = Http2Exception.class)
|
@Test
|
||||||
public void testIncompleteIndex() throws Http2Exception {
|
public void testIncompleteIndex() throws Http2Exception {
|
||||||
byte[] compressed = StringUtil.decodeHexDump("FFF0");
|
byte[] compressed = StringUtil.decodeHexDump("FFF0");
|
||||||
ByteBuf in = Unpooled.wrappedBuffer(compressed);
|
final ByteBuf in = Unpooled.wrappedBuffer(compressed);
|
||||||
try {
|
try {
|
||||||
|
assertEquals(2, in.readableBytes());
|
||||||
|
assertThrows(Http2Exception.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
hpackDecoder.decode(0, in, mockHeaders, true);
|
hpackDecoder.decode(0, in, mockHeaders, true);
|
||||||
assertEquals(1, in.readableBytes());
|
}
|
||||||
hpackDecoder.decode(0, in, mockHeaders, true);
|
});
|
||||||
} finally {
|
} finally {
|
||||||
in.release();
|
in.release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = Http2Exception.class)
|
@Test
|
||||||
public void testUnusedIndex() throws Http2Exception {
|
public void testUnusedIndex() throws Http2Exception {
|
||||||
// Index 0 is not used
|
// Index 0 is not used
|
||||||
|
assertThrows(Http2Exception.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
decode("80");
|
decode("80");
|
||||||
}
|
}
|
||||||
|
});
|
||||||
@Test(expected = Http2Exception.class)
|
|
||||||
public void testIllegalIndex() throws Http2Exception {
|
|
||||||
// Index larger than the header table
|
|
||||||
decode("FF00");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = Http2Exception.class)
|
@Test
|
||||||
|
public void testIllegalIndex() throws Http2Exception {
|
||||||
|
// Index larger than the header table
|
||||||
|
assertThrows(Http2Exception.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
|
decode("FF00");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
public void testInsidiousIndex() throws Http2Exception {
|
public void testInsidiousIndex() throws Http2Exception {
|
||||||
// Insidious index so the last shift causes sign overflow
|
// Insidious index so the last shift causes sign overflow
|
||||||
|
assertThrows(Http2Exception.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
decode("FF8080808007");
|
decode("FF8080808007");
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDynamicTableSizeUpdate() throws Http2Exception {
|
public void testDynamicTableSizeUpdate() throws Http2Exception {
|
||||||
@ -277,18 +332,28 @@ public class HpackDecoderTest {
|
|||||||
assertEquals(31, hpackDecoder.getMaxHeaderTableSize());
|
assertEquals(31, hpackDecoder.getMaxHeaderTableSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = Http2Exception.class)
|
@Test
|
||||||
public void testIllegalDynamicTableSizeUpdate() throws Http2Exception {
|
public void testIllegalDynamicTableSizeUpdate() throws Http2Exception {
|
||||||
// max header table size = MAX_HEADER_TABLE_SIZE + 1
|
// max header table size = MAX_HEADER_TABLE_SIZE + 1
|
||||||
|
assertThrows(Http2Exception.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
decode("3FE21F");
|
decode("3FE21F");
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Test(expected = Http2Exception.class)
|
@Test
|
||||||
public void testInsidiousMaxDynamicTableSize() throws Http2Exception {
|
public void testInsidiousMaxDynamicTableSize() throws Http2Exception {
|
||||||
hpackDecoder.setMaxHeaderTableSize(MAX_VALUE);
|
hpackDecoder.setMaxHeaderTableSize(MAX_VALUE);
|
||||||
// max header table size sign overflow
|
// max header table size sign overflow
|
||||||
|
assertThrows(Http2Exception.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
decode("3FE1FFFFFF07");
|
decode("3FE1FFFFFF07");
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testMaxValidDynamicTableSize() throws Http2Exception {
|
public void testMaxValidDynamicTableSize() throws Http2Exception {
|
||||||
@ -306,19 +371,29 @@ public class HpackDecoderTest {
|
|||||||
decode("2081");
|
decode("2081");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = Http2Exception.class)
|
@Test
|
||||||
public void testTooLargeDynamicTableSizeUpdate() throws Http2Exception {
|
public void testTooLargeDynamicTableSizeUpdate() throws Http2Exception {
|
||||||
hpackDecoder.setMaxHeaderTableSize(0);
|
hpackDecoder.setMaxHeaderTableSize(0);
|
||||||
assertEquals(0, hpackDecoder.getMaxHeaderTableSize());
|
assertEquals(0, hpackDecoder.getMaxHeaderTableSize());
|
||||||
|
assertThrows(Http2Exception.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
decode("21"); // encoder max header table size not small enough
|
decode("21"); // encoder max header table size not small enough
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Test(expected = Http2Exception.class)
|
@Test
|
||||||
public void testMissingDynamicTableSizeUpdate() throws Http2Exception {
|
public void testMissingDynamicTableSizeUpdate() throws Http2Exception {
|
||||||
hpackDecoder.setMaxHeaderTableSize(0);
|
hpackDecoder.setMaxHeaderTableSize(0);
|
||||||
assertEquals(0, hpackDecoder.getMaxHeaderTableSize());
|
assertEquals(0, hpackDecoder.getMaxHeaderTableSize());
|
||||||
|
assertThrows(Http2Exception.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
decode("81");
|
decode("81");
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testLiteralWithIncrementalIndexingWithEmptyName() throws Http2Exception {
|
public void testLiteralWithIncrementalIndexingWithEmptyName() throws Http2Exception {
|
||||||
@ -355,18 +430,23 @@ public class HpackDecoderTest {
|
|||||||
verifyNoMoreInteractions(mockHeaders);
|
verifyNoMoreInteractions(mockHeaders);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = Http2Exception.class)
|
@Test
|
||||||
public void testLiteralWithIncrementalIndexingWithLargeValue() throws Http2Exception {
|
public void testLiteralWithIncrementalIndexingWithLargeValue() throws Http2Exception {
|
||||||
// Ignore header that exceeds max header size
|
// Ignore header that exceeds max header size
|
||||||
StringBuilder sb = new StringBuilder();
|
final StringBuilder sb = new StringBuilder();
|
||||||
sb.append("4004");
|
sb.append("4004");
|
||||||
sb.append(hex("name"));
|
sb.append(hex("name"));
|
||||||
sb.append("7F813F");
|
sb.append("7F813F");
|
||||||
for (int i = 0; i < 8192; i++) {
|
for (int i = 0; i < 8192; i++) {
|
||||||
sb.append("61"); // 'a'
|
sb.append("61"); // 'a'
|
||||||
}
|
}
|
||||||
|
assertThrows(Http2Exception.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
decode(sb.toString());
|
decode(sb.toString());
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testLiteralWithoutIndexingWithEmptyName() throws Http2Exception {
|
public void testLiteralWithoutIndexingWithEmptyName() throws Http2Exception {
|
||||||
@ -374,30 +454,40 @@ public class HpackDecoderTest {
|
|||||||
verify(mockHeaders, times(1)).add(EMPTY_STRING, of("value"));
|
verify(mockHeaders, times(1)).add(EMPTY_STRING, of("value"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = Http2Exception.class)
|
@Test
|
||||||
public void testLiteralWithoutIndexingWithLargeName() throws Http2Exception {
|
public void testLiteralWithoutIndexingWithLargeName() throws Http2Exception {
|
||||||
// Ignore header name that exceeds max header size
|
// Ignore header name that exceeds max header size
|
||||||
StringBuilder sb = new StringBuilder();
|
final StringBuilder sb = new StringBuilder();
|
||||||
sb.append("007F817F");
|
sb.append("007F817F");
|
||||||
for (int i = 0; i < 16384; i++) {
|
for (int i = 0; i < 16384; i++) {
|
||||||
sb.append("61"); // 'a'
|
sb.append("61"); // 'a'
|
||||||
}
|
}
|
||||||
sb.append("00");
|
sb.append("00");
|
||||||
|
assertThrows(Http2Exception.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
decode(sb.toString());
|
decode(sb.toString());
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Test(expected = Http2Exception.class)
|
@Test
|
||||||
public void testLiteralWithoutIndexingWithLargeValue() throws Http2Exception {
|
public void testLiteralWithoutIndexingWithLargeValue() throws Http2Exception {
|
||||||
// Ignore header that exceeds max header size
|
// Ignore header that exceeds max header size
|
||||||
StringBuilder sb = new StringBuilder();
|
final StringBuilder sb = new StringBuilder();
|
||||||
sb.append("0004");
|
sb.append("0004");
|
||||||
sb.append(hex("name"));
|
sb.append(hex("name"));
|
||||||
sb.append("7F813F");
|
sb.append("7F813F");
|
||||||
for (int i = 0; i < 8192; i++) {
|
for (int i = 0; i < 8192; i++) {
|
||||||
sb.append("61"); // 'a'
|
sb.append("61"); // 'a'
|
||||||
}
|
}
|
||||||
|
assertThrows(Http2Exception.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
decode(sb.toString());
|
decode(sb.toString());
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testLiteralNeverIndexedWithEmptyName() throws Http2Exception {
|
public void testLiteralNeverIndexedWithEmptyName() throws Http2Exception {
|
||||||
@ -405,34 +495,44 @@ public class HpackDecoderTest {
|
|||||||
verify(mockHeaders, times(1)).add(EMPTY_STRING, of("value"));
|
verify(mockHeaders, times(1)).add(EMPTY_STRING, of("value"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = Http2Exception.class)
|
@Test
|
||||||
public void testLiteralNeverIndexedWithLargeName() throws Http2Exception {
|
public void testLiteralNeverIndexedWithLargeName() throws Http2Exception {
|
||||||
// Ignore header name that exceeds max header size
|
// Ignore header name that exceeds max header size
|
||||||
StringBuilder sb = new StringBuilder();
|
final StringBuilder sb = new StringBuilder();
|
||||||
sb.append("107F817F");
|
sb.append("107F817F");
|
||||||
for (int i = 0; i < 16384; i++) {
|
for (int i = 0; i < 16384; i++) {
|
||||||
sb.append("61"); // 'a'
|
sb.append("61"); // 'a'
|
||||||
}
|
}
|
||||||
sb.append("00");
|
sb.append("00");
|
||||||
|
assertThrows(Http2Exception.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
decode(sb.toString());
|
decode(sb.toString());
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Test(expected = Http2Exception.class)
|
@Test
|
||||||
public void testLiteralNeverIndexedWithLargeValue() throws Http2Exception {
|
public void testLiteralNeverIndexedWithLargeValue() throws Http2Exception {
|
||||||
// Ignore header that exceeds max header size
|
// Ignore header that exceeds max header size
|
||||||
StringBuilder sb = new StringBuilder();
|
final StringBuilder sb = new StringBuilder();
|
||||||
sb.append("1004");
|
sb.append("1004");
|
||||||
sb.append(hex("name"));
|
sb.append(hex("name"));
|
||||||
sb.append("7F813F");
|
sb.append("7F813F");
|
||||||
for (int i = 0; i < 8192; i++) {
|
for (int i = 0; i < 8192; i++) {
|
||||||
sb.append("61"); // 'a'
|
sb.append("61"); // 'a'
|
||||||
}
|
}
|
||||||
|
assertThrows(Http2Exception.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
decode(sb.toString());
|
decode(sb.toString());
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDecodeLargerThanMaxHeaderListSizeUpdatesDynamicTable() throws Http2Exception {
|
public void testDecodeLargerThanMaxHeaderListSizeUpdatesDynamicTable() throws Http2Exception {
|
||||||
ByteBuf in = Unpooled.buffer(300);
|
final ByteBuf in = Unpooled.buffer(300);
|
||||||
try {
|
try {
|
||||||
hpackDecoder.setMaxHeaderListSize(200);
|
hpackDecoder.setMaxHeaderListSize(200);
|
||||||
HpackEncoder hpackEncoder = new HpackEncoder(true);
|
HpackEncoder hpackEncoder = new HpackEncoder(true);
|
||||||
@ -446,13 +546,13 @@ public class HpackDecoderTest {
|
|||||||
hpackEncoder.encodeHeaders(1, in, toEncode, NEVER_SENSITIVE);
|
hpackEncoder.encodeHeaders(1, in, toEncode, NEVER_SENSITIVE);
|
||||||
|
|
||||||
// decode the headers, we should get an exception
|
// decode the headers, we should get an exception
|
||||||
Http2Headers decoded = new DefaultHttp2Headers();
|
final Http2Headers decoded = new DefaultHttp2Headers();
|
||||||
try {
|
assertThrows(Http2Exception.HeaderListSizeException.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
hpackDecoder.decode(1, in, decoded, true);
|
hpackDecoder.decode(1, in, decoded, true);
|
||||||
fail();
|
|
||||||
} catch (Http2Exception e) {
|
|
||||||
assertTrue(e instanceof Http2Exception.HeaderListSizeException);
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// but the dynamic table should have been updated, so that later blocks
|
// but the dynamic table should have been updated, so that later blocks
|
||||||
// can refer to earlier headers
|
// can refer to earlier headers
|
||||||
@ -494,7 +594,7 @@ public class HpackDecoderTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAccountForHeaderOverhead() throws Exception {
|
public void testAccountForHeaderOverhead() throws Exception {
|
||||||
ByteBuf in = Unpooled.buffer(100);
|
final ByteBuf in = Unpooled.buffer(100);
|
||||||
try {
|
try {
|
||||||
String headerName = "12345";
|
String headerName = "12345";
|
||||||
String headerValue = "56789";
|
String headerValue = "56789";
|
||||||
@ -506,14 +606,18 @@ public class HpackDecoderTest {
|
|||||||
toEncode.add(headerName, headerValue);
|
toEncode.add(headerName, headerValue);
|
||||||
hpackEncoder.encodeHeaders(1, in, toEncode, NEVER_SENSITIVE);
|
hpackEncoder.encodeHeaders(1, in, toEncode, NEVER_SENSITIVE);
|
||||||
|
|
||||||
Http2Headers decoded = new DefaultHttp2Headers();
|
final Http2Headers decoded = new DefaultHttp2Headers();
|
||||||
|
|
||||||
// SETTINGS_MAX_HEADER_LIST_SIZE is big enough for the header to fit...
|
// SETTINGS_MAX_HEADER_LIST_SIZE is big enough for the header to fit...
|
||||||
assertThat(hpackDecoder.getMaxHeaderListSize(), is(greaterThanOrEqualTo(headerSize)));
|
assertThat(hpackDecoder.getMaxHeaderListSize(), is(greaterThanOrEqualTo(headerSize)));
|
||||||
|
|
||||||
// ... but decode should fail because we add some overhead for each header entry
|
// ... but decode should fail because we add some overhead for each header entry
|
||||||
expectedException.expect(Http2Exception.HeaderListSizeException.class);
|
assertThrows(Http2Exception.HeaderListSizeException.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
hpackDecoder.decode(1, in, decoded, true);
|
hpackDecoder.decode(1, in, decoded, true);
|
||||||
|
}
|
||||||
|
});
|
||||||
} finally {
|
} finally {
|
||||||
in.release();
|
in.release();
|
||||||
}
|
}
|
||||||
@ -523,10 +627,14 @@ public class HpackDecoderTest {
|
|||||||
public void testIncompleteHeaderFieldRepresentation() throws Http2Exception {
|
public void testIncompleteHeaderFieldRepresentation() throws Http2Exception {
|
||||||
// Incomplete Literal Header Field with Incremental Indexing
|
// Incomplete Literal Header Field with Incremental Indexing
|
||||||
byte[] input = {(byte) 0x40};
|
byte[] input = {(byte) 0x40};
|
||||||
ByteBuf in = Unpooled.wrappedBuffer(input);
|
final ByteBuf in = Unpooled.wrappedBuffer(input);
|
||||||
try {
|
try {
|
||||||
expectedException.expect(Http2Exception.class);
|
assertThrows(Http2Exception.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
hpackDecoder.decode(0, in, mockHeaders, true);
|
hpackDecoder.decode(0, in, mockHeaders, true);
|
||||||
|
}
|
||||||
|
});
|
||||||
} finally {
|
} finally {
|
||||||
in.release();
|
in.release();
|
||||||
}
|
}
|
||||||
@ -534,7 +642,7 @@ public class HpackDecoderTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void unknownPseudoHeader() throws Exception {
|
public void unknownPseudoHeader() throws Exception {
|
||||||
ByteBuf in = Unpooled.buffer(200);
|
final ByteBuf in = Unpooled.buffer(200);
|
||||||
try {
|
try {
|
||||||
HpackEncoder hpackEncoder = new HpackEncoder(true);
|
HpackEncoder hpackEncoder = new HpackEncoder(true);
|
||||||
|
|
||||||
@ -542,10 +650,14 @@ public class HpackDecoderTest {
|
|||||||
toEncode.add(":test", "1");
|
toEncode.add(":test", "1");
|
||||||
hpackEncoder.encodeHeaders(1, in, toEncode, NEVER_SENSITIVE);
|
hpackEncoder.encodeHeaders(1, in, toEncode, NEVER_SENSITIVE);
|
||||||
|
|
||||||
Http2Headers decoded = new DefaultHttp2Headers();
|
final Http2Headers decoded = new DefaultHttp2Headers();
|
||||||
|
|
||||||
expectedException.expect(Http2Exception.StreamException.class);
|
assertThrows(Http2Exception.StreamException.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
hpackDecoder.decode(1, in, decoded, true);
|
hpackDecoder.decode(1, in, decoded, true);
|
||||||
|
}
|
||||||
|
});
|
||||||
} finally {
|
} finally {
|
||||||
in.release();
|
in.release();
|
||||||
}
|
}
|
||||||
@ -577,7 +689,7 @@ public class HpackDecoderTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void requestPseudoHeaderInResponse() throws Exception {
|
public void requestPseudoHeaderInResponse() throws Exception {
|
||||||
ByteBuf in = Unpooled.buffer(200);
|
final ByteBuf in = Unpooled.buffer(200);
|
||||||
try {
|
try {
|
||||||
HpackEncoder hpackEncoder = new HpackEncoder(true);
|
HpackEncoder hpackEncoder = new HpackEncoder(true);
|
||||||
|
|
||||||
@ -586,10 +698,14 @@ public class HpackDecoderTest {
|
|||||||
toEncode.add(":method", "GET");
|
toEncode.add(":method", "GET");
|
||||||
hpackEncoder.encodeHeaders(1, in, toEncode, NEVER_SENSITIVE);
|
hpackEncoder.encodeHeaders(1, in, toEncode, NEVER_SENSITIVE);
|
||||||
|
|
||||||
Http2Headers decoded = new DefaultHttp2Headers();
|
final Http2Headers decoded = new DefaultHttp2Headers();
|
||||||
|
|
||||||
expectedException.expect(Http2Exception.StreamException.class);
|
assertThrows(Http2Exception.StreamException.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
hpackDecoder.decode(1, in, decoded, true);
|
hpackDecoder.decode(1, in, decoded, true);
|
||||||
|
}
|
||||||
|
});
|
||||||
} finally {
|
} finally {
|
||||||
in.release();
|
in.release();
|
||||||
}
|
}
|
||||||
@ -597,7 +713,7 @@ public class HpackDecoderTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void responsePseudoHeaderInRequest() throws Exception {
|
public void responsePseudoHeaderInRequest() throws Exception {
|
||||||
ByteBuf in = Unpooled.buffer(200);
|
final ByteBuf in = Unpooled.buffer(200);
|
||||||
try {
|
try {
|
||||||
HpackEncoder hpackEncoder = new HpackEncoder(true);
|
HpackEncoder hpackEncoder = new HpackEncoder(true);
|
||||||
|
|
||||||
@ -606,10 +722,14 @@ public class HpackDecoderTest {
|
|||||||
toEncode.add(":status", "200");
|
toEncode.add(":status", "200");
|
||||||
hpackEncoder.encodeHeaders(1, in, toEncode, NEVER_SENSITIVE);
|
hpackEncoder.encodeHeaders(1, in, toEncode, NEVER_SENSITIVE);
|
||||||
|
|
||||||
Http2Headers decoded = new DefaultHttp2Headers();
|
final Http2Headers decoded = new DefaultHttp2Headers();
|
||||||
|
|
||||||
expectedException.expect(Http2Exception.StreamException.class);
|
assertThrows(Http2Exception.StreamException.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
hpackDecoder.decode(1, in, decoded, true);
|
hpackDecoder.decode(1, in, decoded, true);
|
||||||
|
}
|
||||||
|
});
|
||||||
} finally {
|
} finally {
|
||||||
in.release();
|
in.release();
|
||||||
}
|
}
|
||||||
@ -617,7 +737,7 @@ public class HpackDecoderTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void pseudoHeaderAfterRegularHeader() throws Exception {
|
public void pseudoHeaderAfterRegularHeader() throws Exception {
|
||||||
ByteBuf in = Unpooled.buffer(200);
|
final ByteBuf in = Unpooled.buffer(200);
|
||||||
try {
|
try {
|
||||||
HpackEncoder hpackEncoder = new HpackEncoder(true);
|
HpackEncoder hpackEncoder = new HpackEncoder(true);
|
||||||
|
|
||||||
@ -626,10 +746,14 @@ public class HpackDecoderTest {
|
|||||||
toEncode.add(":method", "GET");
|
toEncode.add(":method", "GET");
|
||||||
hpackEncoder.encodeHeaders(1, in, toEncode, NEVER_SENSITIVE);
|
hpackEncoder.encodeHeaders(1, in, toEncode, NEVER_SENSITIVE);
|
||||||
|
|
||||||
Http2Headers decoded = new DefaultHttp2Headers();
|
final Http2Headers decoded = new DefaultHttp2Headers();
|
||||||
|
|
||||||
expectedException.expect(Http2Exception.StreamException.class);
|
assertThrows(Http2Exception.StreamException.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
hpackDecoder.decode(1, in, decoded, true);
|
hpackDecoder.decode(1, in, decoded, true);
|
||||||
|
}
|
||||||
|
});
|
||||||
} finally {
|
} finally {
|
||||||
in.release();
|
in.release();
|
||||||
}
|
}
|
||||||
@ -637,7 +761,7 @@ public class HpackDecoderTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void failedValidationDoesntCorruptHpack() throws Exception {
|
public void failedValidationDoesntCorruptHpack() throws Exception {
|
||||||
ByteBuf in1 = Unpooled.buffer(200);
|
final ByteBuf in1 = Unpooled.buffer(200);
|
||||||
ByteBuf in2 = Unpooled.buffer(200);
|
ByteBuf in2 = Unpooled.buffer(200);
|
||||||
try {
|
try {
|
||||||
HpackEncoder hpackEncoder = new HpackEncoder(true);
|
HpackEncoder hpackEncoder = new HpackEncoder(true);
|
||||||
@ -648,14 +772,16 @@ public class HpackDecoderTest {
|
|||||||
toEncode.add("foo", "bar");
|
toEncode.add("foo", "bar");
|
||||||
hpackEncoder.encodeHeaders(1, in1, toEncode, NEVER_SENSITIVE);
|
hpackEncoder.encodeHeaders(1, in1, toEncode, NEVER_SENSITIVE);
|
||||||
|
|
||||||
Http2Headers decoded = new DefaultHttp2Headers();
|
final Http2Headers decoded = new DefaultHttp2Headers();
|
||||||
|
|
||||||
try {
|
Http2Exception.StreamException expected =
|
||||||
|
assertThrows(Http2Exception.StreamException.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
hpackDecoder.decode(1, in1, decoded, true);
|
hpackDecoder.decode(1, in1, decoded, true);
|
||||||
fail("Should have thrown a StreamException");
|
|
||||||
} catch (Http2Exception.StreamException expected) {
|
|
||||||
assertEquals(1, expected.streamId());
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
assertEquals(1, expected.streamId());
|
||||||
|
|
||||||
// Do it again, this time without validation, to make sure the HPACK state is still sane.
|
// Do it again, this time without validation, to make sure the HPACK state is still sane.
|
||||||
decoded.clear();
|
decoded.clear();
|
||||||
|
@ -15,11 +15,12 @@
|
|||||||
|
|
||||||
package io.netty.handler.codec.http2;
|
package io.netty.handler.codec.http2;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import org.junit.jupiter.api.Test;
|
||||||
import static org.junit.Assert.assertNull;
|
import org.junit.jupiter.api.function.Executable;
|
||||||
import static org.junit.Assert.fail;
|
|
||||||
|
|
||||||
import org.junit.Test;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
|
|
||||||
public class HpackDynamicTableTest {
|
public class HpackDynamicTableTest {
|
||||||
|
|
||||||
@ -47,24 +48,30 @@ public class HpackDynamicTableTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetEntry() {
|
public void testGetEntry() {
|
||||||
HpackDynamicTable table = new HpackDynamicTable(100);
|
final HpackDynamicTable table = new HpackDynamicTable(100);
|
||||||
HpackHeaderField entry = new HpackHeaderField("foo", "bar");
|
HpackHeaderField entry = new HpackHeaderField("foo", "bar");
|
||||||
table.add(entry);
|
table.add(entry);
|
||||||
assertEquals(entry, table.getEntry(1));
|
assertEquals(entry, table.getEntry(1));
|
||||||
table.clear();
|
table.clear();
|
||||||
try {
|
|
||||||
|
assertThrows(IndexOutOfBoundsException.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
table.getEntry(1);
|
table.getEntry(1);
|
||||||
fail();
|
|
||||||
} catch (IndexOutOfBoundsException e) {
|
|
||||||
//success
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = IndexOutOfBoundsException.class)
|
@Test
|
||||||
public void testGetEntryExceptionally() {
|
public void testGetEntryExceptionally() {
|
||||||
HpackDynamicTable table = new HpackDynamicTable(1);
|
final HpackDynamicTable table = new HpackDynamicTable(1);
|
||||||
|
assertThrows(IndexOutOfBoundsException.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
table.getEntry(1);
|
table.getEntry(1);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRemove() {
|
public void testRemove() {
|
||||||
|
@ -17,12 +17,15 @@ package io.netty.handler.codec.http2;
|
|||||||
|
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
import org.junit.Before;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.function.Executable;
|
||||||
|
|
||||||
import static io.netty.handler.codec.http2.Http2CodecUtil.DEFAULT_HEADER_LIST_SIZE;
|
import static io.netty.handler.codec.http2.Http2CodecUtil.DEFAULT_HEADER_LIST_SIZE;
|
||||||
import static io.netty.handler.codec.http2.Http2CodecUtil.MAX_HEADER_TABLE_SIZE;
|
import static io.netty.handler.codec.http2.Http2CodecUtil.MAX_HEADER_TABLE_SIZE;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
|
|
||||||
public class HpackEncoderTest {
|
public class HpackEncoderTest {
|
||||||
@ -30,7 +33,7 @@ public class HpackEncoderTest {
|
|||||||
private HpackEncoder hpackEncoder;
|
private HpackEncoder hpackEncoder;
|
||||||
private Http2Headers mockHeaders;
|
private Http2Headers mockHeaders;
|
||||||
|
|
||||||
@Before
|
@BeforeEach
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
hpackEncoder = new HpackEncoder();
|
hpackEncoder = new HpackEncoder();
|
||||||
hpackDecoder = new HpackDecoder(DEFAULT_HEADER_LIST_SIZE);
|
hpackDecoder = new HpackDecoder(DEFAULT_HEADER_LIST_SIZE);
|
||||||
@ -47,11 +50,16 @@ public class HpackEncoderTest {
|
|||||||
buf.release();
|
buf.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = Http2Exception.class)
|
@Test
|
||||||
public void testSetMaxHeaderTableSizeOverflow() throws Http2Exception {
|
public void testSetMaxHeaderTableSizeOverflow() throws Http2Exception {
|
||||||
ByteBuf buf = Unpooled.buffer();
|
final ByteBuf buf = Unpooled.buffer();
|
||||||
try {
|
try {
|
||||||
|
assertThrows(Http2Exception.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
hpackEncoder.setMaxHeaderTableSize(buf, MAX_HEADER_TABLE_SIZE + 1);
|
hpackEncoder.setMaxHeaderTableSize(buf, MAX_HEADER_TABLE_SIZE + 1);
|
||||||
|
}
|
||||||
|
});
|
||||||
} finally {
|
} finally {
|
||||||
buf.release();
|
buf.release();
|
||||||
}
|
}
|
||||||
@ -82,10 +90,10 @@ public class HpackEncoderTest {
|
|||||||
assertEquals(headersOut.get(bigHeaderName).toString(), bigHeaderVal);
|
assertEquals(headersOut.get(bigHeaderName).toString(), bigHeaderVal);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = Http2Exception.class)
|
@Test
|
||||||
public void testSetMaxHeaderListSizeEnforcedAfterSet() throws Http2Exception {
|
public void testSetMaxHeaderListSizeEnforcedAfterSet() throws Http2Exception {
|
||||||
ByteBuf buf = Unpooled.buffer();
|
final ByteBuf buf = Unpooled.buffer();
|
||||||
Http2Headers headers = new DefaultHttp2Headers().add(
|
final Http2Headers headers = new DefaultHttp2Headers().add(
|
||||||
"x-big-header",
|
"x-big-header",
|
||||||
new String(new char[1024 * 16]).replace('\0', 'X')
|
new String(new char[1024 * 16]).replace('\0', 'X')
|
||||||
);
|
);
|
||||||
@ -93,7 +101,12 @@ public class HpackEncoderTest {
|
|||||||
hpackEncoder.setMaxHeaderListSize(1000);
|
hpackEncoder.setMaxHeaderListSize(1000);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
assertThrows(Http2Exception.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
hpackEncoder.encodeHeaders(0, buf, headers, Http2HeadersEncoder.NEVER_SENSITIVE);
|
hpackEncoder.encodeHeaders(0, buf, headers, Http2HeadersEncoder.NEVER_SENSITIVE);
|
||||||
|
}
|
||||||
|
});
|
||||||
} finally {
|
} finally {
|
||||||
buf.release();
|
buf.release();
|
||||||
}
|
}
|
||||||
|
@ -33,43 +33,27 @@ package io.netty.handler.codec.http2;
|
|||||||
|
|
||||||
import io.netty.util.internal.ObjectUtil;
|
import io.netty.util.internal.ObjectUtil;
|
||||||
import io.netty.util.internal.ResourcesUtil;
|
import io.netty.util.internal.ResourcesUtil;
|
||||||
import org.junit.Test;
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.jupiter.params.provider.MethodSource;
|
||||||
import org.junit.runners.Parameterized;
|
|
||||||
import org.junit.runners.Parameterized.Parameters;
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
@RunWith(Parameterized.class)
|
|
||||||
public class HpackTest {
|
public class HpackTest {
|
||||||
|
|
||||||
private static final String TEST_DIR = '/' + HpackTest.class.getPackage().getName().replaceAll("\\.", "/")
|
private static final String TEST_DIR = '/' + HpackTest.class.getPackage().getName().replaceAll("\\.", "/")
|
||||||
+ "/testdata/";
|
+ "/testdata/";
|
||||||
|
|
||||||
private final String fileName;
|
public static File[] files() {
|
||||||
|
|
||||||
public HpackTest(String fileName) {
|
|
||||||
this.fileName = fileName;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Parameters(name = "{0}")
|
|
||||||
public static Collection<Object[]> data() {
|
|
||||||
File[] files = ResourcesUtil.getFile(HpackTest.class, TEST_DIR).listFiles();
|
File[] files = ResourcesUtil.getFile(HpackTest.class, TEST_DIR).listFiles();
|
||||||
ObjectUtil.checkNotNull(files, "files");
|
ObjectUtil.checkNotNull(files, "files");
|
||||||
|
return files;
|
||||||
ArrayList<Object[]> data = new ArrayList<Object[]>();
|
|
||||||
for (File file : files) {
|
|
||||||
data.add(new Object[]{file.getName()});
|
|
||||||
}
|
|
||||||
return data;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@ParameterizedTest(name = "file = {0}")
|
||||||
public void test() throws Exception {
|
@MethodSource("files")
|
||||||
InputStream is = HpackTest.class.getResourceAsStream(TEST_DIR + fileName);
|
public void test(File file) throws Exception {
|
||||||
|
InputStream is = HpackTest.class.getResourceAsStream(TEST_DIR + file.getName());
|
||||||
HpackTestCase hpackTestCase = HpackTestCase.load(is);
|
HpackTestCase hpackTestCase = HpackTestCase.load(is);
|
||||||
hpackTestCase.testCompress();
|
hpackTestCase.testCompress();
|
||||||
hpackTestCase.testDecompress();
|
hpackTestCase.testDecompress();
|
||||||
|
@ -22,13 +22,12 @@ import io.netty.handler.codec.http.DefaultFullHttpRequest;
|
|||||||
import io.netty.handler.codec.http.FullHttpRequest;
|
import io.netty.handler.codec.http.FullHttpRequest;
|
||||||
import io.netty.handler.codec.http.HttpMethod;
|
import io.netty.handler.codec.http.HttpMethod;
|
||||||
import io.netty.handler.codec.http.HttpVersion;
|
import io.netty.handler.codec.http.HttpVersion;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import static org.junit.Assert.assertNotNull;
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
public class Http2ClientUpgradeCodecTest {
|
public class Http2ClientUpgradeCodecTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -35,13 +35,13 @@ import io.netty.util.concurrent.EventExecutor;
|
|||||||
import io.netty.util.concurrent.GenericFutureListener;
|
import io.netty.util.concurrent.GenericFutureListener;
|
||||||
import io.netty.util.concurrent.ImmediateEventExecutor;
|
import io.netty.util.concurrent.ImmediateEventExecutor;
|
||||||
import io.netty.util.concurrent.Promise;
|
import io.netty.util.concurrent.Promise;
|
||||||
import org.junit.After;
|
import org.junit.jupiter.api.AfterEach;
|
||||||
import org.junit.Before;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.function.Executable;
|
||||||
import org.mockito.ArgumentCaptor;
|
import org.mockito.ArgumentCaptor;
|
||||||
import org.mockito.ArgumentMatchers;
|
import org.mockito.ArgumentMatchers;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.Mockito;
|
|
||||||
import org.mockito.MockitoAnnotations;
|
import org.mockito.MockitoAnnotations;
|
||||||
import org.mockito.invocation.InvocationOnMock;
|
import org.mockito.invocation.InvocationOnMock;
|
||||||
import org.mockito.stubbing.Answer;
|
import org.mockito.stubbing.Answer;
|
||||||
@ -50,7 +50,6 @@ import java.util.List;
|
|||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
|
||||||
|
|
||||||
import static io.netty.buffer.Unpooled.copiedBuffer;
|
import static io.netty.buffer.Unpooled.copiedBuffer;
|
||||||
import static io.netty.handler.codec.http2.Http2CodecUtil.connectionPrefaceBuf;
|
import static io.netty.handler.codec.http2.Http2CodecUtil.connectionPrefaceBuf;
|
||||||
@ -63,10 +62,10 @@ import static io.netty.handler.codec.http2.Http2TestUtil.newVoidPromise;
|
|||||||
import static io.netty.util.CharsetUtil.US_ASCII;
|
import static io.netty.util.CharsetUtil.US_ASCII;
|
||||||
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 org.junit.Assert.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
import static org.junit.Assert.fail;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
import static org.mockito.Mockito.any;
|
import static org.mockito.Mockito.any;
|
||||||
import static org.mockito.Mockito.anyBoolean;
|
import static org.mockito.Mockito.anyBoolean;
|
||||||
import static org.mockito.Mockito.anyInt;
|
import static org.mockito.Mockito.anyInt;
|
||||||
@ -143,7 +142,7 @@ public class Http2ConnectionHandlerTest {
|
|||||||
private String goAwayDebugCap;
|
private String goAwayDebugCap;
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@Before
|
@BeforeEach
|
||||||
public void setup() throws Exception {
|
public void setup() throws Exception {
|
||||||
MockitoAnnotations.initMocks(this);
|
MockitoAnnotations.initMocks(this);
|
||||||
|
|
||||||
@ -227,7 +226,7 @@ public class Http2ConnectionHandlerTest {
|
|||||||
return handler;
|
return handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
@After
|
@AfterEach
|
||||||
public void tearDown() throws Exception {
|
public void tearDown() throws Exception {
|
||||||
if (handler != null) {
|
if (handler != null) {
|
||||||
handler.handlerRemoved(ctx);
|
handler.handlerRemoved(ctx);
|
||||||
@ -237,23 +236,25 @@ public class Http2ConnectionHandlerTest {
|
|||||||
@Test
|
@Test
|
||||||
public void onHttpServerUpgradeWithoutHandlerAdded() throws Exception {
|
public void onHttpServerUpgradeWithoutHandlerAdded() throws Exception {
|
||||||
handler = new Http2ConnectionHandlerBuilder().frameListener(new Http2FrameAdapter()).server(true).build();
|
handler = new Http2ConnectionHandlerBuilder().frameListener(new Http2FrameAdapter()).server(true).build();
|
||||||
try {
|
Http2Exception e = assertThrows(Http2Exception.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
handler.onHttpServerUpgrade(new Http2Settings());
|
handler.onHttpServerUpgrade(new Http2Settings());
|
||||||
fail();
|
|
||||||
} catch (Http2Exception e) {
|
|
||||||
assertEquals(Http2Error.INTERNAL_ERROR, e.error());
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
assertEquals(Http2Error.INTERNAL_ERROR, e.error());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void onHttpClientUpgradeWithoutHandlerAdded() throws Exception {
|
public void onHttpClientUpgradeWithoutHandlerAdded() throws Exception {
|
||||||
handler = new Http2ConnectionHandlerBuilder().frameListener(new Http2FrameAdapter()).server(false).build();
|
handler = new Http2ConnectionHandlerBuilder().frameListener(new Http2FrameAdapter()).server(false).build();
|
||||||
try {
|
Http2Exception e = assertThrows(Http2Exception.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
handler.onHttpClientUpgrade();
|
handler.onHttpClientUpgrade();
|
||||||
fail();
|
|
||||||
} catch (Http2Exception e) {
|
|
||||||
assertEquals(Http2Error.INTERNAL_ERROR, e.error());
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
assertEquals(Http2Error.INTERNAL_ERROR, e.error());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -40,9 +40,10 @@ import io.netty.util.AsciiString;
|
|||||||
import io.netty.util.IllegalReferenceCountException;
|
import io.netty.util.IllegalReferenceCountException;
|
||||||
import io.netty.util.ReferenceCountUtil;
|
import io.netty.util.ReferenceCountUtil;
|
||||||
import io.netty.util.concurrent.Future;
|
import io.netty.util.concurrent.Future;
|
||||||
import org.junit.After;
|
import org.junit.jupiter.api.AfterEach;
|
||||||
import org.junit.Before;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.function.Executable;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.MockitoAnnotations;
|
import org.mockito.MockitoAnnotations;
|
||||||
import org.mockito.invocation.InvocationOnMock;
|
import org.mockito.invocation.InvocationOnMock;
|
||||||
@ -69,13 +70,13 @@ import static org.hamcrest.CoreMatchers.instanceOf;
|
|||||||
import static org.hamcrest.CoreMatchers.not;
|
import static org.hamcrest.CoreMatchers.not;
|
||||||
import static org.hamcrest.MatcherAssert.assertThat;
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
import static org.hamcrest.Matchers.is;
|
import static org.hamcrest.Matchers.is;
|
||||||
import static org.junit.Assert.assertArrayEquals;
|
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
import static org.junit.Assert.assertNotNull;
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
import static org.junit.Assert.assertNull;
|
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
import static org.junit.Assert.fail;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
import static org.mockito.Mockito.any;
|
import static org.mockito.Mockito.any;
|
||||||
import static org.mockito.Mockito.anyBoolean;
|
import static org.mockito.Mockito.anyBoolean;
|
||||||
import static org.mockito.Mockito.anyInt;
|
import static org.mockito.Mockito.anyInt;
|
||||||
@ -115,14 +116,14 @@ public class Http2ConnectionRoundtripTest {
|
|||||||
private CountDownLatch trailersLatch;
|
private CountDownLatch trailersLatch;
|
||||||
private CountDownLatch goAwayLatch;
|
private CountDownLatch goAwayLatch;
|
||||||
|
|
||||||
@Before
|
@BeforeEach
|
||||||
public void setup() throws Exception {
|
public void setup() throws Exception {
|
||||||
MockitoAnnotations.initMocks(this);
|
MockitoAnnotations.initMocks(this);
|
||||||
mockFlowControl(clientListener);
|
mockFlowControl(clientListener);
|
||||||
mockFlowControl(serverListener);
|
mockFlowControl(serverListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
@After
|
@AfterEach
|
||||||
public void teardown() throws Exception {
|
public void teardown() throws Exception {
|
||||||
if (clientChannel != null) {
|
if (clientChannel != null) {
|
||||||
clientChannel.close().syncUninterruptibly();
|
clientChannel.close().syncUninterruptibly();
|
||||||
@ -311,8 +312,8 @@ public class Http2ConnectionRoundtripTest {
|
|||||||
});
|
});
|
||||||
|
|
||||||
assertTrue(clientDataWrite.await(DEFAULT_AWAIT_TIMEOUT_SECONDS, SECONDS));
|
assertTrue(clientDataWrite.await(DEFAULT_AWAIT_TIMEOUT_SECONDS, SECONDS));
|
||||||
assertNotNull("Header encode should have exceeded maxHeaderListSize!", clientHeadersWriteException.get());
|
assertNotNull(clientHeadersWriteException.get(), "Header encode should have exceeded maxHeaderListSize!");
|
||||||
assertNotNull("Data on closed stream should fail!", clientDataWriteException.get());
|
assertNotNull(clientDataWriteException.get(), "Data on closed stream should fail!");
|
||||||
|
|
||||||
// Set the maxHeaderListSize to the max value so we can send the headers.
|
// Set the maxHeaderListSize to the max value so we can send the headers.
|
||||||
runInChannel(serverConnectedChannel, new Http2Runnable() {
|
runInChannel(serverConnectedChannel, new Http2Runnable() {
|
||||||
@ -345,8 +346,8 @@ public class Http2ConnectionRoundtripTest {
|
|||||||
});
|
});
|
||||||
|
|
||||||
assertTrue(clientHeadersLatch.await(DEFAULT_AWAIT_TIMEOUT_SECONDS, SECONDS));
|
assertTrue(clientHeadersLatch.await(DEFAULT_AWAIT_TIMEOUT_SECONDS, SECONDS));
|
||||||
assertNull("Client write of headers should succeed with increased header list size!",
|
assertNull(clientHeadersWriteException2.get(),
|
||||||
clientHeadersWriteException2.get());
|
"Client write of headers should succeed with increased header list size!");
|
||||||
assertTrue(serverRevHeadersLatch.await(DEFAULT_AWAIT_TIMEOUT_SECONDS, SECONDS));
|
assertTrue(serverRevHeadersLatch.await(DEFAULT_AWAIT_TIMEOUT_SECONDS, SECONDS));
|
||||||
|
|
||||||
verify(serverListener, never()).onDataRead(any(ChannelHandlerContext.class), anyInt(), any(ByteBuf.class),
|
verify(serverListener, never()).onDataRead(any(ChannelHandlerContext.class), anyInt(), any(ByteBuf.class),
|
||||||
@ -724,12 +725,13 @@ public class Http2ConnectionRoundtripTest {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
try {
|
ExecutionException e = assertThrows(ExecutionException.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
emptyDataPromise.get();
|
emptyDataPromise.get();
|
||||||
fail();
|
|
||||||
} catch (ExecutionException e) {
|
|
||||||
assertThat(e.getCause(), is(instanceOf(IllegalReferenceCountException.class)));
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
assertThat(e.getCause(), is(instanceOf(IllegalReferenceCountException.class)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -775,13 +777,13 @@ public class Http2ConnectionRoundtripTest {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
try {
|
ExecutionException e = assertThrows(ExecutionException.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
dataPromise.get();
|
dataPromise.get();
|
||||||
fail();
|
|
||||||
} catch (ExecutionException e) {
|
|
||||||
assertThat(e.getCause(), is(instanceOf(IllegalStateException.class)));
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
assertThat(e.getCause(), is(instanceOf(IllegalStateException.class)));
|
||||||
assertPromise.sync();
|
assertPromise.sync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,13 +25,12 @@ import io.netty.channel.ChannelMetadata;
|
|||||||
import io.netty.channel.ChannelPromise;
|
import io.netty.channel.ChannelPromise;
|
||||||
import io.netty.channel.DefaultChannelPromise;
|
import io.netty.channel.DefaultChannelPromise;
|
||||||
import io.netty.channel.DefaultMessageSizeEstimator;
|
import io.netty.channel.DefaultMessageSizeEstimator;
|
||||||
import io.netty.handler.codec.http2.Http2Exception.ShutdownHint;
|
|
||||||
import io.netty.util.ReferenceCountUtil;
|
import io.netty.util.ReferenceCountUtil;
|
||||||
import io.netty.util.concurrent.EventExecutor;
|
import io.netty.util.concurrent.EventExecutor;
|
||||||
import io.netty.util.concurrent.ImmediateEventExecutor;
|
import io.netty.util.concurrent.ImmediateEventExecutor;
|
||||||
import org.junit.After;
|
import org.junit.jupiter.api.AfterEach;
|
||||||
import org.junit.Before;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.MockitoAnnotations;
|
import org.mockito.MockitoAnnotations;
|
||||||
import org.mockito.invocation.InvocationOnMock;
|
import org.mockito.invocation.InvocationOnMock;
|
||||||
@ -44,7 +43,9 @@ import java.util.Queue;
|
|||||||
import static io.netty.handler.codec.http2.Http2CodecUtil.*;
|
import static io.netty.handler.codec.http2.Http2CodecUtil.*;
|
||||||
import static io.netty.handler.codec.http2.Http2Error.CANCEL;
|
import static io.netty.handler.codec.http2.Http2Error.CANCEL;
|
||||||
import static io.netty.handler.codec.http2.Http2Error.ENHANCE_YOUR_CALM;
|
import static io.netty.handler.codec.http2.Http2Error.ENHANCE_YOUR_CALM;
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
import static org.mockito.Mockito.*;
|
import static org.mockito.Mockito.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -79,7 +80,7 @@ public class Http2ControlFrameLimitEncoderTest {
|
|||||||
/**
|
/**
|
||||||
* Init fields and do mocking.
|
* Init fields and do mocking.
|
||||||
*/
|
*/
|
||||||
@Before
|
@BeforeEach
|
||||||
public void setup() throws Exception {
|
public void setup() throws Exception {
|
||||||
MockitoAnnotations.initMocks(this);
|
MockitoAnnotations.initMocks(this);
|
||||||
|
|
||||||
@ -171,7 +172,7 @@ public class Http2ControlFrameLimitEncoderTest {
|
|||||||
return promise;
|
return promise;
|
||||||
}
|
}
|
||||||
|
|
||||||
@After
|
@AfterEach
|
||||||
public void teardown() {
|
public void teardown() {
|
||||||
// Close and release any buffered frames.
|
// Close and release any buffered frames.
|
||||||
encoder.close();
|
encoder.close();
|
||||||
|
@ -17,9 +17,9 @@ package io.netty.handler.codec.http2;
|
|||||||
|
|
||||||
import io.netty.buffer.DefaultByteBufHolder;
|
import io.netty.buffer.DefaultByteBufHolder;
|
||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
import org.junit.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
|
|
||||||
public class Http2DefaultFramesTest {
|
public class Http2DefaultFramesTest {
|
||||||
|
|
||||||
|
@ -15,13 +15,13 @@
|
|||||||
package io.netty.handler.codec.http2;
|
package io.netty.handler.codec.http2;
|
||||||
|
|
||||||
import org.hamcrest.CoreMatchers;
|
import org.hamcrest.CoreMatchers;
|
||||||
import org.junit.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.mockito.ArgumentCaptor;
|
import org.mockito.ArgumentCaptor;
|
||||||
import org.mockito.invocation.InvocationOnMock;
|
import org.mockito.invocation.InvocationOnMock;
|
||||||
import org.mockito.stubbing.Answer;
|
import org.mockito.stubbing.Answer;
|
||||||
|
|
||||||
import static org.hamcrest.MatcherAssert.assertThat;
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
import static org.junit.Assert.assertNull;
|
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
@ -17,11 +17,12 @@ package io.netty.handler.codec.http2;
|
|||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
import org.junit.Before;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.function.Executable;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
|
|
||||||
import static org.junit.Assert.fail;
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
import static org.mockito.Mockito.any;
|
import static org.mockito.Mockito.any;
|
||||||
import static org.mockito.Mockito.eq;
|
import static org.mockito.Mockito.eq;
|
||||||
import static org.mockito.Mockito.times;
|
import static org.mockito.Mockito.times;
|
||||||
@ -41,7 +42,7 @@ public class Http2EmptyDataFrameListenerTest {
|
|||||||
|
|
||||||
private Http2EmptyDataFrameListener listener;
|
private Http2EmptyDataFrameListener listener;
|
||||||
|
|
||||||
@Before
|
@BeforeEach
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
initMocks(this);
|
initMocks(this);
|
||||||
when(nonEmpty.isReadable()).thenReturn(true);
|
when(nonEmpty.isReadable()).thenReturn(true);
|
||||||
@ -53,67 +54,68 @@ public class Http2EmptyDataFrameListenerTest {
|
|||||||
listener.onDataRead(ctx, 1, Unpooled.EMPTY_BUFFER, 0, false);
|
listener.onDataRead(ctx, 1, Unpooled.EMPTY_BUFFER, 0, false);
|
||||||
listener.onDataRead(ctx, 1, Unpooled.EMPTY_BUFFER, 0, false);
|
listener.onDataRead(ctx, 1, Unpooled.EMPTY_BUFFER, 0, false);
|
||||||
|
|
||||||
try {
|
assertThrows(Http2Exception.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
listener.onDataRead(ctx, 1, Unpooled.EMPTY_BUFFER, 0, false);
|
listener.onDataRead(ctx, 1, Unpooled.EMPTY_BUFFER, 0, false);
|
||||||
fail();
|
|
||||||
} catch (Http2Exception expected) {
|
|
||||||
// expected
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
verify(frameListener, times(2)).onDataRead(eq(ctx), eq(1), any(ByteBuf.class), eq(0), eq(false));
|
verify(frameListener, times(2)).onDataRead(eq(ctx), eq(1), any(ByteBuf.class), eq(0), eq(false));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testEmptyDataFramesWithNonEmptyInBetween() throws Http2Exception {
|
public void testEmptyDataFramesWithNonEmptyInBetween() throws Http2Exception {
|
||||||
Http2EmptyDataFrameListener listener = new Http2EmptyDataFrameListener(frameListener, 2);
|
final Http2EmptyDataFrameListener listener = new Http2EmptyDataFrameListener(frameListener, 2);
|
||||||
listener.onDataRead(ctx, 1, Unpooled.EMPTY_BUFFER, 0, false);
|
listener.onDataRead(ctx, 1, Unpooled.EMPTY_BUFFER, 0, false);
|
||||||
listener.onDataRead(ctx, 1, nonEmpty, 0, false);
|
listener.onDataRead(ctx, 1, nonEmpty, 0, false);
|
||||||
|
|
||||||
listener.onDataRead(ctx, 1, Unpooled.EMPTY_BUFFER, 0, false);
|
listener.onDataRead(ctx, 1, Unpooled.EMPTY_BUFFER, 0, false);
|
||||||
listener.onDataRead(ctx, 1, Unpooled.EMPTY_BUFFER, 0, false);
|
listener.onDataRead(ctx, 1, Unpooled.EMPTY_BUFFER, 0, false);
|
||||||
|
|
||||||
try {
|
assertThrows(Http2Exception.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
listener.onDataRead(ctx, 1, Unpooled.EMPTY_BUFFER, 0, false);
|
listener.onDataRead(ctx, 1, Unpooled.EMPTY_BUFFER, 0, false);
|
||||||
fail();
|
|
||||||
} catch (Http2Exception expected) {
|
|
||||||
// expected
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
verify(frameListener, times(4)).onDataRead(eq(ctx), eq(1), any(ByteBuf.class), eq(0), eq(false));
|
verify(frameListener, times(4)).onDataRead(eq(ctx), eq(1), any(ByteBuf.class), eq(0), eq(false));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testEmptyDataFramesWithEndOfStreamInBetween() throws Http2Exception {
|
public void testEmptyDataFramesWithEndOfStreamInBetween() throws Http2Exception {
|
||||||
Http2EmptyDataFrameListener listener = new Http2EmptyDataFrameListener(frameListener, 2);
|
final Http2EmptyDataFrameListener listener = new Http2EmptyDataFrameListener(frameListener, 2);
|
||||||
listener.onDataRead(ctx, 1, Unpooled.EMPTY_BUFFER, 0, false);
|
listener.onDataRead(ctx, 1, Unpooled.EMPTY_BUFFER, 0, false);
|
||||||
listener.onDataRead(ctx, 1, Unpooled.EMPTY_BUFFER, 0, true);
|
listener.onDataRead(ctx, 1, Unpooled.EMPTY_BUFFER, 0, true);
|
||||||
|
|
||||||
listener.onDataRead(ctx, 1, Unpooled.EMPTY_BUFFER, 0, false);
|
listener.onDataRead(ctx, 1, Unpooled.EMPTY_BUFFER, 0, false);
|
||||||
listener.onDataRead(ctx, 1, Unpooled.EMPTY_BUFFER, 0, false);
|
listener.onDataRead(ctx, 1, Unpooled.EMPTY_BUFFER, 0, false);
|
||||||
|
|
||||||
try {
|
assertThrows(Http2Exception.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
listener.onDataRead(ctx, 1, Unpooled.EMPTY_BUFFER, 0, false);
|
listener.onDataRead(ctx, 1, Unpooled.EMPTY_BUFFER, 0, false);
|
||||||
fail();
|
|
||||||
} catch (Http2Exception expected) {
|
|
||||||
// expected
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
verify(frameListener, times(1)).onDataRead(eq(ctx), eq(1), any(ByteBuf.class), eq(0), eq(true));
|
verify(frameListener, times(1)).onDataRead(eq(ctx), eq(1), any(ByteBuf.class), eq(0), eq(true));
|
||||||
verify(frameListener, times(3)).onDataRead(eq(ctx), eq(1), any(ByteBuf.class), eq(0), eq(false));
|
verify(frameListener, times(3)).onDataRead(eq(ctx), eq(1), any(ByteBuf.class), eq(0), eq(false));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testEmptyDataFramesWithHeaderFrameInBetween() throws Http2Exception {
|
public void testEmptyDataFramesWithHeaderFrameInBetween() throws Http2Exception {
|
||||||
Http2EmptyDataFrameListener listener = new Http2EmptyDataFrameListener(frameListener, 2);
|
final Http2EmptyDataFrameListener listener = new Http2EmptyDataFrameListener(frameListener, 2);
|
||||||
listener.onDataRead(ctx, 1, Unpooled.EMPTY_BUFFER, 0, false);
|
listener.onDataRead(ctx, 1, Unpooled.EMPTY_BUFFER, 0, false);
|
||||||
listener.onHeadersRead(ctx, 1, EmptyHttp2Headers.INSTANCE, 0, true);
|
listener.onHeadersRead(ctx, 1, EmptyHttp2Headers.INSTANCE, 0, true);
|
||||||
|
|
||||||
listener.onDataRead(ctx, 1, Unpooled.EMPTY_BUFFER, 0, false);
|
listener.onDataRead(ctx, 1, Unpooled.EMPTY_BUFFER, 0, false);
|
||||||
listener.onDataRead(ctx, 1, Unpooled.EMPTY_BUFFER, 0, false);
|
listener.onDataRead(ctx, 1, Unpooled.EMPTY_BUFFER, 0, false);
|
||||||
|
|
||||||
try {
|
assertThrows(Http2Exception.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
listener.onDataRead(ctx, 1, Unpooled.EMPTY_BUFFER, 0, false);
|
listener.onDataRead(ctx, 1, Unpooled.EMPTY_BUFFER, 0, false);
|
||||||
fail();
|
|
||||||
} catch (Http2Exception expected) {
|
|
||||||
// expected
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
verify(frameListener, times(1)).onHeadersRead(eq(ctx), eq(1), eq(EmptyHttp2Headers.INSTANCE), eq(0), eq(true));
|
verify(frameListener, times(1)).onHeadersRead(eq(ctx), eq(1), eq(EmptyHttp2Headers.INSTANCE), eq(0), eq(true));
|
||||||
verify(frameListener, times(3)).onDataRead(eq(ctx), eq(1), any(ByteBuf.class), eq(0), eq(false));
|
verify(frameListener, times(3)).onDataRead(eq(ctx), eq(1), any(ByteBuf.class), eq(0), eq(false));
|
||||||
@ -121,19 +123,19 @@ public class Http2EmptyDataFrameListenerTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testEmptyDataFramesWithHeaderFrameInBetween2() throws Http2Exception {
|
public void testEmptyDataFramesWithHeaderFrameInBetween2() throws Http2Exception {
|
||||||
Http2EmptyDataFrameListener listener = new Http2EmptyDataFrameListener(frameListener, 2);
|
final Http2EmptyDataFrameListener listener = new Http2EmptyDataFrameListener(frameListener, 2);
|
||||||
listener.onDataRead(ctx, 1, Unpooled.EMPTY_BUFFER, 0, false);
|
listener.onDataRead(ctx, 1, Unpooled.EMPTY_BUFFER, 0, false);
|
||||||
listener.onHeadersRead(ctx, 1, EmptyHttp2Headers.INSTANCE, 0, (short) 0, false, 0, true);
|
listener.onHeadersRead(ctx, 1, EmptyHttp2Headers.INSTANCE, 0, (short) 0, false, 0, true);
|
||||||
|
|
||||||
listener.onDataRead(ctx, 1, Unpooled.EMPTY_BUFFER, 0, false);
|
listener.onDataRead(ctx, 1, Unpooled.EMPTY_BUFFER, 0, false);
|
||||||
listener.onDataRead(ctx, 1, Unpooled.EMPTY_BUFFER, 0, false);
|
listener.onDataRead(ctx, 1, Unpooled.EMPTY_BUFFER, 0, false);
|
||||||
|
|
||||||
try {
|
assertThrows(Http2Exception.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
listener.onDataRead(ctx, 1, Unpooled.EMPTY_BUFFER, 0, false);
|
listener.onDataRead(ctx, 1, Unpooled.EMPTY_BUFFER, 0, false);
|
||||||
fail();
|
|
||||||
} catch (Http2Exception expected) {
|
|
||||||
// expected
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
verify(frameListener, times(1)).onHeadersRead(eq(ctx), eq(1),
|
verify(frameListener, times(1)).onHeadersRead(eq(ctx), eq(1),
|
||||||
eq(EmptyHttp2Headers.INSTANCE), eq(0), eq((short) 0), eq(false), eq(0), eq(true));
|
eq(EmptyHttp2Headers.INSTANCE), eq(0), eq((short) 0), eq(false), eq(0), eq(true));
|
||||||
|
@ -42,16 +42,19 @@ import io.netty.util.concurrent.DefaultPromise;
|
|||||||
import io.netty.util.concurrent.GlobalEventExecutor;
|
import io.netty.util.concurrent.GlobalEventExecutor;
|
||||||
import io.netty.util.concurrent.Promise;
|
import io.netty.util.concurrent.Promise;
|
||||||
import io.netty.util.internal.ReflectionUtil;
|
import io.netty.util.internal.ReflectionUtil;
|
||||||
import org.junit.After;
|
import org.junit.jupiter.api.AfterEach;
|
||||||
import org.junit.Assume;
|
import org.junit.jupiter.api.Assumptions;
|
||||||
import org.junit.Before;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.Timeout;
|
||||||
|
import org.junit.jupiter.api.function.Executable;
|
||||||
import org.mockito.ArgumentCaptor;
|
import org.mockito.ArgumentCaptor;
|
||||||
|
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
import static io.netty.handler.codec.http2.Http2CodecUtil.isStreamIdValid;
|
import static io.netty.handler.codec.http2.Http2CodecUtil.isStreamIdValid;
|
||||||
@ -62,12 +65,12 @@ import static io.netty.handler.codec.http2.Http2TestUtil.assertEqualsAndRelease;
|
|||||||
import static io.netty.handler.codec.http2.Http2TestUtil.bb;
|
import static io.netty.handler.codec.http2.Http2TestUtil.bb;
|
||||||
import static org.hamcrest.MatcherAssert.assertThat;
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
import static org.hamcrest.Matchers.instanceOf;
|
import static org.hamcrest.Matchers.instanceOf;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
import static org.junit.Assert.assertNotNull;
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
import static org.junit.Assert.assertNull;
|
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
import static org.junit.Assert.fail;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
import static org.mockito.Mockito.any;
|
import static org.mockito.Mockito.any;
|
||||||
import static org.mockito.Mockito.anyInt;
|
import static org.mockito.Mockito.anyInt;
|
||||||
import static org.mockito.Mockito.anyLong;
|
import static org.mockito.Mockito.anyLong;
|
||||||
@ -98,12 +101,12 @@ public class Http2FrameCodecTest {
|
|||||||
private final Http2Headers response = new DefaultHttp2Headers()
|
private final Http2Headers response = new DefaultHttp2Headers()
|
||||||
.status(HttpResponseStatus.OK.codeAsText());
|
.status(HttpResponseStatus.OK.codeAsText());
|
||||||
|
|
||||||
@Before
|
@BeforeEach
|
||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
setUp(Http2FrameCodecBuilder.forServer(), new Http2Settings());
|
setUp(Http2FrameCodecBuilder.forServer(), new Http2Settings());
|
||||||
}
|
}
|
||||||
|
|
||||||
@After
|
@AfterEach
|
||||||
public void tearDown() throws Exception {
|
public void tearDown() throws Exception {
|
||||||
if (inboundHandler != null) {
|
if (inboundHandler != null) {
|
||||||
inboundHandler.finishAndReleaseAll();
|
inboundHandler.finishAndReleaseAll();
|
||||||
@ -425,12 +428,13 @@ public class Http2FrameCodecTest {
|
|||||||
Http2HeadersFrame headersFrame = inboundHandler.readInboundMessageOrUserEvent();
|
Http2HeadersFrame headersFrame = inboundHandler.readInboundMessageOrUserEvent();
|
||||||
assertNotNull(headersFrame);
|
assertNotNull(headersFrame);
|
||||||
|
|
||||||
try {
|
Http2FrameStreamException e = assertThrows(Http2FrameStreamException.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
inboundHandler.checkException();
|
inboundHandler.checkException();
|
||||||
fail("stream exception expected");
|
|
||||||
} catch (Http2FrameStreamException e) {
|
|
||||||
assertEquals(streamEx, e.getCause());
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
assertEquals(streamEx, e.getCause());
|
||||||
|
|
||||||
assertNull(inboundHandler.readInboundMessageOrUserEvent());
|
assertNull(inboundHandler.readInboundMessageOrUserEvent());
|
||||||
}
|
}
|
||||||
@ -576,7 +580,8 @@ public class Http2FrameCodecTest {
|
|||||||
verify(frameWriter).writeSettings(eqFrameCodecCtx(), same(settings), any(ChannelPromise.class));
|
verify(frameWriter).writeSettings(eqFrameCodecCtx(), same(settings), any(ChannelPromise.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(timeout = 5000)
|
@Test
|
||||||
|
@Timeout(value = 5000, unit = TimeUnit.MILLISECONDS)
|
||||||
public void newOutboundStream() {
|
public void newOutboundStream() {
|
||||||
final Http2FrameStream stream = frameCodec.newStream();
|
final Http2FrameStream stream = frameCodec.newStream();
|
||||||
|
|
||||||
@ -847,7 +852,7 @@ public class Http2FrameCodecTest {
|
|||||||
UpgradeEvent.class.getDeclaredConstructor(CharSequence.class, FullHttpRequest.class);
|
UpgradeEvent.class.getDeclaredConstructor(CharSequence.class, FullHttpRequest.class);
|
||||||
|
|
||||||
// Check if we could make it accessible which may fail on java9.
|
// Check if we could make it accessible which may fail on java9.
|
||||||
Assume.assumeTrue(ReflectionUtil.trySetAccessible(constructor, true) == null);
|
Assumptions.assumeTrue(ReflectionUtil.trySetAccessible(constructor, true) == null);
|
||||||
|
|
||||||
HttpServerUpgradeHandler.UpgradeEvent upgradeEvent = constructor.newInstance(
|
HttpServerUpgradeHandler.UpgradeEvent upgradeEvent = constructor.newInstance(
|
||||||
"HTTP/2", new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "/"));
|
"HTTP/2", new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "/"));
|
||||||
@ -885,7 +890,7 @@ public class Http2FrameCodecTest {
|
|||||||
UpgradeEvent.class.getDeclaredConstructor(CharSequence.class, FullHttpRequest.class);
|
UpgradeEvent.class.getDeclaredConstructor(CharSequence.class, FullHttpRequest.class);
|
||||||
|
|
||||||
// Check if we could make it accessible which may fail on java9.
|
// Check if we could make it accessible which may fail on java9.
|
||||||
Assume.assumeTrue(ReflectionUtil.trySetAccessible(constructor, true) == null);
|
Assumptions.assumeTrue(ReflectionUtil.trySetAccessible(constructor, true) == null);
|
||||||
|
|
||||||
String longString = new String(new char[70000]).replace("\0", "*");
|
String longString = new String(new char[70000]).replace("\0", "*");
|
||||||
DefaultFullHttpRequest request =
|
DefaultFullHttpRequest request =
|
||||||
|
@ -27,9 +27,10 @@ import io.netty.channel.DefaultChannelPromise;
|
|||||||
import io.netty.util.AsciiString;
|
import io.netty.util.AsciiString;
|
||||||
import io.netty.util.concurrent.EventExecutor;
|
import io.netty.util.concurrent.EventExecutor;
|
||||||
import io.netty.util.concurrent.GlobalEventExecutor;
|
import io.netty.util.concurrent.GlobalEventExecutor;
|
||||||
import org.junit.After;
|
import org.junit.jupiter.api.AfterEach;
|
||||||
import org.junit.Before;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.function.Executable;
|
||||||
import org.mockito.ArgumentCaptor;
|
import org.mockito.ArgumentCaptor;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.MockitoAnnotations;
|
import org.mockito.MockitoAnnotations;
|
||||||
@ -47,9 +48,9 @@ import static io.netty.handler.codec.http2.Http2TestUtil.newTestEncoder;
|
|||||||
import static io.netty.handler.codec.http2.Http2TestUtil.randomString;
|
import static io.netty.handler.codec.http2.Http2TestUtil.randomString;
|
||||||
import static io.netty.util.CharsetUtil.UTF_8;
|
import static io.netty.util.CharsetUtil.UTF_8;
|
||||||
import static java.lang.Math.min;
|
import static java.lang.Math.min;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
import static org.junit.Assert.fail;
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
import static org.mockito.Mockito.any;
|
import static org.mockito.Mockito.any;
|
||||||
import static org.mockito.Mockito.anyBoolean;
|
import static org.mockito.Mockito.anyBoolean;
|
||||||
import static org.mockito.Mockito.anyInt;
|
import static org.mockito.Mockito.anyInt;
|
||||||
@ -90,7 +91,7 @@ public class Http2FrameRoundtripTest {
|
|||||||
private Http2FrameReader reader;
|
private Http2FrameReader reader;
|
||||||
private final List<ByteBuf> needReleasing = new LinkedList<ByteBuf>();
|
private final List<ByteBuf> needReleasing = new LinkedList<ByteBuf>();
|
||||||
|
|
||||||
@Before
|
@BeforeEach
|
||||||
public void setup() throws Exception {
|
public void setup() throws Exception {
|
||||||
MockitoAnnotations.initMocks(this);
|
MockitoAnnotations.initMocks(this);
|
||||||
|
|
||||||
@ -120,7 +121,7 @@ public class Http2FrameRoundtripTest {
|
|||||||
reader = new DefaultHttp2FrameReader(new DefaultHttp2HeadersDecoder(false, newTestDecoder()));
|
reader = new DefaultHttp2FrameReader(new DefaultHttp2HeadersDecoder(false, newTestDecoder()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@After
|
@AfterEach
|
||||||
public void teardown() {
|
public void teardown() {
|
||||||
try {
|
try {
|
||||||
// Release all of the buffers.
|
// Release all of the buffers.
|
||||||
@ -286,15 +287,16 @@ public class Http2FrameRoundtripTest {
|
|||||||
reader.configuration().headersConfiguration().maxHeaderListSize(maxListSize, maxListSize);
|
reader.configuration().headersConfiguration().maxHeaderListSize(maxListSize, maxListSize);
|
||||||
final Http2Headers headers = headersOfSize(maxListSize + 1);
|
final Http2Headers headers = headersOfSize(maxListSize + 1);
|
||||||
writer.writeHeaders(ctx, STREAM_ID, headers, 2, (short) 3, true, MAX_PADDING, true, ctx.newPromise());
|
writer.writeHeaders(ctx, STREAM_ID, headers, 2, (short) 3, true, MAX_PADDING, true, ctx.newPromise());
|
||||||
try {
|
assertThrows(Http2Exception.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
readFrames();
|
readFrames();
|
||||||
fail();
|
}
|
||||||
} catch (Http2Exception e) {
|
});
|
||||||
verify(listener, never()).onHeadersRead(any(ChannelHandlerContext.class), anyInt(),
|
verify(listener, never()).onHeadersRead(any(ChannelHandlerContext.class), anyInt(),
|
||||||
any(Http2Headers.class), anyInt(), anyShort(), anyBoolean(), anyInt(),
|
any(Http2Headers.class), anyInt(), anyShort(), anyBoolean(), anyInt(),
|
||||||
anyBoolean());
|
anyBoolean());
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void emptyPushPromiseShouldMatch() throws Exception {
|
public void emptyPushPromiseShouldMatch() throws Exception {
|
||||||
|
@ -18,12 +18,12 @@ package io.netty.handler.codec.http2;
|
|||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
import io.netty.util.AsciiString;
|
import io.netty.util.AsciiString;
|
||||||
import org.junit.After;
|
import org.junit.jupiter.api.AfterEach;
|
||||||
import org.junit.Before;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import static io.netty.handler.codec.http2.Http2TestUtil.randomString;
|
import static io.netty.handler.codec.http2.Http2TestUtil.randomString;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests for encoding/decoding HTTP2 header blocks.
|
* Tests for encoding/decoding HTTP2 header blocks.
|
||||||
@ -34,14 +34,14 @@ public class Http2HeaderBlockIOTest {
|
|||||||
private DefaultHttp2HeadersEncoder encoder;
|
private DefaultHttp2HeadersEncoder encoder;
|
||||||
private ByteBuf buffer;
|
private ByteBuf buffer;
|
||||||
|
|
||||||
@Before
|
@BeforeEach
|
||||||
public void setup() {
|
public void setup() {
|
||||||
encoder = new DefaultHttp2HeadersEncoder();
|
encoder = new DefaultHttp2HeadersEncoder();
|
||||||
decoder = new DefaultHttp2HeadersDecoder(false);
|
decoder = new DefaultHttp2HeadersDecoder(false);
|
||||||
buffer = Unpooled.buffer();
|
buffer = Unpooled.buffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
@After
|
@AfterEach
|
||||||
public void teardown() {
|
public void teardown() {
|
||||||
buffer.release();
|
buffer.release();
|
||||||
}
|
}
|
||||||
|
@ -14,17 +14,18 @@
|
|||||||
*/
|
*/
|
||||||
package io.netty.handler.codec.http2;
|
package io.netty.handler.codec.http2;
|
||||||
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import io.netty.channel.ChannelHandler;
|
import io.netty.channel.ChannelHandler;
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
import io.netty.channel.ChannelInboundHandlerAdapter;
|
import io.netty.channel.ChannelInboundHandlerAdapter;
|
||||||
import io.netty.channel.embedded.EmbeddedChannel;
|
import io.netty.channel.embedded.EmbeddedChannel;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.function.Executable;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
import static org.junit.Assert.assertNotNull;
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
public abstract class Http2MultiplexClientUpgradeTest<C extends Http2FrameCodec> {
|
public abstract class Http2MultiplexClientUpgradeTest<C extends Http2FrameCodec> {
|
||||||
|
|
||||||
@ -76,14 +77,20 @@ public abstract class Http2MultiplexClientUpgradeTest<C extends Http2FrameCodec>
|
|||||||
assertTrue(upgradeHandler.channelInactiveCalled);
|
assertTrue(upgradeHandler.channelInactiveCalled);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = Http2Exception.class)
|
@Test
|
||||||
public void clientUpgradeWithoutUpgradeHandlerThrowsHttp2Exception() throws Http2Exception {
|
public void clientUpgradeWithoutUpgradeHandlerThrowsHttp2Exception() throws Http2Exception {
|
||||||
C codec = newCodec(null);
|
final C codec = newCodec(null);
|
||||||
EmbeddedChannel ch = new EmbeddedChannel(codec, newMultiplexer(null));
|
final EmbeddedChannel ch = new EmbeddedChannel(codec, newMultiplexer(null));
|
||||||
|
|
||||||
|
assertThrows(Http2Exception.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Http2Exception {
|
||||||
try {
|
try {
|
||||||
codec.onHttpClientUpgrade();
|
codec.onHttpClientUpgrade();
|
||||||
} finally {
|
} finally {
|
||||||
assertTrue(ch.finishAndReleaseAll());
|
ch.finishAndReleaseAll();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,21 +32,23 @@ import io.netty.channel.EventLoopGroup;
|
|||||||
import io.netty.channel.local.LocalAddress;
|
import io.netty.channel.local.LocalAddress;
|
||||||
import io.netty.channel.local.LocalChannel;
|
import io.netty.channel.local.LocalChannel;
|
||||||
import io.netty.channel.local.LocalServerChannel;
|
import io.netty.channel.local.LocalServerChannel;
|
||||||
import org.junit.After;
|
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
import org.junit.Assert;
|
import org.junit.jupiter.api.AfterEach;
|
||||||
import org.junit.Before;
|
import org.junit.jupiter.api.BeforeAll;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.function.Executable;
|
||||||
|
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
|
|
||||||
import static io.netty.handler.codec.http2.Http2CodecUtil.isStreamIdValid;
|
import static io.netty.handler.codec.http2.Http2CodecUtil.isStreamIdValid;
|
||||||
import static java.util.concurrent.TimeUnit.SECONDS;
|
import static java.util.concurrent.TimeUnit.SECONDS;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.Assert.assertNotNull;
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
import static org.junit.jupiter.api.Assertions.fail;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unit tests for {@link Http2MultiplexCodec}.
|
* Unit tests for {@link Http2MultiplexCodec}.
|
||||||
@ -59,12 +61,12 @@ public class Http2MultiplexCodecBuilderTest {
|
|||||||
private Channel clientChannel;
|
private Channel clientChannel;
|
||||||
private LastInboundHandler serverLastInboundHandler;
|
private LastInboundHandler serverLastInboundHandler;
|
||||||
|
|
||||||
@BeforeClass
|
@BeforeAll
|
||||||
public static void init() {
|
public static void init() {
|
||||||
group = new DefaultEventLoop();
|
group = new DefaultEventLoop();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Before
|
@BeforeEach
|
||||||
public void setUp() throws InterruptedException {
|
public void setUp() throws InterruptedException {
|
||||||
final CountDownLatch serverChannelLatch = new CountDownLatch(1);
|
final CountDownLatch serverChannelLatch = new CountDownLatch(1);
|
||||||
LocalAddress serverAddress = new LocalAddress(getClass().getName());
|
LocalAddress serverAddress = new LocalAddress(getClass().getName());
|
||||||
@ -115,7 +117,7 @@ public class Http2MultiplexCodecBuilderTest {
|
|||||||
.handler(new Http2MultiplexCodecBuilder(false, new ChannelInitializer<Channel>() {
|
.handler(new Http2MultiplexCodecBuilder(false, new ChannelInitializer<Channel>() {
|
||||||
@Override
|
@Override
|
||||||
protected void initChannel(Channel ch) throws Exception {
|
protected void initChannel(Channel ch) throws Exception {
|
||||||
Assert.fail("Should not be called for outbound streams");
|
fail("Should not be called for outbound streams");
|
||||||
}
|
}
|
||||||
}).build());
|
}).build());
|
||||||
clientChannel = cb.connect(serverAddress).sync().channel();
|
clientChannel = cb.connect(serverAddress).sync().channel();
|
||||||
@ -127,7 +129,7 @@ public class Http2MultiplexCodecBuilderTest {
|
|||||||
group.shutdownGracefully(0, 5, SECONDS);
|
group.shutdownGracefully(0, 5, SECONDS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@After
|
@AfterEach
|
||||||
public void tearDown() throws Exception {
|
public void tearDown() throws Exception {
|
||||||
if (clientChannel != null) {
|
if (clientChannel != null) {
|
||||||
clientChannel.close().syncUninterruptibly();
|
clientChannel.close().syncUninterruptibly();
|
||||||
@ -251,8 +253,13 @@ public class Http2MultiplexCodecBuilderTest {
|
|||||||
assertNotNull(Http2MultiplexCodecBuilder.forServer(new SharableChannelHandler2()));
|
assertNotNull(Http2MultiplexCodecBuilder.forServer(new SharableChannelHandler2()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = IllegalArgumentException.class)
|
@Test
|
||||||
public void testUnsharableHandler() {
|
public void testUnsharableHandler() {
|
||||||
|
assertThrows(IllegalArgumentException.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
Http2MultiplexCodecBuilder.forServer(new UnsharableChannelHandler());
|
Http2MultiplexCodecBuilder.forServer(new UnsharableChannelHandler());
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,10 +33,10 @@ import io.netty.handler.codec.http2.Http2Exception.StreamException;
|
|||||||
import io.netty.handler.codec.http2.LastInboundHandler.Consumer;
|
import io.netty.handler.codec.http2.LastInboundHandler.Consumer;
|
||||||
import io.netty.util.AsciiString;
|
import io.netty.util.AsciiString;
|
||||||
import io.netty.util.AttributeKey;
|
import io.netty.util.AttributeKey;
|
||||||
import org.hamcrest.CoreMatchers;
|
import org.junit.jupiter.api.AfterEach;
|
||||||
import org.junit.After;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.Before;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.Test;
|
import org.junit.jupiter.api.function.Executable;
|
||||||
import org.mockito.ArgumentMatcher;
|
import org.mockito.ArgumentMatcher;
|
||||||
import org.mockito.Mockito;
|
import org.mockito.Mockito;
|
||||||
import org.mockito.invocation.InvocationOnMock;
|
import org.mockito.invocation.InvocationOnMock;
|
||||||
@ -56,13 +56,13 @@ import static io.netty.handler.codec.http2.Http2TestUtil.anyHttp2Settings;
|
|||||||
import static io.netty.handler.codec.http2.Http2TestUtil.assertEqualsAndRelease;
|
import static io.netty.handler.codec.http2.Http2TestUtil.assertEqualsAndRelease;
|
||||||
import static io.netty.handler.codec.http2.Http2TestUtil.bb;
|
import static io.netty.handler.codec.http2.Http2TestUtil.bb;
|
||||||
import static io.netty.util.ReferenceCountUtil.release;
|
import static io.netty.util.ReferenceCountUtil.release;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
import static org.junit.Assert.assertNotEquals;
|
import static org.junit.jupiter.api.Assertions.assertNotEquals;
|
||||||
import static org.junit.Assert.assertNotNull;
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
import static org.junit.Assert.assertNull;
|
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
import static org.junit.Assert.fail;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
import static org.mockito.ArgumentMatchers.anyBoolean;
|
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||||
import static org.mockito.ArgumentMatchers.anyInt;
|
import static org.mockito.ArgumentMatchers.anyInt;
|
||||||
@ -72,7 +72,6 @@ import static org.mockito.ArgumentMatchers.eq;
|
|||||||
import static org.mockito.Mockito.never;
|
import static org.mockito.Mockito.never;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
import static org.hamcrest.MatcherAssert.assertThat;
|
|
||||||
|
|
||||||
public abstract class Http2MultiplexTest<C extends Http2FrameCodec> {
|
public abstract class Http2MultiplexTest<C extends Http2FrameCodec> {
|
||||||
private final Http2Headers request = new DefaultHttp2Headers()
|
private final Http2Headers request = new DefaultHttp2Headers()
|
||||||
@ -90,7 +89,7 @@ public abstract class Http2MultiplexTest<C extends Http2FrameCodec> {
|
|||||||
protected abstract C newCodec(TestChannelInitializer childChannelInitializer, Http2FrameWriter frameWriter);
|
protected abstract C newCodec(TestChannelInitializer childChannelInitializer, Http2FrameWriter frameWriter);
|
||||||
protected abstract ChannelHandler newMultiplexer(TestChannelInitializer childChannelInitializer);
|
protected abstract ChannelHandler newMultiplexer(TestChannelInitializer childChannelInitializer);
|
||||||
|
|
||||||
@Before
|
@BeforeEach
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
childChannelInitializer = new TestChannelInitializer();
|
childChannelInitializer = new TestChannelInitializer();
|
||||||
parentChannel = new EmbeddedChannel();
|
parentChannel = new EmbeddedChannel();
|
||||||
@ -130,7 +129,7 @@ public abstract class Http2MultiplexTest<C extends Http2FrameCodec> {
|
|||||||
return eq(codec.ctx);
|
return eq(codec.ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@After
|
@AfterEach
|
||||||
public void tearDown() throws Exception {
|
public void tearDown() throws Exception {
|
||||||
if (childChannelInitializer.handler instanceof LastInboundHandler) {
|
if (childChannelInitializer.handler instanceof LastInboundHandler) {
|
||||||
((LastInboundHandler) childChannelInitializer.handler).finishAndReleaseAll();
|
((LastInboundHandler) childChannelInitializer.handler).finishAndReleaseAll();
|
||||||
@ -233,16 +232,17 @@ public abstract class Http2MultiplexTest<C extends Http2FrameCodec> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void headerMultipleContentLengthValidationShouldPropagate(boolean endStream) {
|
private void headerMultipleContentLengthValidationShouldPropagate(boolean endStream) {
|
||||||
LastInboundHandler inboundHandler = new LastInboundHandler();
|
final LastInboundHandler inboundHandler = new LastInboundHandler();
|
||||||
request.addLong(HttpHeaderNames.CONTENT_LENGTH, 0);
|
request.addLong(HttpHeaderNames.CONTENT_LENGTH, 0);
|
||||||
request.addLong(HttpHeaderNames.CONTENT_LENGTH, 1);
|
request.addLong(HttpHeaderNames.CONTENT_LENGTH, 1);
|
||||||
Http2StreamChannel channel = newInboundStream(3, endStream, inboundHandler);
|
Http2StreamChannel channel = newInboundStream(3, endStream, inboundHandler);
|
||||||
try {
|
|
||||||
|
assertThrows(StreamException.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
inboundHandler.checkException();
|
inboundHandler.checkException();
|
||||||
fail();
|
|
||||||
} catch (Exception e) {
|
|
||||||
assertThat(e, CoreMatchers.<Exception>instanceOf(StreamException.class));
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
assertNull(inboundHandler.readInbound());
|
assertNull(inboundHandler.readInbound());
|
||||||
assertFalse(channel.isActive());
|
assertFalse(channel.isActive());
|
||||||
}
|
}
|
||||||
@ -268,15 +268,16 @@ public abstract class Http2MultiplexTest<C extends Http2FrameCodec> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void headerSignContentLengthValidationShouldPropagateWithEndStream(boolean minus, boolean endStream) {
|
private void headerSignContentLengthValidationShouldPropagateWithEndStream(boolean minus, boolean endStream) {
|
||||||
LastInboundHandler inboundHandler = new LastInboundHandler();
|
final LastInboundHandler inboundHandler = new LastInboundHandler();
|
||||||
request.add(HttpHeaderNames.CONTENT_LENGTH, (minus ? "-" : "+") + 1);
|
request.add(HttpHeaderNames.CONTENT_LENGTH, (minus ? "-" : "+") + 1);
|
||||||
Http2StreamChannel channel = newInboundStream(3, endStream, inboundHandler);
|
Http2StreamChannel channel = newInboundStream(3, endStream, inboundHandler);
|
||||||
try {
|
assertThrows(StreamException.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
inboundHandler.checkException();
|
inboundHandler.checkException();
|
||||||
fail();
|
|
||||||
} catch (Exception e) {
|
|
||||||
assertThat(e, CoreMatchers.<Exception>instanceOf(StreamException.class));
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
assertNull(inboundHandler.readInbound());
|
assertNull(inboundHandler.readInbound());
|
||||||
assertFalse(channel.isActive());
|
assertFalse(channel.isActive());
|
||||||
}
|
}
|
||||||
@ -323,7 +324,7 @@ public abstract class Http2MultiplexTest<C extends Http2FrameCodec> {
|
|||||||
|
|
||||||
private void headerContentLengthNotMatchValidationShouldPropagate(
|
private void headerContentLengthNotMatchValidationShouldPropagate(
|
||||||
boolean closeLocal, boolean endStream, boolean trailer) {
|
boolean closeLocal, boolean endStream, boolean trailer) {
|
||||||
LastInboundHandler inboundHandler = new LastInboundHandler();
|
final LastInboundHandler inboundHandler = new LastInboundHandler();
|
||||||
request.addLong(HttpHeaderNames.CONTENT_LENGTH, 1);
|
request.addLong(HttpHeaderNames.CONTENT_LENGTH, 1);
|
||||||
Http2StreamChannel channel = newInboundStream(3, false, inboundHandler);
|
Http2StreamChannel channel = newInboundStream(3, false, inboundHandler);
|
||||||
assertTrue(channel.isActive());
|
assertTrue(channel.isActive());
|
||||||
@ -341,12 +342,14 @@ public abstract class Http2MultiplexTest<C extends Http2FrameCodec> {
|
|||||||
} else {
|
} else {
|
||||||
frameInboundWriter.writeInboundData(channel.stream().id(), bb("foo"), 0, endStream);
|
frameInboundWriter.writeInboundData(channel.stream().id(), bb("foo"), 0, endStream);
|
||||||
}
|
}
|
||||||
try {
|
|
||||||
|
assertThrows(StreamException.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
inboundHandler.checkException();
|
inboundHandler.checkException();
|
||||||
fail();
|
|
||||||
} catch (Exception e) {
|
|
||||||
assertThat(e, CoreMatchers.<Exception>instanceOf(StreamException.class));
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
Http2HeadersFrame headersFrame = new DefaultHttp2HeadersFrame(request).stream(channel.stream());
|
Http2HeadersFrame headersFrame = new DefaultHttp2HeadersFrame(request).stream(channel.stream());
|
||||||
assertEquals(headersFrame, inboundHandler.readInbound());
|
assertEquals(headersFrame, inboundHandler.readInbound());
|
||||||
assertNull(inboundHandler.readInbound());
|
assertNull(inboundHandler.readInbound());
|
||||||
@ -617,19 +620,25 @@ public abstract class Http2MultiplexTest<C extends Http2FrameCodec> {
|
|||||||
anyLong(), anyChannelPromise());
|
anyLong(), anyChannelPromise());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = StreamException.class)
|
@Test
|
||||||
public void streamExceptionTriggersChildChannelExceptionAndClose() throws Exception {
|
public void streamExceptionTriggersChildChannelExceptionAndClose() throws Exception {
|
||||||
LastInboundHandler inboundHandler = new LastInboundHandler();
|
final LastInboundHandler inboundHandler = new LastInboundHandler();
|
||||||
Http2StreamChannel channel = newInboundStream(3, false, inboundHandler);
|
Http2StreamChannel channel = newInboundStream(3, false, inboundHandler);
|
||||||
assertTrue(channel.isActive());
|
assertTrue(channel.isActive());
|
||||||
StreamException cause = new StreamException(channel.stream().id(), Http2Error.PROTOCOL_ERROR, "baaam!");
|
StreamException cause = new StreamException(channel.stream().id(), Http2Error.PROTOCOL_ERROR, "baaam!");
|
||||||
parentChannel.pipeline().fireExceptionCaught(cause);
|
parentChannel.pipeline().fireExceptionCaught(cause);
|
||||||
|
|
||||||
assertFalse(channel.isActive());
|
assertFalse(channel.isActive());
|
||||||
|
|
||||||
|
assertThrows(StreamException.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
inboundHandler.checkException();
|
inboundHandler.checkException();
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Test(expected = ClosedChannelException.class)
|
@Test
|
||||||
public void streamClosedErrorTranslatedToClosedChannelExceptionOnWrites() throws Exception {
|
public void streamClosedErrorTranslatedToClosedChannelExceptionOnWrites() throws Exception {
|
||||||
LastInboundHandler inboundHandler = new LastInboundHandler();
|
LastInboundHandler inboundHandler = new LastInboundHandler();
|
||||||
|
|
||||||
@ -646,7 +655,8 @@ public abstract class Http2MultiplexTest<C extends Http2FrameCodec> {
|
|||||||
new StreamException(childChannel.stream().id(), Http2Error.STREAM_CLOSED, "Stream Closed"));
|
new StreamException(childChannel.stream().id(), Http2Error.STREAM_CLOSED, "Stream Closed"));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
ChannelFuture future = childChannel.writeAndFlush(new DefaultHttp2HeadersFrame(new DefaultHttp2Headers()));
|
final ChannelFuture future = childChannel.writeAndFlush(
|
||||||
|
new DefaultHttp2HeadersFrame(new DefaultHttp2Headers()));
|
||||||
|
|
||||||
parentChannel.flush();
|
parentChannel.flush();
|
||||||
|
|
||||||
@ -655,8 +665,13 @@ public abstract class Http2MultiplexTest<C extends Http2FrameCodec> {
|
|||||||
|
|
||||||
inboundHandler.checkException();
|
inboundHandler.checkException();
|
||||||
|
|
||||||
|
assertThrows(ClosedChannelException.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() {
|
||||||
future.syncUninterruptibly();
|
future.syncUninterruptibly();
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void creatingWritingReadingAndClosingOutboundStreamShouldWork() {
|
public void creatingWritingReadingAndClosingOutboundStreamShouldWork() {
|
||||||
@ -692,7 +707,7 @@ public abstract class Http2MultiplexTest<C extends Http2FrameCodec> {
|
|||||||
// Test failing the promise of the first headers frame of an outbound stream. In practice this error case would most
|
// Test failing the promise of the first headers frame of an outbound stream. In practice this error case would most
|
||||||
// likely happen due to the max concurrent streams limit being hit or the channel running out of stream identifiers.
|
// likely happen due to the max concurrent streams limit being hit or the channel running out of stream identifiers.
|
||||||
//
|
//
|
||||||
@Test(expected = Http2NoMoreStreamIdsException.class)
|
@Test
|
||||||
public void failedOutboundStreamCreationThrowsAndClosesChannel() throws Exception {
|
public void failedOutboundStreamCreationThrowsAndClosesChannel() throws Exception {
|
||||||
LastInboundHandler handler = new LastInboundHandler();
|
LastInboundHandler handler = new LastInboundHandler();
|
||||||
Http2StreamChannel childChannel = newOutboundStream(handler);
|
Http2StreamChannel childChannel = newOutboundStream(handler);
|
||||||
@ -709,7 +724,7 @@ public abstract class Http2MultiplexTest<C extends Http2FrameCodec> {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
ChannelFuture future = childChannel.writeAndFlush(new DefaultHttp2HeadersFrame(headers));
|
final ChannelFuture future = childChannel.writeAndFlush(new DefaultHttp2HeadersFrame(headers));
|
||||||
parentChannel.flush();
|
parentChannel.flush();
|
||||||
|
|
||||||
assertFalse(childChannel.isActive());
|
assertFalse(childChannel.isActive());
|
||||||
@ -717,8 +732,13 @@ public abstract class Http2MultiplexTest<C extends Http2FrameCodec> {
|
|||||||
|
|
||||||
handler.checkException();
|
handler.checkException();
|
||||||
|
|
||||||
|
assertThrows(Http2NoMoreStreamIdsException.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() {
|
||||||
future.syncUninterruptibly();
|
future.syncUninterruptibly();
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void channelClosedWhenCloseListenerCompletes() {
|
public void channelClosedWhenCloseListenerCompletes() {
|
||||||
@ -1352,7 +1372,7 @@ public abstract class Http2MultiplexTest<C extends Http2FrameCodec> {
|
|||||||
int numFrames) {
|
int numFrames) {
|
||||||
for (int i = 0; i < numFrames; i++) {
|
for (int i = 0; i < numFrames; i++) {
|
||||||
Http2StreamFrame frame = inboundHandler.readInbound();
|
Http2StreamFrame frame = inboundHandler.readInbound();
|
||||||
assertNotNull(i + " out of " + numFrames + " received", frame);
|
assertNotNull(frame, i + " out of " + numFrames + " received");
|
||||||
assertEquals(streamChannel.stream(), frame.stream());
|
assertEquals(streamChannel.stream(), frame.stream());
|
||||||
release(frame);
|
release(frame);
|
||||||
}
|
}
|
||||||
|
@ -46,10 +46,11 @@ import io.netty.util.NetUtil;
|
|||||||
import io.netty.util.ReferenceCountUtil;
|
import io.netty.util.ReferenceCountUtil;
|
||||||
import io.netty.util.concurrent.Future;
|
import io.netty.util.concurrent.Future;
|
||||||
import io.netty.util.concurrent.FutureListener;
|
import io.netty.util.concurrent.FutureListener;
|
||||||
import org.junit.After;
|
import org.junit.jupiter.api.AfterEach;
|
||||||
import org.junit.Before;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.Ignore;
|
import org.junit.jupiter.api.Disabled;
|
||||||
import org.junit.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.Timeout;
|
||||||
|
|
||||||
import javax.net.ssl.SSLException;
|
import javax.net.ssl.SSLException;
|
||||||
import javax.net.ssl.X509TrustManager;
|
import javax.net.ssl.X509TrustManager;
|
||||||
@ -64,8 +65,8 @@ import java.util.concurrent.TimeUnit;
|
|||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
import static java.util.concurrent.TimeUnit.MILLISECONDS;
|
import static java.util.concurrent.TimeUnit.MILLISECONDS;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
import static org.junit.Assume.assumeTrue;
|
import static org.junit.jupiter.api.Assumptions.assumeTrue;
|
||||||
|
|
||||||
public class Http2MultiplexTransportTest {
|
public class Http2MultiplexTransportTest {
|
||||||
private static final ChannelHandler DISCARD_HANDLER = new ChannelInboundHandlerAdapter() {
|
private static final ChannelHandler DISCARD_HANDLER = new ChannelInboundHandlerAdapter() {
|
||||||
@ -91,12 +92,12 @@ public class Http2MultiplexTransportTest {
|
|||||||
private Channel serverChannel;
|
private Channel serverChannel;
|
||||||
private Channel serverConnectedChannel;
|
private Channel serverConnectedChannel;
|
||||||
|
|
||||||
@Before
|
@BeforeEach
|
||||||
public void setup() {
|
public void setup() {
|
||||||
eventLoopGroup = new NioEventLoopGroup();
|
eventLoopGroup = new NioEventLoopGroup();
|
||||||
}
|
}
|
||||||
|
|
||||||
@After
|
@AfterEach
|
||||||
public void teardown() {
|
public void teardown() {
|
||||||
if (clientChannel != null) {
|
if (clientChannel != null) {
|
||||||
clientChannel.close();
|
clientChannel.close();
|
||||||
@ -110,12 +111,14 @@ public class Http2MultiplexTransportTest {
|
|||||||
eventLoopGroup.shutdownGracefully(0, 0, MILLISECONDS);
|
eventLoopGroup.shutdownGracefully(0, 0, MILLISECONDS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(timeout = 10000)
|
@Test
|
||||||
|
@Timeout(value = 10000, unit = MILLISECONDS)
|
||||||
public void asyncSettingsAckWithMultiplexCodec() throws InterruptedException {
|
public void asyncSettingsAckWithMultiplexCodec() throws InterruptedException {
|
||||||
asyncSettingsAck0(new Http2MultiplexCodecBuilder(true, DISCARD_HANDLER).build(), null);
|
asyncSettingsAck0(new Http2MultiplexCodecBuilder(true, DISCARD_HANDLER).build(), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(timeout = 10000)
|
@Test
|
||||||
|
@Timeout(value = 10000, unit = MILLISECONDS)
|
||||||
public void asyncSettingsAckWithMultiplexHandler() throws InterruptedException {
|
public void asyncSettingsAckWithMultiplexHandler() throws InterruptedException {
|
||||||
asyncSettingsAck0(new Http2FrameCodecBuilder(true).build(),
|
asyncSettingsAck0(new Http2FrameCodecBuilder(true).build(),
|
||||||
new Http2MultiplexHandler(DISCARD_HANDLER));
|
new Http2MultiplexHandler(DISCARD_HANDLER));
|
||||||
@ -198,7 +201,8 @@ public class Http2MultiplexTransportTest {
|
|||||||
serverAckAllLatch.await();
|
serverAckAllLatch.await();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(timeout = 5000L)
|
@Test
|
||||||
|
@Timeout(value = 5000L, unit = MILLISECONDS)
|
||||||
public void testFlushNotDiscarded()
|
public void testFlushNotDiscarded()
|
||||||
throws InterruptedException {
|
throws InterruptedException {
|
||||||
final ScheduledExecutorService executorService = Executors.newScheduledThreadPool(1);
|
final ScheduledExecutorService executorService = Executors.newScheduledThreadPool(1);
|
||||||
@ -276,24 +280,28 @@ public class Http2MultiplexTransportTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(timeout = 5000L)
|
@Test
|
||||||
|
@Timeout(value = 5000L, unit = MILLISECONDS)
|
||||||
public void testSSLExceptionOpenSslTLSv12() throws Exception {
|
public void testSSLExceptionOpenSslTLSv12() throws Exception {
|
||||||
testSslException(SslProvider.OPENSSL, false);
|
testSslException(SslProvider.OPENSSL, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(timeout = 5000L)
|
@Test
|
||||||
|
@Timeout(value = 5000L, unit = MILLISECONDS)
|
||||||
public void testSSLExceptionOpenSslTLSv13() throws Exception {
|
public void testSSLExceptionOpenSslTLSv13() throws Exception {
|
||||||
testSslException(SslProvider.OPENSSL, true);
|
testSslException(SslProvider.OPENSSL, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Ignore("JDK SSLEngine does not produce an alert")
|
@Disabled("JDK SSLEngine does not produce an alert")
|
||||||
@Test(timeout = 5000L)
|
@Test
|
||||||
|
@Timeout(value = 5000L, unit = MILLISECONDS)
|
||||||
public void testSSLExceptionJDKTLSv12() throws Exception {
|
public void testSSLExceptionJDKTLSv12() throws Exception {
|
||||||
testSslException(SslProvider.JDK, false);
|
testSslException(SslProvider.JDK, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Ignore("JDK SSLEngine does not produce an alert")
|
@Disabled("JDK SSLEngine does not produce an alert")
|
||||||
@Test(timeout = 5000L)
|
@Test
|
||||||
|
@Timeout(value = 5000L, unit = MILLISECONDS)
|
||||||
public void testSSLExceptionJDKTLSv13() throws Exception {
|
public void testSSLExceptionJDKTLSv13() throws Exception {
|
||||||
testSslException(SslProvider.JDK, true);
|
testSslException(SslProvider.JDK, true);
|
||||||
}
|
}
|
||||||
@ -446,13 +454,15 @@ public class Http2MultiplexTransportTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(timeout = 5000L)
|
@Test
|
||||||
|
@Timeout(value = 5000L, unit = MILLISECONDS)
|
||||||
public void testFireChannelReadAfterHandshakeSuccess_JDK() throws Exception {
|
public void testFireChannelReadAfterHandshakeSuccess_JDK() throws Exception {
|
||||||
assumeTrue(SslProvider.isAlpnSupported(SslProvider.JDK));
|
assumeTrue(SslProvider.isAlpnSupported(SslProvider.JDK));
|
||||||
testFireChannelReadAfterHandshakeSuccess(SslProvider.JDK);
|
testFireChannelReadAfterHandshakeSuccess(SslProvider.JDK);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(timeout = 5000L)
|
@Test
|
||||||
|
@Timeout(value = 5000L, unit = MILLISECONDS)
|
||||||
public void testFireChannelReadAfterHandshakeSuccess_OPENSSL() throws Exception {
|
public void testFireChannelReadAfterHandshakeSuccess_OPENSSL() throws Exception {
|
||||||
assumeTrue(OpenSsl.isAvailable());
|
assumeTrue(OpenSsl.isAvailable());
|
||||||
assumeTrue(SslProvider.isAlpnSupported(SslProvider.OPENSSL));
|
assumeTrue(SslProvider.isAlpnSupported(SslProvider.OPENSSL));
|
||||||
|
@ -20,9 +20,9 @@ import io.netty.handler.ssl.SslContext;
|
|||||||
import io.netty.handler.ssl.SslContextBuilder;
|
import io.netty.handler.ssl.SslContextBuilder;
|
||||||
import io.netty.handler.ssl.SslProvider;
|
import io.netty.handler.ssl.SslProvider;
|
||||||
import io.netty.handler.ssl.SupportedCipherSuiteFilter;
|
import io.netty.handler.ssl.SupportedCipherSuiteFilter;
|
||||||
import org.junit.Assert;
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.Assume;
|
import org.junit.jupiter.api.Assumptions;
|
||||||
import org.junit.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import javax.net.ssl.SSLEngine;
|
import javax.net.ssl.SSLEngine;
|
||||||
import javax.net.ssl.SSLException;
|
import javax.net.ssl.SSLException;
|
||||||
@ -31,7 +31,7 @@ public class Http2SecurityUtilTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testTLSv13CiphersIncluded() throws SSLException {
|
public void testTLSv13CiphersIncluded() throws SSLException {
|
||||||
Assume.assumeTrue(SslProvider.isTlsv13Supported(SslProvider.JDK));
|
Assumptions.assumeTrue(SslProvider.isTlsv13Supported(SslProvider.JDK));
|
||||||
testCiphersIncluded("TLSv1.3");
|
testCiphersIncluded("TLSv1.3");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,6 +44,6 @@ public class Http2SecurityUtilTest {
|
|||||||
SslContext context = SslContextBuilder.forClient().sslProvider(SslProvider.JDK).protocols(protocol)
|
SslContext context = SslContextBuilder.forClient().sslProvider(SslProvider.JDK).protocols(protocol)
|
||||||
.ciphers(Http2SecurityUtil.CIPHERS, SupportedCipherSuiteFilter.INSTANCE).build();
|
.ciphers(Http2SecurityUtil.CIPHERS, SupportedCipherSuiteFilter.INSTANCE).build();
|
||||||
SSLEngine engine = context.newEngine(UnpooledByteBufAllocator.DEFAULT);
|
SSLEngine engine = context.newEngine(UnpooledByteBufAllocator.DEFAULT);
|
||||||
Assert.assertTrue("No " + protocol + " ciphers found", engine.getEnabledCipherSuites().length > 0);
|
Assertions.assertTrue(engine.getEnabledCipherSuites().length > 0, "No " + protocol + " ciphers found");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,12 +28,12 @@ import io.netty.handler.codec.http.HttpHeaderNames;
|
|||||||
import io.netty.handler.codec.http.HttpMethod;
|
import io.netty.handler.codec.http.HttpMethod;
|
||||||
import io.netty.handler.codec.http.HttpVersion;
|
import io.netty.handler.codec.http.HttpVersion;
|
||||||
|
|
||||||
import static org.junit.Assert.assertNotNull;
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
import static org.junit.Assert.assertNull;
|
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||||
import static org.junit.Assert.assertSame;
|
import static org.junit.jupiter.api.Assertions.assertSame;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.mockito.Mockito;
|
import org.mockito.Mockito;
|
||||||
|
|
||||||
public class Http2ServerUpgradeCodecTest {
|
public class Http2ServerUpgradeCodecTest {
|
||||||
|
@ -15,14 +15,17 @@
|
|||||||
|
|
||||||
package io.netty.handler.codec.http2;
|
package io.netty.handler.codec.http2;
|
||||||
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Test;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.function.Executable;
|
||||||
|
|
||||||
import static io.netty.handler.codec.http2.Http2CodecUtil.MAX_FRAME_SIZE_UPPER_BOUND;
|
import static io.netty.handler.codec.http2.Http2CodecUtil.MAX_FRAME_SIZE_UPPER_BOUND;
|
||||||
import static io.netty.handler.codec.http2.Http2CodecUtil.MAX_UNSIGNED_INT;
|
import static io.netty.handler.codec.http2.Http2CodecUtil.MAX_UNSIGNED_INT;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.Assert.assertNull;
|
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests for {@link Http2Settings}.
|
* Tests for {@link Http2Settings}.
|
||||||
@ -31,7 +34,7 @@ public class Http2SettingsTest {
|
|||||||
|
|
||||||
private Http2Settings settings;
|
private Http2Settings settings;
|
||||||
|
|
||||||
@Before
|
@BeforeEach
|
||||||
public void setup() {
|
public void setup() {
|
||||||
settings = new Http2Settings();
|
settings = new Http2Settings();
|
||||||
}
|
}
|
||||||
@ -83,10 +86,15 @@ public class Http2SettingsTest {
|
|||||||
assertEquals(MAX_UNSIGNED_INT, (long) settings.maxHeaderListSize());
|
assertEquals(MAX_UNSIGNED_INT, (long) settings.maxHeaderListSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = IllegalArgumentException.class)
|
@Test
|
||||||
public void headerListSizeBoundCheck() {
|
public void headerListSizeBoundCheck() {
|
||||||
|
assertThrows(IllegalArgumentException.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() {
|
||||||
settings.maxHeaderListSize(Long.MAX_VALUE);
|
settings.maxHeaderListSize(Long.MAX_VALUE);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void headerTableSizeUnsignedInt() {
|
public void headerTableSizeUnsignedInt() {
|
||||||
@ -94,13 +102,23 @@ public class Http2SettingsTest {
|
|||||||
assertEquals(MAX_UNSIGNED_INT, (long) settings.get(Http2CodecUtil.SETTINGS_HEADER_TABLE_SIZE));
|
assertEquals(MAX_UNSIGNED_INT, (long) settings.get(Http2CodecUtil.SETTINGS_HEADER_TABLE_SIZE));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = IllegalArgumentException.class)
|
@Test
|
||||||
public void headerTableSizeBoundCheck() {
|
public void headerTableSizeBoundCheck() {
|
||||||
|
assertThrows(IllegalArgumentException.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() {
|
||||||
settings.put(Http2CodecUtil.SETTINGS_HEADER_TABLE_SIZE, (Long) Long.MAX_VALUE);
|
settings.put(Http2CodecUtil.SETTINGS_HEADER_TABLE_SIZE, (Long) Long.MAX_VALUE);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Test(expected = IllegalArgumentException.class)
|
@Test
|
||||||
public void headerTableSizeBoundCheck2() {
|
public void headerTableSizeBoundCheck2() {
|
||||||
|
assertThrows(IllegalArgumentException.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() {
|
||||||
settings.put(Http2CodecUtil.SETTINGS_HEADER_TABLE_SIZE, Long.valueOf(-1L));
|
settings.put(Http2CodecUtil.SETTINGS_HEADER_TABLE_SIZE, Long.valueOf(-1L));
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,9 +32,8 @@ import io.netty.util.concurrent.Promise;
|
|||||||
import io.netty.util.internal.logging.InternalLogger;
|
import io.netty.util.internal.logging.InternalLogger;
|
||||||
import io.netty.util.internal.logging.InternalLoggerFactory;
|
import io.netty.util.internal.logging.InternalLoggerFactory;
|
||||||
import org.hamcrest.core.IsInstanceOf;
|
import org.hamcrest.core.IsInstanceOf;
|
||||||
import org.junit.Rule;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.Test;
|
import org.junit.jupiter.api.function.Executable;
|
||||||
import org.junit.rules.ExpectedException;
|
|
||||||
|
|
||||||
import java.nio.channels.ClosedChannelException;
|
import java.nio.channels.ClosedChannelException;
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
@ -46,7 +45,8 @@ import static java.util.concurrent.TimeUnit.SECONDS;
|
|||||||
import static org.hamcrest.MatcherAssert.assertThat;
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
import static org.hamcrest.Matchers.is;
|
import static org.hamcrest.Matchers.is;
|
||||||
import static org.hamcrest.Matchers.instanceOf;
|
import static org.hamcrest.Matchers.instanceOf;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
@ -55,9 +55,6 @@ public class Http2StreamChannelBootstrapTest {
|
|||||||
private static final InternalLogger logger =
|
private static final InternalLogger logger =
|
||||||
InternalLoggerFactory.getInstance(Http2StreamChannelBootstrapTest.class);
|
InternalLoggerFactory.getInstance(Http2StreamChannelBootstrapTest.class);
|
||||||
|
|
||||||
@Rule
|
|
||||||
public ExpectedException exceptionRule = ExpectedException.none();
|
|
||||||
|
|
||||||
private volatile Channel serverConnectedChannel;
|
private volatile Channel serverConnectedChannel;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -109,14 +106,18 @@ public class Http2StreamChannelBootstrapTest {
|
|||||||
});
|
});
|
||||||
|
|
||||||
Http2StreamChannelBootstrap bootstrap = new Http2StreamChannelBootstrap(clientChannel);
|
Http2StreamChannelBootstrap bootstrap = new Http2StreamChannelBootstrap(clientChannel);
|
||||||
Promise<Http2StreamChannel> promise = clientChannel.eventLoop().newPromise();
|
final Promise<Http2StreamChannel> promise = clientChannel.eventLoop().newPromise();
|
||||||
bootstrap.open(promise);
|
bootstrap.open(promise);
|
||||||
assertThat(promise.isDone(), is(false));
|
assertThat(promise.isDone(), is(false));
|
||||||
closeLatch.countDown();
|
closeLatch.countDown();
|
||||||
|
|
||||||
exceptionRule.expect(ExecutionException.class);
|
ExecutionException exception = assertThrows(ExecutionException.class, new Executable() {
|
||||||
exceptionRule.expectCause(IsInstanceOf.<Throwable>instanceOf(ClosedChannelException.class));
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
promise.get(3, SECONDS);
|
promise.get(3, SECONDS);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
assertThat(exception.getCause(), IsInstanceOf.<Throwable>instanceOf(ClosedChannelException.class));
|
||||||
} finally {
|
} finally {
|
||||||
safeClose(clientChannel);
|
safeClose(clientChannel);
|
||||||
safeClose(serverConnectedChannel);
|
safeClose(serverConnectedChannel);
|
||||||
|
@ -14,20 +14,18 @@
|
|||||||
*/
|
*/
|
||||||
package io.netty.handler.codec.http2;
|
package io.netty.handler.codec.http2;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.ObjectInputStream;
|
import java.io.ObjectInputStream;
|
||||||
import java.io.ObjectOutputStream;
|
import java.io.ObjectOutputStream;
|
||||||
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.buffer.ByteBufInputStream;
|
import io.netty.buffer.ByteBufInputStream;
|
||||||
import io.netty.buffer.ByteBufOutputStream;
|
import io.netty.buffer.ByteBufOutputStream;
|
||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
import io.netty.channel.ChannelId;
|
import io.netty.channel.ChannelId;
|
||||||
import io.netty.channel.DefaultChannelId;
|
import io.netty.channel.DefaultChannelId;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
public class Http2StreamChannelIdTest {
|
public class Http2StreamChannelIdTest {
|
||||||
|
|
||||||
|
@ -47,8 +47,8 @@ import io.netty.handler.ssl.SslContext;
|
|||||||
import io.netty.handler.ssl.SslContextBuilder;
|
import io.netty.handler.ssl.SslContextBuilder;
|
||||||
import io.netty.handler.ssl.SslProvider;
|
import io.netty.handler.ssl.SslProvider;
|
||||||
import io.netty.util.CharsetUtil;
|
import io.netty.util.CharsetUtil;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.Test;
|
import org.junit.jupiter.api.function.Executable;
|
||||||
|
|
||||||
import java.util.Queue;
|
import java.util.Queue;
|
||||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||||
@ -56,10 +56,11 @@ import java.util.concurrent.ConcurrentLinkedQueue;
|
|||||||
import static org.hamcrest.CoreMatchers.is;
|
import static org.hamcrest.CoreMatchers.is;
|
||||||
import static org.hamcrest.CoreMatchers.nullValue;
|
import static org.hamcrest.CoreMatchers.nullValue;
|
||||||
import static org.hamcrest.MatcherAssert.assertThat;
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.Assert.assertNull;
|
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
|
|
||||||
public class Http2StreamFrameToHttpObjectCodecTest {
|
public class Http2StreamFrameToHttpObjectCodecTest {
|
||||||
|
|
||||||
@ -90,15 +91,17 @@ public class Http2StreamFrameToHttpObjectCodecTest {
|
|||||||
assertFalse(ch.finish());
|
assertFalse(ch.finish());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test (expected = EncoderException.class)
|
@Test
|
||||||
public void encodeNonFullHttpResponse100ContinueIsRejected() throws Exception {
|
public void encodeNonFullHttpResponse100ContinueIsRejected() throws Exception {
|
||||||
EmbeddedChannel ch = new EmbeddedChannel(new Http2StreamFrameToHttpObjectCodec(true));
|
final EmbeddedChannel ch = new EmbeddedChannel(new Http2StreamFrameToHttpObjectCodec(true));
|
||||||
try {
|
assertThrows(EncoderException.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() {
|
||||||
ch.writeOutbound(new DefaultHttpResponse(
|
ch.writeOutbound(new DefaultHttpResponse(
|
||||||
HttpVersion.HTTP_1_1, HttpResponseStatus.CONTINUE));
|
HttpVersion.HTTP_1_1, HttpResponseStatus.CONTINUE));
|
||||||
} finally {
|
|
||||||
ch.finishAndReleaseAll();
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
ch.finishAndReleaseAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -21,7 +21,8 @@ import io.netty.handler.codec.http.HttpMethod;
|
|||||||
import io.netty.handler.codec.http.HttpRequest;
|
import io.netty.handler.codec.http.HttpRequest;
|
||||||
import io.netty.handler.codec.http.HttpVersion;
|
import io.netty.handler.codec.http.HttpVersion;
|
||||||
import io.netty.util.AsciiString;
|
import io.netty.util.AsciiString;
|
||||||
import org.junit.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.function.Executable;
|
||||||
|
|
||||||
import static io.netty.handler.codec.http.HttpHeaderNames.CONNECTION;
|
import static io.netty.handler.codec.http.HttpHeaderNames.CONNECTION;
|
||||||
import static io.netty.handler.codec.http.HttpHeaderNames.COOKIE;
|
import static io.netty.handler.codec.http.HttpHeaderNames.COOKIE;
|
||||||
@ -33,12 +34,13 @@ import static io.netty.handler.codec.http.HttpHeaderNames.TRANSFER_ENCODING;
|
|||||||
import static io.netty.handler.codec.http.HttpHeaderNames.UPGRADE;
|
import static io.netty.handler.codec.http.HttpHeaderNames.UPGRADE;
|
||||||
import static io.netty.handler.codec.http.HttpHeaderValues.GZIP;
|
import static io.netty.handler.codec.http.HttpHeaderValues.GZIP;
|
||||||
import static io.netty.handler.codec.http.HttpHeaderValues.TRAILERS;
|
import static io.netty.handler.codec.http.HttpHeaderValues.TRAILERS;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
import static org.junit.Assert.assertNotNull;
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
import static org.junit.Assert.assertNull;
|
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||||
import static org.junit.Assert.assertSame;
|
import static org.junit.jupiter.api.Assertions.assertSame;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
public class HttpConversionUtilTest {
|
public class HttpConversionUtilTest {
|
||||||
|
|
||||||
@ -84,10 +86,15 @@ public class HttpConversionUtilTest {
|
|||||||
assertSame(AsciiString.EMPTY_STRING, headers.authority());
|
assertSame(AsciiString.EMPTY_STRING, headers.authority());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = IllegalArgumentException.class)
|
@Test
|
||||||
public void setHttp2AuthorityWithEmptyAuthority() {
|
public void setHttp2AuthorityWithEmptyAuthority() {
|
||||||
|
assertThrows(IllegalArgumentException.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() {
|
||||||
HttpConversionUtil.setHttp2Authority("info@", new DefaultHttp2Headers());
|
HttpConversionUtil.setHttp2Authority("info@", new DefaultHttp2Headers());
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void stripTEHeaders() {
|
public void stripTEHeaders() {
|
||||||
|
@ -67,7 +67,6 @@ import static org.hamcrest.MatcherAssert.assertThat;
|
|||||||
import static org.hamcrest.Matchers.instanceOf;
|
import static org.hamcrest.Matchers.instanceOf;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
import static org.junit.Assert.assertNotEquals;
|
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
import static org.mockito.Mockito.any;
|
import static org.mockito.Mockito.any;
|
||||||
import static org.mockito.Mockito.anyBoolean;
|
import static org.mockito.Mockito.anyBoolean;
|
||||||
|
@ -46,9 +46,9 @@ import io.netty.handler.codec.http2.Http2TestUtil.Http2Runnable;
|
|||||||
import io.netty.util.AsciiString;
|
import io.netty.util.AsciiString;
|
||||||
import io.netty.util.CharsetUtil;
|
import io.netty.util.CharsetUtil;
|
||||||
import io.netty.util.concurrent.Future;
|
import io.netty.util.concurrent.Future;
|
||||||
import org.junit.After;
|
import org.junit.jupiter.api.AfterEach;
|
||||||
import org.junit.Before;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.mockito.ArgumentCaptor;
|
import org.mockito.ArgumentCaptor;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.MockitoAnnotations;
|
import org.mockito.MockitoAnnotations;
|
||||||
@ -61,9 +61,9 @@ import static io.netty.handler.codec.http2.Http2Exception.isStreamError;
|
|||||||
import static io.netty.handler.codec.http2.Http2TestUtil.of;
|
import static io.netty.handler.codec.http2.Http2TestUtil.of;
|
||||||
import static io.netty.handler.codec.http2.Http2TestUtil.runInChannel;
|
import static io.netty.handler.codec.http2.Http2TestUtil.runInChannel;
|
||||||
import static java.util.concurrent.TimeUnit.SECONDS;
|
import static java.util.concurrent.TimeUnit.SECONDS;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.Assert.assertNotNull;
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
import static org.mockito.Mockito.times;
|
import static org.mockito.Mockito.times;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
|
|
||||||
@ -102,12 +102,12 @@ public class InboundHttp2ToHttpAdapterTest {
|
|||||||
private HttpSettingsDelegator settingsDelegator;
|
private HttpSettingsDelegator settingsDelegator;
|
||||||
private Http2Exception clientException;
|
private Http2Exception clientException;
|
||||||
|
|
||||||
@Before
|
@BeforeEach
|
||||||
public void setup() throws Exception {
|
public void setup() throws Exception {
|
||||||
MockitoAnnotations.initMocks(this);
|
MockitoAnnotations.initMocks(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@After
|
@AfterEach
|
||||||
public void teardown() throws Exception {
|
public void teardown() throws Exception {
|
||||||
cleanupCapturedRequests();
|
cleanupCapturedRequests();
|
||||||
cleanupCapturedResponses();
|
cleanupCapturedResponses();
|
||||||
|
@ -16,47 +16,77 @@
|
|||||||
package io.netty.handler.codec.http2;
|
package io.netty.handler.codec.http2;
|
||||||
|
|
||||||
import io.netty.util.AsciiString;
|
import io.netty.util.AsciiString;
|
||||||
import org.junit.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.function.Executable;
|
||||||
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.NoSuchElementException;
|
import java.util.NoSuchElementException;
|
||||||
|
|
||||||
import static io.netty.handler.codec.http2.DefaultHttp2HeadersTest.*;
|
import static io.netty.handler.codec.http2.DefaultHttp2HeadersTest.*;
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
public class ReadOnlyHttp2HeadersTest {
|
public class ReadOnlyHttp2HeadersTest {
|
||||||
@Test(expected = IllegalArgumentException.class)
|
@Test
|
||||||
public void notKeyValuePairThrows() {
|
public void notKeyValuePairThrows() {
|
||||||
|
assertThrows(IllegalArgumentException.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() {
|
||||||
ReadOnlyHttp2Headers.trailers(false, new AsciiString[]{ null });
|
ReadOnlyHttp2Headers.trailers(false, new AsciiString[]{ null });
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Test(expected = NullPointerException.class)
|
@Test
|
||||||
public void nullTrailersNotAllowed() {
|
public void nullTrailersNotAllowed() {
|
||||||
|
assertThrows(NullPointerException.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() {
|
||||||
ReadOnlyHttp2Headers.trailers(false, (AsciiString[]) null);
|
ReadOnlyHttp2Headers.trailers(false, (AsciiString[]) null);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void nullHeaderNameNotChecked() {
|
public void nullHeaderNameNotChecked() {
|
||||||
ReadOnlyHttp2Headers.trailers(false, null, null);
|
ReadOnlyHttp2Headers.trailers(false, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = Http2Exception.class)
|
@Test
|
||||||
public void nullHeaderNameValidated() {
|
public void nullHeaderNameValidated() {
|
||||||
|
assertThrows(Http2Exception.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() {
|
||||||
ReadOnlyHttp2Headers.trailers(true, null, new AsciiString("foo"));
|
ReadOnlyHttp2Headers.trailers(true, null, new AsciiString("foo"));
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Test(expected = IllegalArgumentException.class)
|
@Test
|
||||||
public void pseudoHeaderNotAllowedAfterNonPseudoHeaders() {
|
public void pseudoHeaderNotAllowedAfterNonPseudoHeaders() {
|
||||||
|
assertThrows(IllegalArgumentException.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() {
|
||||||
ReadOnlyHttp2Headers.trailers(true, new AsciiString(":name"), new AsciiString("foo"),
|
ReadOnlyHttp2Headers.trailers(true, new AsciiString(":name"), new AsciiString("foo"),
|
||||||
new AsciiString("othername"), new AsciiString("goo"),
|
new AsciiString("othername"), new AsciiString("goo"),
|
||||||
new AsciiString(":pseudo"), new AsciiString("val"));
|
new AsciiString(":pseudo"), new AsciiString("val"));
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Test(expected = IllegalArgumentException.class)
|
@Test
|
||||||
public void nullValuesAreNotAllowed() {
|
public void nullValuesAreNotAllowed() {
|
||||||
|
assertThrows(IllegalArgumentException.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() {
|
||||||
ReadOnlyHttp2Headers.trailers(true, new AsciiString("foo"), null);
|
ReadOnlyHttp2Headers.trailers(true, new AsciiString("foo"), null);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void emptyHeaderNameAllowed() {
|
public void emptyHeaderNameAllowed() {
|
||||||
@ -75,35 +105,65 @@ public class ReadOnlyHttp2HeadersTest {
|
|||||||
verifyPseudoHeadersFirst(headers);
|
verifyPseudoHeadersFirst(headers);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = UnsupportedOperationException.class)
|
@Test
|
||||||
public void testIteratorReadOnlyClient() {
|
public void testIteratorReadOnlyClient() {
|
||||||
|
assertThrows(UnsupportedOperationException.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() {
|
||||||
testIteratorReadOnly(newClientHeaders());
|
testIteratorReadOnly(newClientHeaders());
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Test(expected = UnsupportedOperationException.class)
|
@Test
|
||||||
public void testIteratorReadOnlyServer() {
|
public void testIteratorReadOnlyServer() {
|
||||||
|
assertThrows(UnsupportedOperationException.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() {
|
||||||
testIteratorReadOnly(newServerHeaders());
|
testIteratorReadOnly(newServerHeaders());
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Test(expected = UnsupportedOperationException.class)
|
@Test
|
||||||
public void testIteratorReadOnlyTrailers() {
|
public void testIteratorReadOnlyTrailers() {
|
||||||
|
assertThrows(UnsupportedOperationException.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() {
|
||||||
testIteratorReadOnly(newTrailers());
|
testIteratorReadOnly(newTrailers());
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Test(expected = UnsupportedOperationException.class)
|
@Test
|
||||||
public void testIteratorEntryReadOnlyClient() {
|
public void testIteratorEntryReadOnlyClient() {
|
||||||
|
assertThrows(UnsupportedOperationException.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() {
|
||||||
testIteratorEntryReadOnly(newClientHeaders());
|
testIteratorEntryReadOnly(newClientHeaders());
|
||||||
}
|
}
|
||||||
|
});
|
||||||
@Test(expected = UnsupportedOperationException.class)
|
|
||||||
public void testIteratorEntryReadOnlyServer() {
|
|
||||||
testIteratorEntryReadOnly(newServerHeaders());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = UnsupportedOperationException.class)
|
@Test
|
||||||
|
public void testIteratorEntryReadOnlyServer() {
|
||||||
|
assertThrows(UnsupportedOperationException.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() {
|
||||||
|
testIteratorEntryReadOnly(newServerHeaders());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
public void testIteratorEntryReadOnlyTrailers() {
|
public void testIteratorEntryReadOnlyTrailers() {
|
||||||
|
assertThrows(UnsupportedOperationException.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() {
|
||||||
testIteratorEntryReadOnly(newTrailers());
|
testIteratorEntryReadOnly(newTrailers());
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSize() {
|
public void testSize() {
|
||||||
@ -172,14 +232,14 @@ public class ReadOnlyHttp2HeadersTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testEmptyValueIterator() {
|
public void testEmptyValueIterator() {
|
||||||
Http2Headers headers = newServerHeaders();
|
Http2Headers headers = newServerHeaders();
|
||||||
Iterator<CharSequence> itr = headers.valueIterator("foo");
|
final Iterator<CharSequence> itr = headers.valueIterator("foo");
|
||||||
assertFalse(itr.hasNext());
|
assertFalse(itr.hasNext());
|
||||||
try {
|
assertThrows(NoSuchElementException.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() {
|
||||||
itr.next();
|
itr.next();
|
||||||
fail();
|
|
||||||
} catch (NoSuchElementException ignored) {
|
|
||||||
// ignored
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -21,10 +21,10 @@ import static io.netty.handler.codec.http2.Http2CodecUtil.DEFAULT_PRIORITY_WEIGH
|
|||||||
import static io.netty.handler.codec.http2.Http2CodecUtil.SMALLEST_MAX_CONCURRENT_STREAMS;
|
import static io.netty.handler.codec.http2.Http2CodecUtil.SMALLEST_MAX_CONCURRENT_STREAMS;
|
||||||
import static io.netty.handler.codec.http2.Http2Error.CANCEL;
|
import static io.netty.handler.codec.http2.Http2Error.CANCEL;
|
||||||
import static io.netty.handler.codec.http2.Http2Stream.State.HALF_CLOSED_LOCAL;
|
import static io.netty.handler.codec.http2.Http2Stream.State.HALF_CLOSED_LOCAL;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
import static org.junit.Assert.assertNotNull;
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
import static org.mockito.Mockito.any;
|
import static org.mockito.Mockito.any;
|
||||||
import static org.mockito.Mockito.anyBoolean;
|
import static org.mockito.Mockito.anyBoolean;
|
||||||
import static org.mockito.Mockito.anyInt;
|
import static org.mockito.Mockito.anyInt;
|
||||||
@ -53,9 +53,9 @@ import io.netty.handler.codec.http2.StreamBufferingEncoder.Http2GoAwayException;
|
|||||||
import io.netty.util.ReferenceCountUtil;
|
import io.netty.util.ReferenceCountUtil;
|
||||||
import io.netty.util.concurrent.EventExecutor;
|
import io.netty.util.concurrent.EventExecutor;
|
||||||
import io.netty.util.concurrent.ImmediateEventExecutor;
|
import io.netty.util.concurrent.ImmediateEventExecutor;
|
||||||
import org.junit.After;
|
import org.junit.jupiter.api.AfterEach;
|
||||||
import org.junit.Before;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.mockito.ArgumentCaptor;
|
import org.mockito.ArgumentCaptor;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.MockitoAnnotations;
|
import org.mockito.MockitoAnnotations;
|
||||||
@ -96,7 +96,7 @@ public class StreamBufferingEncoderTest {
|
|||||||
/**
|
/**
|
||||||
* Init fields and do mocking.
|
* Init fields and do mocking.
|
||||||
*/
|
*/
|
||||||
@Before
|
@BeforeEach
|
||||||
public void setup() throws Exception {
|
public void setup() throws Exception {
|
||||||
MockitoAnnotations.initMocks(this);
|
MockitoAnnotations.initMocks(this);
|
||||||
|
|
||||||
@ -155,7 +155,7 @@ public class StreamBufferingEncoderTest {
|
|||||||
handler.handlerAdded(ctx);
|
handler.handlerAdded(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@After
|
@AfterEach
|
||||||
public void teardown() {
|
public void teardown() {
|
||||||
// Close and release any buffered frames.
|
// Close and release any buffered frames.
|
||||||
encoder.close();
|
encoder.close();
|
||||||
|
@ -17,8 +17,9 @@ package io.netty.handler.codec.http2;
|
|||||||
import io.netty.handler.codec.http2.Http2TestUtil.TestStreamByteDistributorStreamState;
|
import io.netty.handler.codec.http2.Http2TestUtil.TestStreamByteDistributorStreamState;
|
||||||
import io.netty.util.collection.IntObjectHashMap;
|
import io.netty.util.collection.IntObjectHashMap;
|
||||||
import io.netty.util.collection.IntObjectMap;
|
import io.netty.util.collection.IntObjectMap;
|
||||||
import org.junit.Before;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.function.Executable;
|
||||||
import org.mockito.ArgumentCaptor;
|
import org.mockito.ArgumentCaptor;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.MockitoAnnotations;
|
import org.mockito.MockitoAnnotations;
|
||||||
@ -28,11 +29,11 @@ import org.mockito.verification.VerificationMode;
|
|||||||
|
|
||||||
import static io.netty.handler.codec.http2.Http2CodecUtil.DEFAULT_MIN_ALLOCATION_CHUNK;
|
import static io.netty.handler.codec.http2.Http2CodecUtil.DEFAULT_MIN_ALLOCATION_CHUNK;
|
||||||
import static io.netty.handler.codec.http2.Http2CodecUtil.DEFAULT_PRIORITY_WEIGHT;
|
import static io.netty.handler.codec.http2.Http2CodecUtil.DEFAULT_PRIORITY_WEIGHT;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
import static org.junit.Assert.assertSame;
|
import static org.junit.jupiter.api.Assertions.assertSame;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
import static org.junit.Assert.fail;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
import static org.mockito.Mockito.any;
|
import static org.mockito.Mockito.any;
|
||||||
import static org.mockito.Mockito.anyInt;
|
import static org.mockito.Mockito.anyInt;
|
||||||
import static org.mockito.Mockito.atMost;
|
import static org.mockito.Mockito.atMost;
|
||||||
@ -63,7 +64,7 @@ public class UniformStreamByteDistributorTest {
|
|||||||
@Mock
|
@Mock
|
||||||
private StreamByteDistributor.Writer writer;
|
private StreamByteDistributor.Writer writer;
|
||||||
|
|
||||||
@Before
|
@BeforeEach
|
||||||
public void setup() throws Http2Exception {
|
public void setup() throws Http2Exception {
|
||||||
MockitoAnnotations.initMocks(this);
|
MockitoAnnotations.initMocks(this);
|
||||||
|
|
||||||
@ -130,14 +131,15 @@ public class UniformStreamByteDistributorTest {
|
|||||||
Exception fakeException = new RuntimeException("Fake exception");
|
Exception fakeException = new RuntimeException("Fake exception");
|
||||||
doThrow(fakeException).when(writer).write(same(stream(STREAM_C)), eq(3));
|
doThrow(fakeException).when(writer).write(same(stream(STREAM_C)), eq(3));
|
||||||
|
|
||||||
try {
|
Http2Exception e = assertThrows(Http2Exception.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
write(10);
|
write(10);
|
||||||
fail("Expected an exception");
|
}
|
||||||
} catch (Http2Exception e) {
|
});
|
||||||
assertFalse(Http2Exception.isStreamError(e));
|
assertFalse(Http2Exception.isStreamError(e));
|
||||||
assertEquals(Http2Error.INTERNAL_ERROR, e.error());
|
assertEquals(Http2Error.INTERNAL_ERROR, e.error());
|
||||||
assertSame(fakeException, e.getCause());
|
assertSame(fakeException, e.getCause());
|
||||||
}
|
|
||||||
|
|
||||||
verifyWrite(atMost(1), STREAM_A, 1);
|
verifyWrite(atMost(1), STREAM_A, 1);
|
||||||
verifyWrite(atMost(1), STREAM_B, 2);
|
verifyWrite(atMost(1), STREAM_B, 2);
|
||||||
|
@ -14,17 +14,17 @@
|
|||||||
*/
|
*/
|
||||||
package io.netty.handler.codec.http2;
|
package io.netty.handler.codec.http2;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.mockito.MockitoAnnotations;
|
import org.mockito.MockitoAnnotations;
|
||||||
|
|
||||||
import static io.netty.handler.codec.http2.Http2CodecUtil.DEFAULT_PRIORITY_WEIGHT;
|
import static io.netty.handler.codec.http2.Http2CodecUtil.DEFAULT_PRIORITY_WEIGHT;
|
||||||
import static io.netty.handler.codec.http2.Http2CodecUtil.MAX_WEIGHT;
|
import static io.netty.handler.codec.http2.Http2CodecUtil.MAX_WEIGHT;
|
||||||
import static io.netty.handler.codec.http2.Http2CodecUtil.MIN_WEIGHT;
|
import static io.netty.handler.codec.http2.Http2CodecUtil.MIN_WEIGHT;
|
||||||
import static io.netty.handler.codec.http2.WeightedFairQueueByteDistributor.INITIAL_CHILDREN_MAP_SIZE;
|
import static io.netty.handler.codec.http2.WeightedFairQueueByteDistributor.INITIAL_CHILDREN_MAP_SIZE;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
import static org.mockito.Mockito.any;
|
import static org.mockito.Mockito.any;
|
||||||
import static org.mockito.Mockito.anyInt;
|
import static org.mockito.Mockito.anyInt;
|
||||||
import static org.mockito.Mockito.doAnswer;
|
import static org.mockito.Mockito.doAnswer;
|
||||||
@ -42,7 +42,7 @@ public class WeightedFairQueueByteDistributorDependencyTreeTest extends
|
|||||||
private static final short speculativeWeight = 1;
|
private static final short speculativeWeight = 1;
|
||||||
private static final short followersWeight = 1;
|
private static final short followersWeight = 1;
|
||||||
|
|
||||||
@Before
|
@BeforeEach
|
||||||
public void setup() throws Http2Exception {
|
public void setup() throws Http2Exception {
|
||||||
MockitoAnnotations.initMocks(this);
|
MockitoAnnotations.initMocks(this);
|
||||||
|
|
||||||
|
@ -14,18 +14,19 @@
|
|||||||
*/
|
*/
|
||||||
package io.netty.handler.codec.http2;
|
package io.netty.handler.codec.http2;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.function.Executable;
|
||||||
import org.mockito.ArgumentCaptor;
|
import org.mockito.ArgumentCaptor;
|
||||||
import org.mockito.MockitoAnnotations;
|
import org.mockito.MockitoAnnotations;
|
||||||
import org.mockito.verification.VerificationMode;
|
import org.mockito.verification.VerificationMode;
|
||||||
|
|
||||||
import static io.netty.handler.codec.http2.Http2CodecUtil.DEFAULT_PRIORITY_WEIGHT;
|
import static io.netty.handler.codec.http2.Http2CodecUtil.DEFAULT_PRIORITY_WEIGHT;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
import static org.junit.Assert.assertSame;
|
import static org.junit.jupiter.api.Assertions.assertSame;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
import static org.junit.Assert.fail;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
import static org.mockito.Mockito.any;
|
import static org.mockito.Mockito.any;
|
||||||
import static org.mockito.Mockito.anyInt;
|
import static org.mockito.Mockito.anyInt;
|
||||||
import static org.mockito.Mockito.atLeastOnce;
|
import static org.mockito.Mockito.atLeastOnce;
|
||||||
@ -47,7 +48,7 @@ public class WeightedFairQueueByteDistributorTest extends AbstractWeightedFairQu
|
|||||||
private static final int STREAM_E = 9;
|
private static final int STREAM_E = 9;
|
||||||
private static final int ALLOCATION_QUANTUM = 100;
|
private static final int ALLOCATION_QUANTUM = 100;
|
||||||
|
|
||||||
@Before
|
@BeforeEach
|
||||||
public void setup() throws Http2Exception {
|
public void setup() throws Http2Exception {
|
||||||
MockitoAnnotations.initMocks(this);
|
MockitoAnnotations.initMocks(this);
|
||||||
|
|
||||||
@ -152,14 +153,15 @@ public class WeightedFairQueueByteDistributorTest extends AbstractWeightedFairQu
|
|||||||
Exception fakeException = new RuntimeException("Fake exception");
|
Exception fakeException = new RuntimeException("Fake exception");
|
||||||
doThrow(fakeException).when(writer).write(same(stream(STREAM_C)), eq(3));
|
doThrow(fakeException).when(writer).write(same(stream(STREAM_C)), eq(3));
|
||||||
|
|
||||||
try {
|
Http2Exception e = assertThrows(Http2Exception.class, new Executable() {
|
||||||
|
@Override
|
||||||
|
public void execute() throws Throwable {
|
||||||
write(10);
|
write(10);
|
||||||
fail("Expected an exception");
|
}
|
||||||
} catch (Http2Exception e) {
|
});
|
||||||
assertFalse(Http2Exception.isStreamError(e));
|
assertFalse(Http2Exception.isStreamError(e));
|
||||||
assertEquals(Http2Error.INTERNAL_ERROR, e.error());
|
assertEquals(Http2Error.INTERNAL_ERROR, e.error());
|
||||||
assertSame(fakeException, e.getCause());
|
assertSame(fakeException, e.getCause());
|
||||||
}
|
|
||||||
|
|
||||||
verifyWrite(atMost(1), STREAM_A, 1);
|
verifyWrite(atMost(1), STREAM_A, 1);
|
||||||
verifyWrite(atMost(1), STREAM_B, 2);
|
verifyWrite(atMost(1), STREAM_B, 2);
|
||||||
|
Loading…
Reference in New Issue
Block a user