2015-11-04 21:46:03 +01:00
|
|
|
/*
|
|
|
|
* Copyright 2015 The Netty Project
|
|
|
|
*
|
|
|
|
* The Netty Project licenses this file to you under the Apache License,
|
|
|
|
* version 2.0 (the "License"); you may not use this file except in compliance
|
|
|
|
* with the License. You may obtain a copy of the License at:
|
|
|
|
*
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
|
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
|
|
* License for the specific language governing permissions and limitations
|
|
|
|
* under the License.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Copyright 2014 Twitter, Inc.
|
|
|
|
*
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
*
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
|
|
|
*/
|
2016-04-12 14:22:41 +02:00
|
|
|
package io.netty.handler.codec.http2.internal.hpack;
|
2015-11-04 21:46:03 +01:00
|
|
|
|
2016-05-30 13:40:08 +02:00
|
|
|
import io.netty.buffer.ByteBuf;
|
|
|
|
import io.netty.buffer.Unpooled;
|
2016-08-05 09:09:43 +02:00
|
|
|
import io.netty.handler.codec.http2.Http2Exception;
|
2016-05-30 13:40:08 +02:00
|
|
|
import io.netty.handler.codec.http2.Http2Headers;
|
2016-05-10 18:09:37 +02:00
|
|
|
import org.junit.Before;
|
|
|
|
import org.junit.Test;
|
|
|
|
|
2017-01-13 05:44:52 +01:00
|
|
|
import static io.netty.handler.codec.http2.internal.hpack.Decoder.decodeULE128;
|
2016-05-30 13:40:08 +02:00
|
|
|
import static io.netty.util.AsciiString.EMPTY_STRING;
|
|
|
|
import static io.netty.util.AsciiString.of;
|
2016-08-13 04:27:32 +02:00
|
|
|
import static java.lang.Integer.MAX_VALUE;
|
2015-11-04 21:46:03 +01:00
|
|
|
import static org.junit.Assert.assertEquals;
|
|
|
|
import static org.mockito.Mockito.mock;
|
|
|
|
import static org.mockito.Mockito.reset;
|
|
|
|
import static org.mockito.Mockito.times;
|
|
|
|
import static org.mockito.Mockito.verify;
|
|
|
|
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
|
|
|
|
|
|
|
public class DecoderTest {
|
|
|
|
private Decoder decoder;
|
2016-05-30 13:40:08 +02:00
|
|
|
private Http2Headers mockHeaders;
|
2015-11-04 21:46:03 +01:00
|
|
|
|
|
|
|
private static String hex(String s) {
|
|
|
|
return Hex.encodeHexString(s.getBytes());
|
|
|
|
}
|
|
|
|
|
2016-08-05 09:09:43 +02:00
|
|
|
private void decode(String encoded) throws Http2Exception {
|
2015-11-04 21:46:03 +01:00
|
|
|
byte[] b = Hex.decodeHex(encoded.toCharArray());
|
2016-05-30 13:40:08 +02:00
|
|
|
ByteBuf in = Unpooled.wrappedBuffer(b);
|
2016-05-10 18:09:37 +02:00
|
|
|
try {
|
2016-09-16 15:57:33 +02:00
|
|
|
decoder.decode(0, in, mockHeaders);
|
2016-05-10 18:09:37 +02:00
|
|
|
} finally {
|
2016-05-30 13:40:08 +02:00
|
|
|
in.release();
|
2016-05-10 18:09:37 +02:00
|
|
|
}
|
2015-11-04 21:46:03 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
@Before
|
2016-09-16 15:57:33 +02:00
|
|
|
public void setUp() throws Http2Exception {
|
2017-01-14 02:09:44 +01:00
|
|
|
decoder = new Decoder(8192, 32);
|
2016-05-30 13:40:08 +02:00
|
|
|
mockHeaders = mock(Http2Headers.class);
|
2015-11-04 21:46:03 +01:00
|
|
|
}
|
|
|
|
|
2017-01-13 05:44:52 +01:00
|
|
|
@Test
|
|
|
|
public void testDecodeULE128IntMax() throws Http2Exception {
|
|
|
|
byte[] input = {(byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0x07};
|
|
|
|
ByteBuf in = Unpooled.wrappedBuffer(input);
|
|
|
|
try {
|
|
|
|
assertEquals(Integer.MAX_VALUE, decodeULE128(in, 0));
|
|
|
|
} finally {
|
|
|
|
in.release();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Test(expected = Http2Exception.class)
|
|
|
|
public void testDecodeULE128IntOverflow1() throws Http2Exception {
|
|
|
|
byte[] input = {(byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0x07};
|
|
|
|
ByteBuf in = Unpooled.wrappedBuffer(input);
|
|
|
|
final int readerIndex = in.readerIndex();
|
|
|
|
try {
|
|
|
|
decodeULE128(in, 1);
|
|
|
|
} finally {
|
|
|
|
assertEquals(readerIndex, in.readerIndex());
|
|
|
|
in.release();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Test(expected = Http2Exception.class)
|
|
|
|
public void testDecodeULE128IntOverflow2() throws Http2Exception {
|
|
|
|
byte[] input = {(byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0x08};
|
|
|
|
ByteBuf in = Unpooled.wrappedBuffer(input);
|
|
|
|
final int readerIndex = in.readerIndex();
|
|
|
|
try {
|
|
|
|
decodeULE128(in, 0);
|
|
|
|
} finally {
|
|
|
|
assertEquals(readerIndex, in.readerIndex());
|
|
|
|
in.release();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Test
|
|
|
|
public void testDecodeULE128LongMax() throws Http2Exception {
|
|
|
|
byte[] input = {(byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
|
|
|
|
(byte) 0xFF, (byte) 0x7F};
|
|
|
|
ByteBuf in = Unpooled.wrappedBuffer(input);
|
|
|
|
try {
|
|
|
|
assertEquals(Long.MAX_VALUE, decodeULE128(in, 0L));
|
|
|
|
} finally {
|
|
|
|
in.release();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Test(expected = Http2Exception.class)
|
|
|
|
public void testDecodeULE128LongOverflow1() throws Http2Exception {
|
|
|
|
byte[] input = {(byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
|
|
|
|
(byte) 0xFF, (byte) 0xFF};
|
|
|
|
ByteBuf in = Unpooled.wrappedBuffer(input);
|
|
|
|
final int readerIndex = in.readerIndex();
|
|
|
|
try {
|
|
|
|
decodeULE128(in, 0L);
|
|
|
|
} finally {
|
|
|
|
assertEquals(readerIndex, in.readerIndex());
|
|
|
|
in.release();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Test(expected = Http2Exception.class)
|
|
|
|
public void testDecodeULE128LongOverflow2() throws Http2Exception {
|
|
|
|
byte[] input = {(byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
|
|
|
|
(byte) 0xFF, (byte) 0x7F};
|
|
|
|
ByteBuf in = Unpooled.wrappedBuffer(input);
|
|
|
|
final int readerIndex = in.readerIndex();
|
|
|
|
try {
|
|
|
|
decodeULE128(in, 1L);
|
|
|
|
} finally {
|
|
|
|
assertEquals(readerIndex, in.readerIndex());
|
|
|
|
in.release();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Test
|
|
|
|
public void testSetTableSizeWithMaxUnsigned32BitValueSucceeds() throws Http2Exception {
|
|
|
|
byte[] input = {(byte) 0x3F, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0x0E};
|
|
|
|
ByteBuf in = Unpooled.wrappedBuffer(input);
|
|
|
|
try {
|
|
|
|
final long expectedHeaderSize = 4026531870L; // based on the input above
|
|
|
|
decoder.setMaxHeaderTableSize(expectedHeaderSize);
|
|
|
|
decoder.decode(0, in, mockHeaders);
|
|
|
|
assertEquals(expectedHeaderSize, decoder.getMaxHeaderTableSize());
|
|
|
|
} finally {
|
|
|
|
in.release();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Test(expected = Http2Exception.class)
|
|
|
|
public void testSetTableSizeOverLimitFails() throws Http2Exception {
|
|
|
|
byte[] input = {(byte) 0x3F, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0x0E};
|
|
|
|
ByteBuf in = Unpooled.wrappedBuffer(input);
|
|
|
|
try {
|
|
|
|
decoder.setMaxHeaderTableSize(4026531870L - 1); // based on the input above ... 1 less than is above.
|
|
|
|
decoder.decode(0, in, mockHeaders);
|
|
|
|
} finally {
|
|
|
|
in.release();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-05-10 18:09:37 +02:00
|
|
|
@Test
|
2016-08-05 09:09:43 +02:00
|
|
|
public void testLiteralHuffmanEncodedWithEmptyNameAndValue() throws Http2Exception {
|
2016-05-10 18:09:37 +02:00
|
|
|
byte[] input = {0, (byte) 0x80, 0};
|
2016-05-30 13:40:08 +02:00
|
|
|
ByteBuf in = Unpooled.wrappedBuffer(input);
|
2016-05-10 18:09:37 +02:00
|
|
|
try {
|
2016-09-16 15:57:33 +02:00
|
|
|
decoder.decode(0, in, mockHeaders);
|
2016-05-30 13:40:08 +02:00
|
|
|
verify(mockHeaders, times(1)).add(EMPTY_STRING, EMPTY_STRING);
|
2016-05-10 18:09:37 +02:00
|
|
|
} finally {
|
2016-05-30 13:40:08 +02:00
|
|
|
in.release();
|
2016-05-10 18:09:37 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-05 09:09:43 +02:00
|
|
|
@Test(expected = Http2Exception.class)
|
|
|
|
public void testLiteralHuffmanEncodedWithPaddingGreaterThan7Throws() throws Http2Exception {
|
2016-05-10 18:09:37 +02:00
|
|
|
byte[] input = {0, (byte) 0x81, -1};
|
2016-05-30 13:40:08 +02:00
|
|
|
ByteBuf in = Unpooled.wrappedBuffer(input);
|
2016-05-10 18:09:37 +02:00
|
|
|
try {
|
2016-09-16 15:57:33 +02:00
|
|
|
decoder.decode(0, in, mockHeaders);
|
2016-05-10 18:09:37 +02:00
|
|
|
} finally {
|
2016-05-30 13:40:08 +02:00
|
|
|
in.release();
|
2016-05-10 18:09:37 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-05 09:09:43 +02:00
|
|
|
@Test(expected = Http2Exception.class)
|
|
|
|
public void testLiteralHuffmanEncodedWithDecodingEOSThrows() throws Http2Exception {
|
2016-05-10 18:09:37 +02:00
|
|
|
byte[] input = {0, (byte) 0x84, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF};
|
2016-05-30 13:40:08 +02:00
|
|
|
ByteBuf in = Unpooled.wrappedBuffer(input);
|
2016-05-10 18:09:37 +02:00
|
|
|
try {
|
2016-09-16 15:57:33 +02:00
|
|
|
decoder.decode(0, in, mockHeaders);
|
2016-05-10 18:09:37 +02:00
|
|
|
} finally {
|
2016-05-30 13:40:08 +02:00
|
|
|
in.release();
|
2016-05-10 18:09:37 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-05 09:09:43 +02:00
|
|
|
@Test(expected = Http2Exception.class)
|
|
|
|
public void testLiteralHuffmanEncodedWithPaddingNotCorrespondingToMSBThrows() throws Http2Exception {
|
2016-05-10 18:09:37 +02:00
|
|
|
byte[] input = {0, (byte) 0x81, 0};
|
2016-05-30 13:40:08 +02:00
|
|
|
ByteBuf in = Unpooled.wrappedBuffer(input);
|
2016-05-10 18:09:37 +02:00
|
|
|
try {
|
2016-09-16 15:57:33 +02:00
|
|
|
decoder.decode(0, in, mockHeaders);
|
2016-05-10 18:09:37 +02:00
|
|
|
} finally {
|
2016-05-30 13:40:08 +02:00
|
|
|
in.release();
|
2016-05-10 18:09:37 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-05 09:09:43 +02:00
|
|
|
@Test(expected = Http2Exception.class)
|
2017-01-13 05:44:52 +01:00
|
|
|
public void testIncompleteIndex() throws Http2Exception {
|
2015-11-04 21:46:03 +01:00
|
|
|
byte[] compressed = Hex.decodeHex("FFF0".toCharArray());
|
2016-05-30 13:40:08 +02:00
|
|
|
ByteBuf in = Unpooled.wrappedBuffer(compressed);
|
2016-05-10 18:09:37 +02:00
|
|
|
try {
|
2016-09-16 15:57:33 +02:00
|
|
|
decoder.decode(0, in, mockHeaders);
|
2016-05-30 13:40:08 +02:00
|
|
|
assertEquals(1, in.readableBytes());
|
2016-09-16 15:57:33 +02:00
|
|
|
decoder.decode(0, in, mockHeaders);
|
2016-05-10 18:09:37 +02:00
|
|
|
} finally {
|
2016-05-30 13:40:08 +02:00
|
|
|
in.release();
|
2016-05-10 18:09:37 +02:00
|
|
|
}
|
2015-11-04 21:46:03 +01:00
|
|
|
}
|
|
|
|
|
2016-08-05 09:09:43 +02:00
|
|
|
@Test(expected = Http2Exception.class)
|
|
|
|
public void testUnusedIndex() throws Http2Exception {
|
2015-11-04 21:46:03 +01:00
|
|
|
// Index 0 is not used
|
|
|
|
decode("80");
|
|
|
|
}
|
|
|
|
|
2016-08-05 09:09:43 +02:00
|
|
|
@Test(expected = Http2Exception.class)
|
|
|
|
public void testIllegalIndex() throws Http2Exception {
|
2015-11-04 21:46:03 +01:00
|
|
|
// Index larger than the header table
|
|
|
|
decode("FF00");
|
|
|
|
}
|
|
|
|
|
2016-08-05 09:09:43 +02:00
|
|
|
@Test(expected = Http2Exception.class)
|
|
|
|
public void testInsidiousIndex() throws Http2Exception {
|
2015-11-04 21:46:03 +01:00
|
|
|
// Insidious index so the last shift causes sign overflow
|
2016-08-13 04:27:32 +02:00
|
|
|
decode("FF8080808007");
|
2015-11-04 21:46:03 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
@Test
|
2016-08-05 09:09:43 +02:00
|
|
|
public void testDynamicTableSizeUpdate() throws Http2Exception {
|
2015-11-04 21:46:03 +01:00
|
|
|
decode("20");
|
|
|
|
assertEquals(0, decoder.getMaxHeaderTableSize());
|
|
|
|
decode("3FE11F");
|
|
|
|
assertEquals(4096, decoder.getMaxHeaderTableSize());
|
|
|
|
}
|
|
|
|
|
|
|
|
@Test
|
2016-08-05 09:09:43 +02:00
|
|
|
public void testDynamicTableSizeUpdateRequired() throws Http2Exception {
|
2015-11-04 21:46:03 +01:00
|
|
|
decoder.setMaxHeaderTableSize(32);
|
|
|
|
decode("3F00");
|
|
|
|
assertEquals(31, decoder.getMaxHeaderTableSize());
|
|
|
|
}
|
|
|
|
|
2016-08-05 09:09:43 +02:00
|
|
|
@Test(expected = Http2Exception.class)
|
|
|
|
public void testIllegalDynamicTableSizeUpdate() throws Http2Exception {
|
2015-11-04 21:46:03 +01:00
|
|
|
// max header table size = MAX_HEADER_TABLE_SIZE + 1
|
|
|
|
decode("3FE21F");
|
|
|
|
}
|
|
|
|
|
2016-08-05 09:09:43 +02:00
|
|
|
@Test(expected = Http2Exception.class)
|
|
|
|
public void testInsidiousMaxDynamicTableSize() throws Http2Exception {
|
2016-08-13 04:27:32 +02:00
|
|
|
decoder.setMaxHeaderTableSize(MAX_VALUE);
|
2015-11-04 21:46:03 +01:00
|
|
|
// max header table size sign overflow
|
|
|
|
decode("3FE1FFFFFF07");
|
|
|
|
}
|
|
|
|
|
2016-08-13 04:27:32 +02:00
|
|
|
@Test
|
|
|
|
public void testMaxValidDynamicTableSize() throws Http2Exception {
|
|
|
|
decoder.setMaxHeaderTableSize(MAX_VALUE);
|
|
|
|
String baseValue = "3FE1FFFFFF0";
|
|
|
|
for (int i = 0; i < 7; ++i) {
|
|
|
|
decode(baseValue + i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-11-04 21:46:03 +01:00
|
|
|
@Test
|
2016-08-05 09:09:43 +02:00
|
|
|
public void testReduceMaxDynamicTableSize() throws Http2Exception {
|
2015-11-04 21:46:03 +01:00
|
|
|
decoder.setMaxHeaderTableSize(0);
|
|
|
|
assertEquals(0, decoder.getMaxHeaderTableSize());
|
|
|
|
decode("2081");
|
|
|
|
}
|
|
|
|
|
2016-08-05 09:09:43 +02:00
|
|
|
@Test(expected = Http2Exception.class)
|
|
|
|
public void testTooLargeDynamicTableSizeUpdate() throws Http2Exception {
|
2015-11-04 21:46:03 +01:00
|
|
|
decoder.setMaxHeaderTableSize(0);
|
|
|
|
assertEquals(0, decoder.getMaxHeaderTableSize());
|
|
|
|
decode("21"); // encoder max header table size not small enough
|
|
|
|
}
|
|
|
|
|
2016-08-05 09:09:43 +02:00
|
|
|
@Test(expected = Http2Exception.class)
|
|
|
|
public void testMissingDynamicTableSizeUpdate() throws Http2Exception {
|
2015-11-04 21:46:03 +01:00
|
|
|
decoder.setMaxHeaderTableSize(0);
|
|
|
|
assertEquals(0, decoder.getMaxHeaderTableSize());
|
|
|
|
decode("81");
|
|
|
|
}
|
|
|
|
|
2016-05-10 18:09:37 +02:00
|
|
|
@Test
|
2016-08-05 09:09:43 +02:00
|
|
|
public void testLiteralWithIncrementalIndexingWithEmptyName() throws Http2Exception {
|
2016-05-10 18:09:37 +02:00
|
|
|
decode("400005" + hex("value"));
|
2016-05-30 13:40:08 +02:00
|
|
|
verify(mockHeaders, times(1)).add(EMPTY_STRING, of("value"));
|
2015-11-04 21:46:03 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
@Test
|
2016-08-05 09:09:43 +02:00
|
|
|
public void testLiteralWithIncrementalIndexingCompleteEviction() throws Http2Exception {
|
2015-11-04 21:46:03 +01:00
|
|
|
// Verify indexed host header
|
|
|
|
decode("4004" + hex("name") + "05" + hex("value"));
|
2016-05-30 13:40:08 +02:00
|
|
|
verify(mockHeaders).add(of("name"), of("value"));
|
|
|
|
verifyNoMoreInteractions(mockHeaders);
|
2015-11-04 21:46:03 +01:00
|
|
|
|
2016-05-30 13:40:08 +02:00
|
|
|
reset(mockHeaders);
|
2015-11-04 21:46:03 +01:00
|
|
|
StringBuilder sb = new StringBuilder();
|
|
|
|
for (int i = 0; i < 4096; i++) {
|
2016-05-30 13:40:08 +02:00
|
|
|
sb.append('a');
|
2015-11-04 21:46:03 +01:00
|
|
|
}
|
|
|
|
String value = sb.toString();
|
|
|
|
sb = new StringBuilder();
|
|
|
|
sb.append("417F811F");
|
|
|
|
for (int i = 0; i < 4096; i++) {
|
|
|
|
sb.append("61"); // 'a'
|
|
|
|
}
|
|
|
|
decode(sb.toString());
|
2016-05-30 13:40:08 +02:00
|
|
|
verify(mockHeaders).add(of(":authority"), of(value));
|
|
|
|
verifyNoMoreInteractions(mockHeaders);
|
2016-08-05 09:09:43 +02:00
|
|
|
reset(mockHeaders);
|
2015-11-04 21:46:03 +01:00
|
|
|
|
|
|
|
// Verify next header is inserted at index 62
|
|
|
|
decode("4004" + hex("name") + "05" + hex("value") + "BE");
|
2016-05-30 13:40:08 +02:00
|
|
|
verify(mockHeaders, times(2)).add(of("name"), of("value"));
|
|
|
|
verifyNoMoreInteractions(mockHeaders);
|
2015-11-04 21:46:03 +01:00
|
|
|
}
|
|
|
|
|
2016-08-05 09:09:43 +02:00
|
|
|
@Test(expected = Http2Exception.class)
|
|
|
|
public void testLiteralWithIncrementalIndexingWithLargeValue() throws Http2Exception {
|
2015-11-04 21:46:03 +01:00
|
|
|
// Ignore header that exceeds max header size
|
|
|
|
StringBuilder sb = new StringBuilder();
|
|
|
|
sb.append("4004");
|
|
|
|
sb.append(hex("name"));
|
|
|
|
sb.append("7F813F");
|
|
|
|
for (int i = 0; i < 8192; i++) {
|
|
|
|
sb.append("61"); // 'a'
|
|
|
|
}
|
|
|
|
decode(sb.toString());
|
|
|
|
}
|
|
|
|
|
2016-05-10 18:09:37 +02:00
|
|
|
@Test
|
2016-08-05 09:09:43 +02:00
|
|
|
public void testLiteralWithoutIndexingWithEmptyName() throws Http2Exception {
|
2015-11-04 21:46:03 +01:00
|
|
|
decode("000005" + hex("value"));
|
2016-05-30 13:40:08 +02:00
|
|
|
verify(mockHeaders, times(1)).add(EMPTY_STRING, of("value"));
|
2015-11-04 21:46:03 +01:00
|
|
|
}
|
|
|
|
|
2016-08-05 09:09:43 +02:00
|
|
|
@Test(expected = Http2Exception.class)
|
|
|
|
public void testLiteralWithoutIndexingWithLargeName() throws Http2Exception {
|
2015-11-04 21:46:03 +01:00
|
|
|
// Ignore header name that exceeds max header size
|
|
|
|
StringBuilder sb = new StringBuilder();
|
|
|
|
sb.append("007F817F");
|
|
|
|
for (int i = 0; i < 16384; i++) {
|
|
|
|
sb.append("61"); // 'a'
|
|
|
|
}
|
|
|
|
sb.append("00");
|
|
|
|
decode(sb.toString());
|
|
|
|
}
|
|
|
|
|
2016-08-05 09:09:43 +02:00
|
|
|
@Test(expected = Http2Exception.class)
|
|
|
|
public void testLiteralWithoutIndexingWithLargeValue() throws Http2Exception {
|
2015-11-04 21:46:03 +01:00
|
|
|
// Ignore header that exceeds max header size
|
|
|
|
StringBuilder sb = new StringBuilder();
|
|
|
|
sb.append("0004");
|
|
|
|
sb.append(hex("name"));
|
|
|
|
sb.append("7F813F");
|
|
|
|
for (int i = 0; i < 8192; i++) {
|
|
|
|
sb.append("61"); // 'a'
|
|
|
|
}
|
|
|
|
decode(sb.toString());
|
|
|
|
}
|
|
|
|
|
2016-05-10 18:09:37 +02:00
|
|
|
@Test
|
2016-08-05 09:09:43 +02:00
|
|
|
public void testLiteralNeverIndexedWithEmptyName() throws Http2Exception {
|
2015-11-04 21:46:03 +01:00
|
|
|
decode("100005" + hex("value"));
|
2016-05-30 13:40:08 +02:00
|
|
|
verify(mockHeaders, times(1)).add(EMPTY_STRING, of("value"));
|
2015-11-04 21:46:03 +01:00
|
|
|
}
|
|
|
|
|
2016-08-05 09:09:43 +02:00
|
|
|
@Test(expected = Http2Exception.class)
|
|
|
|
public void testLiteralNeverIndexedWithLargeName() throws Http2Exception {
|
2015-11-04 21:46:03 +01:00
|
|
|
// Ignore header name that exceeds max header size
|
|
|
|
StringBuilder sb = new StringBuilder();
|
|
|
|
sb.append("107F817F");
|
|
|
|
for (int i = 0; i < 16384; i++) {
|
|
|
|
sb.append("61"); // 'a'
|
|
|
|
}
|
|
|
|
sb.append("00");
|
|
|
|
decode(sb.toString());
|
|
|
|
}
|
|
|
|
|
2016-08-05 09:09:43 +02:00
|
|
|
@Test(expected = Http2Exception.class)
|
|
|
|
public void testLiteralNeverIndexedWithLargeValue() throws Http2Exception {
|
2015-11-04 21:46:03 +01:00
|
|
|
// Ignore header that exceeds max header size
|
|
|
|
StringBuilder sb = new StringBuilder();
|
|
|
|
sb.append("1004");
|
|
|
|
sb.append(hex("name"));
|
|
|
|
sb.append("7F813F");
|
|
|
|
for (int i = 0; i < 8192; i++) {
|
|
|
|
sb.append("61"); // 'a'
|
|
|
|
}
|
|
|
|
decode(sb.toString());
|
|
|
|
}
|
|
|
|
}
|