@Test public void testLiteralWithoutIndexingWithEmptyName() throws Http2Exception { decode("000005" + hex("value")); verify(mockHeaders, times(1)).add(EMPTY_STRING, of("value")); }
public void decode(int streamId, ByteBuf in, Http2Headers headers) throws Http2Exception { int index = 0; long headersLength = 0; int nameLength = 0; int valueLength = 0; byte state = READ_HEADER_REPRESENTATION; boolean huffmanEncoded = false; CharSequence name = null; IndexType indexType = IndexType.NONE; while (in.isReadable()) { switch (state) { case READ_HEADER_REPRESENTATION: byte b = in.readByte(); if (maxDynamicTableSizeChangeRequired && (b & 0xE0) != 0x20) { throw MAX_DYNAMIC_TABLE_SIZE_CHANGE_REQUIRED; } if (b < 0) { index = b & 0x7F; switch (index) { case 0: throw DECODE_ILLEGAL_INDEX_VALUE; case 0x7F: state = READ_INDEXED_HEADER; break; default: headersLength = indexHeader(streamId, index, headers, headersLength); } } else if ((b & 0x40) == 0x40) { indexType = IndexType.INCREMENTAL; index = b & 0x3F; switch (index) { case 0: state = READ_LITERAL_HEADER_NAME_LENGTH_PREFIX; break; case 0x3F: state = READ_INDEXED_HEADER_NAME; break; default: name = readName(index); state = READ_LITERAL_HEADER_VALUE_LENGTH_PREFIX; } } else if ((b & 0x20) == 0x20) { index = b & 0x1F; if (index == 0x1F) { state = READ_MAX_DYNAMIC_TABLE_SIZE; } else { setDynamicTableSize(index); state = READ_HEADER_REPRESENTATION; } } else { indexType = ((b & 0x10) == 0x10) ? IndexType.NEVER : IndexType.NONE; index = b & 0x0F; switch (index) { case 0: state = READ_LITERAL_HEADER_NAME_LENGTH_PREFIX; break; case 0x0F: state = READ_INDEXED_HEADER_NAME; break; default: name = readName(index); state = READ_LITERAL_HEADER_VALUE_LENGTH_PREFIX; } } break; case READ_MAX_DYNAMIC_TABLE_SIZE: setDynamicTableSize(decodeULE128(in, (long) index)); state = READ_HEADER_REPRESENTATION; break; case READ_INDEXED_HEADER: headersLength = indexHeader(streamId, decodeULE128(in, index), headers, headersLength); state = READ_HEADER_REPRESENTATION; break; case READ_INDEXED_HEADER_NAME: name = readName(decodeULE128(in, index)); state = READ_LITERAL_HEADER_VALUE_LENGTH_PREFIX; break; case READ_LITERAL_HEADER_NAME_LENGTH_PREFIX: b = in.readByte(); huffmanEncoded = (b & 0x80) == 0x80; index = b & 0x7F; if (index == 0x7f) { state = READ_LITERAL_HEADER_NAME_LENGTH; } else { if (index > maxHeaderListSizeGoAway - headersLength) { headerListSizeExceeded(maxHeaderListSizeGoAway); } nameLength = index; state = READ_LITERAL_HEADER_NAME; } break; case READ_LITERAL_HEADER_NAME_LENGTH: nameLength = decodeULE128(in, index); if (nameLength > maxHeaderListSizeGoAway - headersLength) { headerListSizeExceeded(maxHeaderListSizeGoAway); } state = READ_LITERAL_HEADER_NAME; break; case READ_LITERAL_HEADER_NAME: if (in.readableBytes() < nameLength) { throw notEnoughDataException(in); } name = readStringLiteral(in, nameLength, huffmanEncoded); state = READ_LITERAL_HEADER_VALUE_LENGTH_PREFIX; break; case READ_LITERAL_HEADER_VALUE_LENGTH_PREFIX: b = in.readByte(); huffmanEncoded = (b & 0x80) == 0x80; index = b & 0x7F; switch (index) { case 0x7f: state = READ_LITERAL_HEADER_VALUE_LENGTH; break; case 0: headersLength = insertHeader(streamId, headers, name, EMPTY_STRING, indexType, headersLength); state = READ_HEADER_REPRESENTATION; break; default: if ((long) index + nameLength > maxHeaderListSizeGoAway - headersLength) { headerListSizeExceeded(maxHeaderListSizeGoAway); } valueLength = index; state = READ_LITERAL_HEADER_VALUE; } break; case READ_LITERAL_HEADER_VALUE_LENGTH: valueLength = decodeULE128(in, index); if ((long) valueLength + nameLength > maxHeaderListSizeGoAway - headersLength) { headerListSizeExceeded(maxHeaderListSizeGoAway); } state = READ_LITERAL_HEADER_VALUE; break; case READ_LITERAL_HEADER_VALUE: if (in.readableBytes() < valueLength) { throw notEnoughDataException(in); } CharSequence value = readStringLiteral(in, valueLength, huffmanEncoded); headersLength = insertHeader(streamId, headers, name, value, indexType, headersLength); state = READ_HEADER_REPRESENTATION; break; default: throw new Error("should not reach here state: " + state); } } if (headersLength > maxHeaderListSize) { headerListSizeExceeded(streamId, maxHeaderListSize, true); } }
HpackDecoder { public void decode(int streamId, ByteBuf in, Http2Headers headers) throws Http2Exception { int index = 0; long headersLength = 0; int nameLength = 0; int valueLength = 0; byte state = READ_HEADER_REPRESENTATION; boolean huffmanEncoded = false; CharSequence name = null; IndexType indexType = IndexType.NONE; while (in.isReadable()) { switch (state) { case READ_HEADER_REPRESENTATION: byte b = in.readByte(); if (maxDynamicTableSizeChangeRequired && (b & 0xE0) != 0x20) { throw MAX_DYNAMIC_TABLE_SIZE_CHANGE_REQUIRED; } if (b < 0) { index = b & 0x7F; switch (index) { case 0: throw DECODE_ILLEGAL_INDEX_VALUE; case 0x7F: state = READ_INDEXED_HEADER; break; default: headersLength = indexHeader(streamId, index, headers, headersLength); } } else if ((b & 0x40) == 0x40) { indexType = IndexType.INCREMENTAL; index = b & 0x3F; switch (index) { case 0: state = READ_LITERAL_HEADER_NAME_LENGTH_PREFIX; break; case 0x3F: state = READ_INDEXED_HEADER_NAME; break; default: name = readName(index); state = READ_LITERAL_HEADER_VALUE_LENGTH_PREFIX; } } else if ((b & 0x20) == 0x20) { index = b & 0x1F; if (index == 0x1F) { state = READ_MAX_DYNAMIC_TABLE_SIZE; } else { setDynamicTableSize(index); state = READ_HEADER_REPRESENTATION; } } else { indexType = ((b & 0x10) == 0x10) ? IndexType.NEVER : IndexType.NONE; index = b & 0x0F; switch (index) { case 0: state = READ_LITERAL_HEADER_NAME_LENGTH_PREFIX; break; case 0x0F: state = READ_INDEXED_HEADER_NAME; break; default: name = readName(index); state = READ_LITERAL_HEADER_VALUE_LENGTH_PREFIX; } } break; case READ_MAX_DYNAMIC_TABLE_SIZE: setDynamicTableSize(decodeULE128(in, (long) index)); state = READ_HEADER_REPRESENTATION; break; case READ_INDEXED_HEADER: headersLength = indexHeader(streamId, decodeULE128(in, index), headers, headersLength); state = READ_HEADER_REPRESENTATION; break; case READ_INDEXED_HEADER_NAME: name = readName(decodeULE128(in, index)); state = READ_LITERAL_HEADER_VALUE_LENGTH_PREFIX; break; case READ_LITERAL_HEADER_NAME_LENGTH_PREFIX: b = in.readByte(); huffmanEncoded = (b & 0x80) == 0x80; index = b & 0x7F; if (index == 0x7f) { state = READ_LITERAL_HEADER_NAME_LENGTH; } else { if (index > maxHeaderListSizeGoAway - headersLength) { headerListSizeExceeded(maxHeaderListSizeGoAway); } nameLength = index; state = READ_LITERAL_HEADER_NAME; } break; case READ_LITERAL_HEADER_NAME_LENGTH: nameLength = decodeULE128(in, index); if (nameLength > maxHeaderListSizeGoAway - headersLength) { headerListSizeExceeded(maxHeaderListSizeGoAway); } state = READ_LITERAL_HEADER_NAME; break; case READ_LITERAL_HEADER_NAME: if (in.readableBytes() < nameLength) { throw notEnoughDataException(in); } name = readStringLiteral(in, nameLength, huffmanEncoded); state = READ_LITERAL_HEADER_VALUE_LENGTH_PREFIX; break; case READ_LITERAL_HEADER_VALUE_LENGTH_PREFIX: b = in.readByte(); huffmanEncoded = (b & 0x80) == 0x80; index = b & 0x7F; switch (index) { case 0x7f: state = READ_LITERAL_HEADER_VALUE_LENGTH; break; case 0: headersLength = insertHeader(streamId, headers, name, EMPTY_STRING, indexType, headersLength); state = READ_HEADER_REPRESENTATION; break; default: if ((long) index + nameLength > maxHeaderListSizeGoAway - headersLength) { headerListSizeExceeded(maxHeaderListSizeGoAway); } valueLength = index; state = READ_LITERAL_HEADER_VALUE; } break; case READ_LITERAL_HEADER_VALUE_LENGTH: valueLength = decodeULE128(in, index); if ((long) valueLength + nameLength > maxHeaderListSizeGoAway - headersLength) { headerListSizeExceeded(maxHeaderListSizeGoAway); } state = READ_LITERAL_HEADER_VALUE; break; case READ_LITERAL_HEADER_VALUE: if (in.readableBytes() < valueLength) { throw notEnoughDataException(in); } CharSequence value = readStringLiteral(in, valueLength, huffmanEncoded); headersLength = insertHeader(streamId, headers, name, value, indexType, headersLength); state = READ_HEADER_REPRESENTATION; break; default: throw new Error("should not reach here state: " + state); } } if (headersLength > maxHeaderListSize) { headerListSizeExceeded(streamId, maxHeaderListSize, true); } } }
HpackDecoder { public void decode(int streamId, ByteBuf in, Http2Headers headers) throws Http2Exception { int index = 0; long headersLength = 0; int nameLength = 0; int valueLength = 0; byte state = READ_HEADER_REPRESENTATION; boolean huffmanEncoded = false; CharSequence name = null; IndexType indexType = IndexType.NONE; while (in.isReadable()) { switch (state) { case READ_HEADER_REPRESENTATION: byte b = in.readByte(); if (maxDynamicTableSizeChangeRequired && (b & 0xE0) != 0x20) { throw MAX_DYNAMIC_TABLE_SIZE_CHANGE_REQUIRED; } if (b < 0) { index = b & 0x7F; switch (index) { case 0: throw DECODE_ILLEGAL_INDEX_VALUE; case 0x7F: state = READ_INDEXED_HEADER; break; default: headersLength = indexHeader(streamId, index, headers, headersLength); } } else if ((b & 0x40) == 0x40) { indexType = IndexType.INCREMENTAL; index = b & 0x3F; switch (index) { case 0: state = READ_LITERAL_HEADER_NAME_LENGTH_PREFIX; break; case 0x3F: state = READ_INDEXED_HEADER_NAME; break; default: name = readName(index); state = READ_LITERAL_HEADER_VALUE_LENGTH_PREFIX; } } else if ((b & 0x20) == 0x20) { index = b & 0x1F; if (index == 0x1F) { state = READ_MAX_DYNAMIC_TABLE_SIZE; } else { setDynamicTableSize(index); state = READ_HEADER_REPRESENTATION; } } else { indexType = ((b & 0x10) == 0x10) ? IndexType.NEVER : IndexType.NONE; index = b & 0x0F; switch (index) { case 0: state = READ_LITERAL_HEADER_NAME_LENGTH_PREFIX; break; case 0x0F: state = READ_INDEXED_HEADER_NAME; break; default: name = readName(index); state = READ_LITERAL_HEADER_VALUE_LENGTH_PREFIX; } } break; case READ_MAX_DYNAMIC_TABLE_SIZE: setDynamicTableSize(decodeULE128(in, (long) index)); state = READ_HEADER_REPRESENTATION; break; case READ_INDEXED_HEADER: headersLength = indexHeader(streamId, decodeULE128(in, index), headers, headersLength); state = READ_HEADER_REPRESENTATION; break; case READ_INDEXED_HEADER_NAME: name = readName(decodeULE128(in, index)); state = READ_LITERAL_HEADER_VALUE_LENGTH_PREFIX; break; case READ_LITERAL_HEADER_NAME_LENGTH_PREFIX: b = in.readByte(); huffmanEncoded = (b & 0x80) == 0x80; index = b & 0x7F; if (index == 0x7f) { state = READ_LITERAL_HEADER_NAME_LENGTH; } else { if (index > maxHeaderListSizeGoAway - headersLength) { headerListSizeExceeded(maxHeaderListSizeGoAway); } nameLength = index; state = READ_LITERAL_HEADER_NAME; } break; case READ_LITERAL_HEADER_NAME_LENGTH: nameLength = decodeULE128(in, index); if (nameLength > maxHeaderListSizeGoAway - headersLength) { headerListSizeExceeded(maxHeaderListSizeGoAway); } state = READ_LITERAL_HEADER_NAME; break; case READ_LITERAL_HEADER_NAME: if (in.readableBytes() < nameLength) { throw notEnoughDataException(in); } name = readStringLiteral(in, nameLength, huffmanEncoded); state = READ_LITERAL_HEADER_VALUE_LENGTH_PREFIX; break; case READ_LITERAL_HEADER_VALUE_LENGTH_PREFIX: b = in.readByte(); huffmanEncoded = (b & 0x80) == 0x80; index = b & 0x7F; switch (index) { case 0x7f: state = READ_LITERAL_HEADER_VALUE_LENGTH; break; case 0: headersLength = insertHeader(streamId, headers, name, EMPTY_STRING, indexType, headersLength); state = READ_HEADER_REPRESENTATION; break; default: if ((long) index + nameLength > maxHeaderListSizeGoAway - headersLength) { headerListSizeExceeded(maxHeaderListSizeGoAway); } valueLength = index; state = READ_LITERAL_HEADER_VALUE; } break; case READ_LITERAL_HEADER_VALUE_LENGTH: valueLength = decodeULE128(in, index); if ((long) valueLength + nameLength > maxHeaderListSizeGoAway - headersLength) { headerListSizeExceeded(maxHeaderListSizeGoAway); } state = READ_LITERAL_HEADER_VALUE; break; case READ_LITERAL_HEADER_VALUE: if (in.readableBytes() < valueLength) { throw notEnoughDataException(in); } CharSequence value = readStringLiteral(in, valueLength, huffmanEncoded); headersLength = insertHeader(streamId, headers, name, value, indexType, headersLength); state = READ_HEADER_REPRESENTATION; break; default: throw new Error("should not reach here state: " + state); } } if (headersLength > maxHeaderListSize) { headerListSizeExceeded(streamId, maxHeaderListSize, true); } } HpackDecoder(long maxHeaderListSize, int initialHuffmanDecodeCapacity);   HpackDecoder(long maxHeaderListSize, int initialHuffmanDecodeCapacity, int maxHeaderTableSize); }
HpackDecoder { public void decode(int streamId, ByteBuf in, Http2Headers headers) throws Http2Exception { int index = 0; long headersLength = 0; int nameLength = 0; int valueLength = 0; byte state = READ_HEADER_REPRESENTATION; boolean huffmanEncoded = false; CharSequence name = null; IndexType indexType = IndexType.NONE; while (in.isReadable()) { switch (state) { case READ_HEADER_REPRESENTATION: byte b = in.readByte(); if (maxDynamicTableSizeChangeRequired && (b & 0xE0) != 0x20) { throw MAX_DYNAMIC_TABLE_SIZE_CHANGE_REQUIRED; } if (b < 0) { index = b & 0x7F; switch (index) { case 0: throw DECODE_ILLEGAL_INDEX_VALUE; case 0x7F: state = READ_INDEXED_HEADER; break; default: headersLength = indexHeader(streamId, index, headers, headersLength); } } else if ((b & 0x40) == 0x40) { indexType = IndexType.INCREMENTAL; index = b & 0x3F; switch (index) { case 0: state = READ_LITERAL_HEADER_NAME_LENGTH_PREFIX; break; case 0x3F: state = READ_INDEXED_HEADER_NAME; break; default: name = readName(index); state = READ_LITERAL_HEADER_VALUE_LENGTH_PREFIX; } } else if ((b & 0x20) == 0x20) { index = b & 0x1F; if (index == 0x1F) { state = READ_MAX_DYNAMIC_TABLE_SIZE; } else { setDynamicTableSize(index); state = READ_HEADER_REPRESENTATION; } } else { indexType = ((b & 0x10) == 0x10) ? IndexType.NEVER : IndexType.NONE; index = b & 0x0F; switch (index) { case 0: state = READ_LITERAL_HEADER_NAME_LENGTH_PREFIX; break; case 0x0F: state = READ_INDEXED_HEADER_NAME; break; default: name = readName(index); state = READ_LITERAL_HEADER_VALUE_LENGTH_PREFIX; } } break; case READ_MAX_DYNAMIC_TABLE_SIZE: setDynamicTableSize(decodeULE128(in, (long) index)); state = READ_HEADER_REPRESENTATION; break; case READ_INDEXED_HEADER: headersLength = indexHeader(streamId, decodeULE128(in, index), headers, headersLength); state = READ_HEADER_REPRESENTATION; break; case READ_INDEXED_HEADER_NAME: name = readName(decodeULE128(in, index)); state = READ_LITERAL_HEADER_VALUE_LENGTH_PREFIX; break; case READ_LITERAL_HEADER_NAME_LENGTH_PREFIX: b = in.readByte(); huffmanEncoded = (b & 0x80) == 0x80; index = b & 0x7F; if (index == 0x7f) { state = READ_LITERAL_HEADER_NAME_LENGTH; } else { if (index > maxHeaderListSizeGoAway - headersLength) { headerListSizeExceeded(maxHeaderListSizeGoAway); } nameLength = index; state = READ_LITERAL_HEADER_NAME; } break; case READ_LITERAL_HEADER_NAME_LENGTH: nameLength = decodeULE128(in, index); if (nameLength > maxHeaderListSizeGoAway - headersLength) { headerListSizeExceeded(maxHeaderListSizeGoAway); } state = READ_LITERAL_HEADER_NAME; break; case READ_LITERAL_HEADER_NAME: if (in.readableBytes() < nameLength) { throw notEnoughDataException(in); } name = readStringLiteral(in, nameLength, huffmanEncoded); state = READ_LITERAL_HEADER_VALUE_LENGTH_PREFIX; break; case READ_LITERAL_HEADER_VALUE_LENGTH_PREFIX: b = in.readByte(); huffmanEncoded = (b & 0x80) == 0x80; index = b & 0x7F; switch (index) { case 0x7f: state = READ_LITERAL_HEADER_VALUE_LENGTH; break; case 0: headersLength = insertHeader(streamId, headers, name, EMPTY_STRING, indexType, headersLength); state = READ_HEADER_REPRESENTATION; break; default: if ((long) index + nameLength > maxHeaderListSizeGoAway - headersLength) { headerListSizeExceeded(maxHeaderListSizeGoAway); } valueLength = index; state = READ_LITERAL_HEADER_VALUE; } break; case READ_LITERAL_HEADER_VALUE_LENGTH: valueLength = decodeULE128(in, index); if ((long) valueLength + nameLength > maxHeaderListSizeGoAway - headersLength) { headerListSizeExceeded(maxHeaderListSizeGoAway); } state = READ_LITERAL_HEADER_VALUE; break; case READ_LITERAL_HEADER_VALUE: if (in.readableBytes() < valueLength) { throw notEnoughDataException(in); } CharSequence value = readStringLiteral(in, valueLength, huffmanEncoded); headersLength = insertHeader(streamId, headers, name, value, indexType, headersLength); state = READ_HEADER_REPRESENTATION; break; default: throw new Error("should not reach here state: " + state); } } if (headersLength > maxHeaderListSize) { headerListSizeExceeded(streamId, maxHeaderListSize, true); } } HpackDecoder(long maxHeaderListSize, int initialHuffmanDecodeCapacity);   HpackDecoder(long maxHeaderListSize, int initialHuffmanDecodeCapacity, int maxHeaderTableSize); void decode(int streamId, ByteBuf in, Http2Headers headers); void setMaxHeaderTableSize(long maxHeaderTableSize); void setMaxHeaderListSize(long maxHeaderListSize, long maxHeaderListSizeGoAway); long getMaxHeaderListSize(); long getMaxHeaderListSizeGoAway(); long getMaxHeaderTableSize(); }
HpackDecoder { public void decode(int streamId, ByteBuf in, Http2Headers headers) throws Http2Exception { int index = 0; long headersLength = 0; int nameLength = 0; int valueLength = 0; byte state = READ_HEADER_REPRESENTATION; boolean huffmanEncoded = false; CharSequence name = null; IndexType indexType = IndexType.NONE; while (in.isReadable()) { switch (state) { case READ_HEADER_REPRESENTATION: byte b = in.readByte(); if (maxDynamicTableSizeChangeRequired && (b & 0xE0) != 0x20) { throw MAX_DYNAMIC_TABLE_SIZE_CHANGE_REQUIRED; } if (b < 0) { index = b & 0x7F; switch (index) { case 0: throw DECODE_ILLEGAL_INDEX_VALUE; case 0x7F: state = READ_INDEXED_HEADER; break; default: headersLength = indexHeader(streamId, index, headers, headersLength); } } else if ((b & 0x40) == 0x40) { indexType = IndexType.INCREMENTAL; index = b & 0x3F; switch (index) { case 0: state = READ_LITERAL_HEADER_NAME_LENGTH_PREFIX; break; case 0x3F: state = READ_INDEXED_HEADER_NAME; break; default: name = readName(index); state = READ_LITERAL_HEADER_VALUE_LENGTH_PREFIX; } } else if ((b & 0x20) == 0x20) { index = b & 0x1F; if (index == 0x1F) { state = READ_MAX_DYNAMIC_TABLE_SIZE; } else { setDynamicTableSize(index); state = READ_HEADER_REPRESENTATION; } } else { indexType = ((b & 0x10) == 0x10) ? IndexType.NEVER : IndexType.NONE; index = b & 0x0F; switch (index) { case 0: state = READ_LITERAL_HEADER_NAME_LENGTH_PREFIX; break; case 0x0F: state = READ_INDEXED_HEADER_NAME; break; default: name = readName(index); state = READ_LITERAL_HEADER_VALUE_LENGTH_PREFIX; } } break; case READ_MAX_DYNAMIC_TABLE_SIZE: setDynamicTableSize(decodeULE128(in, (long) index)); state = READ_HEADER_REPRESENTATION; break; case READ_INDEXED_HEADER: headersLength = indexHeader(streamId, decodeULE128(in, index), headers, headersLength); state = READ_HEADER_REPRESENTATION; break; case READ_INDEXED_HEADER_NAME: name = readName(decodeULE128(in, index)); state = READ_LITERAL_HEADER_VALUE_LENGTH_PREFIX; break; case READ_LITERAL_HEADER_NAME_LENGTH_PREFIX: b = in.readByte(); huffmanEncoded = (b & 0x80) == 0x80; index = b & 0x7F; if (index == 0x7f) { state = READ_LITERAL_HEADER_NAME_LENGTH; } else { if (index > maxHeaderListSizeGoAway - headersLength) { headerListSizeExceeded(maxHeaderListSizeGoAway); } nameLength = index; state = READ_LITERAL_HEADER_NAME; } break; case READ_LITERAL_HEADER_NAME_LENGTH: nameLength = decodeULE128(in, index); if (nameLength > maxHeaderListSizeGoAway - headersLength) { headerListSizeExceeded(maxHeaderListSizeGoAway); } state = READ_LITERAL_HEADER_NAME; break; case READ_LITERAL_HEADER_NAME: if (in.readableBytes() < nameLength) { throw notEnoughDataException(in); } name = readStringLiteral(in, nameLength, huffmanEncoded); state = READ_LITERAL_HEADER_VALUE_LENGTH_PREFIX; break; case READ_LITERAL_HEADER_VALUE_LENGTH_PREFIX: b = in.readByte(); huffmanEncoded = (b & 0x80) == 0x80; index = b & 0x7F; switch (index) { case 0x7f: state = READ_LITERAL_HEADER_VALUE_LENGTH; break; case 0: headersLength = insertHeader(streamId, headers, name, EMPTY_STRING, indexType, headersLength); state = READ_HEADER_REPRESENTATION; break; default: if ((long) index + nameLength > maxHeaderListSizeGoAway - headersLength) { headerListSizeExceeded(maxHeaderListSizeGoAway); } valueLength = index; state = READ_LITERAL_HEADER_VALUE; } break; case READ_LITERAL_HEADER_VALUE_LENGTH: valueLength = decodeULE128(in, index); if ((long) valueLength + nameLength > maxHeaderListSizeGoAway - headersLength) { headerListSizeExceeded(maxHeaderListSizeGoAway); } state = READ_LITERAL_HEADER_VALUE; break; case READ_LITERAL_HEADER_VALUE: if (in.readableBytes() < valueLength) { throw notEnoughDataException(in); } CharSequence value = readStringLiteral(in, valueLength, huffmanEncoded); headersLength = insertHeader(streamId, headers, name, value, indexType, headersLength); state = READ_HEADER_REPRESENTATION; break; default: throw new Error("should not reach here state: " + state); } } if (headersLength > maxHeaderListSize) { headerListSizeExceeded(streamId, maxHeaderListSize, true); } } HpackDecoder(long maxHeaderListSize, int initialHuffmanDecodeCapacity);   HpackDecoder(long maxHeaderListSize, int initialHuffmanDecodeCapacity, int maxHeaderTableSize); void decode(int streamId, ByteBuf in, Http2Headers headers); void setMaxHeaderTableSize(long maxHeaderTableSize); void setMaxHeaderListSize(long maxHeaderListSize, long maxHeaderListSizeGoAway); long getMaxHeaderListSize(); long getMaxHeaderListSizeGoAway(); long getMaxHeaderTableSize();  }