Allow extensions of QpackEncoder to override choice to huffman encode.
Signed-off-by: Lachlan Roberts <lachlan@webtide.com>
This commit is contained in:
parent
f1e46c6127
commit
1ae03a9d40
|
@ -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));
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue