From 1ae03a9d404e07d5e02ab13721e1dd59092d5276 Mon Sep 17 00:00:00 2001 From: Lachlan Roberts Date: Fri, 5 Mar 2021 15:31:20 +1100 Subject: [PATCH] Allow extensions of QpackEncoder to override choice to huffman encode. Signed-off-by: Lachlan Roberts --- .../jetty/http3/qpack/EncodableEntry.java | 16 +++++++++------- .../eclipse/jetty/http3/qpack/QpackEncoder.java | 8 ++++---- .../jetty/http3/qpack/EncodeDecodeTest.java | 9 ++++++++- .../jetty/http3/qpack/NBitIntegerTest.java | 15 --------------- 4 files changed, 21 insertions(+), 27 deletions(-) diff --git a/jetty-http3/http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/EncodableEntry.java b/jetty-http3/http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/EncodableEntry.java index 66762f9d1ad..939001ffeba 100644 --- a/jetty-http3/http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/EncodableEntry.java +++ b/jetty-http3/http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/EncodableEntry.java @@ -24,6 +24,7 @@ class EncodableEntry private final Entry _referencedEntry; private final Entry _referencedName; private final HttpField _field; + private final boolean _huffman; public EncodableEntry(Entry entry) { @@ -31,22 +32,25 @@ class EncodableEntry _referencedEntry = entry; _referencedName = 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. _referencedEntry = null; _referencedName = nameEntry; _field = field; + _huffman = huffman; } - public EncodableEntry(HttpField field) + public EncodableEntry(HttpField field, boolean huffman) { // We want to use a literal name and value. _referencedEntry = null; _referencedName = null; _field = field; + _huffman = huffman; } 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 staticBit = _referencedName.isStatic() ? (byte)0x10 : (byte)0x00; String value = (Objects.requireNonNull(_field).getValue() == null) ? "" : _field.getValue(); - boolean huffman = QpackEncoder.shouldHuffmanEncode(_referencedName.getHttpField()); // Encode the prefix. buffer.put((byte)(0x40 | allowIntermediary | staticBit)); @@ -73,7 +76,7 @@ class EncodableEntry NBitInteger.encode(buffer, 4, relativeIndex); // Encode the value. - if (huffman) + if (_huffman) { buffer.put((byte)0x80); NBitInteger.encode(buffer, 7, Huffman.octetsNeeded(value)); @@ -89,12 +92,11 @@ class EncodableEntry else { byte allowIntermediary = 0x00; // TODO: this is 0x10 bit, when should this be set? - boolean huffman = QpackEncoder.shouldHuffmanEncode(Objects.requireNonNull(_field)); - String name = _field.getName(); + String name = Objects.requireNonNull(_field).getName(); String value = (_field.getValue() == null) ? "" : _field.getValue(); // Encode the prefix code and the name. - if (huffman) + if (_huffman) { buffer.put((byte)(0x28 | allowIntermediary)); NBitInteger.encode(buffer, 3, Huffman.octetsNeeded(name)); diff --git a/jetty-http3/http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/QpackEncoder.java b/jetty-http3/http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/QpackEncoder.java index 76c0e351fb3..70321f5d743 100644 --- a/jetty-http3/http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/QpackEncoder.java +++ b/jetty-http3/http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/QpackEncoder.java @@ -232,9 +232,9 @@ public class QpackEncoder 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 @@ -357,7 +357,7 @@ public class QpackEncoder return new EncodableEntry(newEntry); } - return new EncodableEntry(nameEntry, field); + return new EncodableEntry(nameEntry, field, huffman); } else { @@ -372,7 +372,7 @@ public class QpackEncoder return new EncodableEntry(newEntry); } - return new EncodableEntry(field); + return new EncodableEntry(field, huffman); } } diff --git a/jetty-http3/http3-qpack/src/test/java/org/eclipse/jetty/http3/qpack/EncodeDecodeTest.java b/jetty-http3/http3-qpack/src/test/java/org/eclipse/jetty/http3/qpack/EncodeDecodeTest.java index 29c59024371..de3207ab950 100644 --- a/jetty-http3/http3-qpack/src/test/java/org/eclipse/jetty/http3/qpack/EncodeDecodeTest.java +++ b/jetty-http3/http3-qpack/src/test/java/org/eclipse/jetty/http3/qpack/EncodeDecodeTest.java @@ -57,7 +57,14 @@ public class EncodeDecodeTest { _encoderHandler = new TestEncoderHandler(); _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); _encoderInstructionParser = new EncoderInstructionParser(_decoder); _decoderInstructionParser = new DecoderInstructionParser(_encoder); diff --git a/jetty-http3/http3-qpack/src/test/java/org/eclipse/jetty/http3/qpack/NBitIntegerTest.java b/jetty-http3/http3-qpack/src/test/java/org/eclipse/jetty/http3/qpack/NBitIntegerTest.java index 11802f73940..7729bed0bb0 100644 --- a/jetty-http3/http3-qpack/src/test/java/org/eclipse/jetty/http3/qpack/NBitIntegerTest.java +++ b/jetty-http3/http3-qpack/src/test/java/org/eclipse/jetty/http3/qpack/NBitIntegerTest.java @@ -73,21 +73,6 @@ public class NBitIntegerTest 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) { ByteBuffer buf = BufferUtil.allocate(16);