Allow extensions of QpackEncoder to override choice to huffman encode.

Signed-off-by: Lachlan Roberts <lachlan@webtide.com>
This commit is contained in:
Lachlan Roberts 2021-03-05 15:31:20 +11:00 committed by Simone Bordet
parent f1e46c6127
commit 1ae03a9d40
4 changed files with 21 additions and 27 deletions

View File

@ -24,6 +24,7 @@ class EncodableEntry
private final Entry _referencedEntry; private final Entry _referencedEntry;
private final Entry _referencedName; private final Entry _referencedName;
private final HttpField _field; private final HttpField _field;
private final boolean _huffman;
public EncodableEntry(Entry entry) public EncodableEntry(Entry entry)
{ {
@ -31,22 +32,25 @@ class EncodableEntry
_referencedEntry = entry; _referencedEntry = entry;
_referencedName = null; _referencedName = null;
_field = null; _field = null;
_huffman = false;
} }
public EncodableEntry(Entry nameEntry, HttpField field) public EncodableEntry(Entry nameEntry, HttpField field, boolean huffman)
{ {
// We want to reference the name and use a literal value. // We want to reference the name and use a literal value.
_referencedEntry = null; _referencedEntry = null;
_referencedName = nameEntry; _referencedName = nameEntry;
_field = field; _field = field;
_huffman = huffman;
} }
public EncodableEntry(HttpField field) public EncodableEntry(HttpField field, boolean huffman)
{ {
// We want to use a literal name and value. // We want to use a literal name and value.
_referencedEntry = null; _referencedEntry = null;
_referencedName = null; _referencedName = null;
_field = field; _field = field;
_huffman = huffman;
} }
public void encode(ByteBuffer buffer, int base) public void encode(ByteBuffer buffer, int base)
@ -65,7 +69,6 @@ class EncodableEntry
byte allowIntermediary = 0x00; // TODO: this is 0x20 bit, when should this be set? byte allowIntermediary = 0x00; // TODO: this is 0x20 bit, when should this be set?
byte staticBit = _referencedName.isStatic() ? (byte)0x10 : (byte)0x00; byte staticBit = _referencedName.isStatic() ? (byte)0x10 : (byte)0x00;
String value = (Objects.requireNonNull(_field).getValue() == null) ? "" : _field.getValue(); String value = (Objects.requireNonNull(_field).getValue() == null) ? "" : _field.getValue();
boolean huffman = QpackEncoder.shouldHuffmanEncode(_referencedName.getHttpField());
// Encode the prefix. // Encode the prefix.
buffer.put((byte)(0x40 | allowIntermediary | staticBit)); buffer.put((byte)(0x40 | allowIntermediary | staticBit));
@ -73,7 +76,7 @@ class EncodableEntry
NBitInteger.encode(buffer, 4, relativeIndex); NBitInteger.encode(buffer, 4, relativeIndex);
// Encode the value. // Encode the value.
if (huffman) if (_huffman)
{ {
buffer.put((byte)0x80); buffer.put((byte)0x80);
NBitInteger.encode(buffer, 7, Huffman.octetsNeeded(value)); NBitInteger.encode(buffer, 7, Huffman.octetsNeeded(value));
@ -89,12 +92,11 @@ class EncodableEntry
else else
{ {
byte allowIntermediary = 0x00; // TODO: this is 0x10 bit, when should this be set? byte allowIntermediary = 0x00; // TODO: this is 0x10 bit, when should this be set?
boolean huffman = QpackEncoder.shouldHuffmanEncode(Objects.requireNonNull(_field)); String name = Objects.requireNonNull(_field).getName();
String name = _field.getName();
String value = (_field.getValue() == null) ? "" : _field.getValue(); String value = (_field.getValue() == null) ? "" : _field.getValue();
// Encode the prefix code and the name. // Encode the prefix code and the name.
if (huffman) if (_huffman)
{ {
buffer.put((byte)(0x28 | allowIntermediary)); buffer.put((byte)(0x28 | allowIntermediary));
NBitInteger.encode(buffer, 3, Huffman.octetsNeeded(name)); NBitInteger.encode(buffer, 3, Huffman.octetsNeeded(name));

View File

@ -232,9 +232,9 @@ public class QpackEncoder
return !DO_NOT_INDEX.contains(httpField.getHeader()); return !DO_NOT_INDEX.contains(httpField.getHeader());
} }
public static boolean shouldHuffmanEncode(HttpField httpField) protected boolean shouldHuffmanEncode(HttpField httpField)
{ {
return false; //!DO_NOT_HUFFMAN.contains(httpField.getHeader()); return !DO_NOT_HUFFMAN.contains(httpField.getHeader());
} }
public ByteBuffer encode(int streamId, HttpFields httpFields) throws QpackException public ByteBuffer encode(int streamId, HttpFields httpFields) throws QpackException
@ -357,7 +357,7 @@ public class QpackEncoder
return new EncodableEntry(newEntry); return new EncodableEntry(newEntry);
} }
return new EncodableEntry(nameEntry, field); return new EncodableEntry(nameEntry, field, huffman);
} }
else else
{ {
@ -372,7 +372,7 @@ public class QpackEncoder
return new EncodableEntry(newEntry); return new EncodableEntry(newEntry);
} }
return new EncodableEntry(field); return new EncodableEntry(field, huffman);
} }
} }

View File

@ -57,7 +57,14 @@ public class EncodeDecodeTest
{ {
_encoderHandler = new TestEncoderHandler(); _encoderHandler = new TestEncoderHandler();
_decoderHandler = new TestDecoderHandler(); _decoderHandler = new TestDecoderHandler();
_encoder = new QpackEncoder(_encoderHandler, MAX_BLOCKED_STREAMS); _encoder = new QpackEncoder(_encoderHandler, MAX_BLOCKED_STREAMS)
{
@Override
protected boolean shouldHuffmanEncode(HttpField httpField)
{
return false;
}
};
_decoder = new QpackDecoder(_decoderHandler, MAX_HEADER_SIZE); _decoder = new QpackDecoder(_decoderHandler, MAX_HEADER_SIZE);
_encoderInstructionParser = new EncoderInstructionParser(_decoder); _encoderInstructionParser = new EncoderInstructionParser(_decoder);
_decoderInstructionParser = new DecoderInstructionParser(_encoder); _decoderInstructionParser = new DecoderInstructionParser(_encoder);

View File

@ -73,21 +73,6 @@ public class NBitIntegerTest
testEncode(8, 255 + 0x00 + 0x80 * 0x80, "Ff808001"); testEncode(8, 255 + 0x00 + 0x80 * 0x80, "Ff808001");
} }
@Test
public void test()
{
ByteBuffer buffer = BufferUtil.allocate(100);
BufferUtil.clearToFill(buffer);
buffer.put((byte)0x00);
NBitInteger.encode(buffer, 7, 4);
BufferUtil.flipToFlush(buffer, 0);
System.err.println(BufferUtil.toDetailString(buffer));
buffer.position(1);
int decode = NBitInteger.decode(buffer, 7);
System.err.println(decode);
}
public void testEncode(int n, int i, String expected) public void testEncode(int n, int i, String expected)
{ {
ByteBuffer buf = BufferUtil.allocate(16); ByteBuffer buf = BufferUtil.allocate(16);