QpackEncoder Class — netty Architecture
Architecture documentation for the QpackEncoder class in QpackEncoder.java from the netty codebase.
Entity Profile
Dependency Diagram
graph TD 9e578dbc_12be_4439_554b_24e265961ea5["QpackEncoder"] a9d0b375_1921_29ff_f601_0a8b3ca33ae0["QpackEncoder.java"] 9e578dbc_12be_4439_554b_24e265961ea5 -->|defined in| a9d0b375_1921_29ff_f601_0a8b3ca33ae0 fc008159_521a_9ed0_66d2_5d504adc35a7["QpackEncoder()"] 9e578dbc_12be_4439_554b_24e265961ea5 -->|method| fc008159_521a_9ed0_66d2_5d504adc35a7 c02c31bf_f073_98b8_7f17_f6cd7211e31c["encodeHeaders()"] 9e578dbc_12be_4439_554b_24e265961ea5 -->|method| c02c31bf_f073_98b8_7f17_f6cd7211e31c 1d867d55_ac46_d432_63e0_92c3e1f26137["configureDynamicTable()"] 9e578dbc_12be_4439_554b_24e265961ea5 -->|method| 1d867d55_ac46_d432_63e0_92c3e1f26137 e1d12aa6_1484_afa3_2b10_70aeca3d253d["sectionAcknowledgment()"] 9e578dbc_12be_4439_554b_24e265961ea5 -->|method| e1d12aa6_1484_afa3_2b10_70aeca3d253d 554804fb_ef2d_c20a_03d3_e86785605525["streamCancellation()"] 9e578dbc_12be_4439_554b_24e265961ea5 -->|method| 554804fb_ef2d_c20a_03d3_e86785605525 c670e914_7927_d7c7_5ce6_12f17aaee6fa["insertCountIncrement()"] 9e578dbc_12be_4439_554b_24e265961ea5 -->|method| c670e914_7927_d7c7_5ce6_12f17aaee6fa 4290254a_d002_4407_68f0_95045618c5ff["encodeHeader()"] 9e578dbc_12be_4439_554b_24e265961ea5 -->|method| 4290254a_d002_4407_68f0_95045618c5ff e6a8c78f_612c_a898_3946_dd974c0e8e72["encodeWithDynamicTable()"] 9e578dbc_12be_4439_554b_24e265961ea5 -->|method| e6a8c78f_612c_a898_3946_dd974c0e8e72 e5dd0675_23b6_2e4d_161a_a83f05c006a9["tryEncodeWithDynamicTable()"] 9e578dbc_12be_4439_554b_24e265961ea5 -->|method| e5dd0675_23b6_2e4d_161a_a83f05c006a9 ff05e54c_ab86_28f0_9c02_ca61844188a2["tryAddToDynamicTable()"] 9e578dbc_12be_4439_554b_24e265961ea5 -->|method| ff05e54c_ab86_28f0_9c02_ca61844188a2 aecc0b51_b4bf_12ee_de58_fe48c890656f["encodeIndexedStaticTable()"] 9e578dbc_12be_4439_554b_24e265961ea5 -->|method| aecc0b51_b4bf_12ee_de58_fe48c890656f 4a1423e0_537b_7a93_4ca7_87c2b75fd5a3["encodeIndexedDynamicTable()"] 9e578dbc_12be_4439_554b_24e265961ea5 -->|method| 4a1423e0_537b_7a93_4ca7_87c2b75fd5a3 07b6b4b6_0f8d_7e39_baf3_06035d82689b["encodePostBaseIndexed()"] 9e578dbc_12be_4439_554b_24e265961ea5 -->|method| 07b6b4b6_0f8d_7e39_baf3_06035d82689b
Relationship Graph
Source Code
codec-http3/src/main/java/io/netty/handler/codec/http3/QpackEncoder.java lines 36–544
final class QpackEncoder {
private static final QpackException INVALID_SECTION_ACKNOWLEDGMENT =
QpackException.newStatic(QpackDecoder.class, "sectionAcknowledgment(...)",
"QPACK - section acknowledgment received for unknown stream.");
private static final int DYNAMIC_TABLE_ENCODE_NOT_DONE = -1;
private static final int DYNAMIC_TABLE_ENCODE_NOT_POSSIBLE = -2;
private final QpackHuffmanEncoder huffmanEncoder;
private final QpackEncoderDynamicTable dynamicTable;
private int maxBlockedStreams;
private int blockedStreams;
private LongObjectHashMap<Queue<Indices>> streamSectionTrackers;
QpackEncoder() {
this(new QpackEncoderDynamicTable());
}
QpackEncoder(QpackEncoderDynamicTable dynamicTable) {
huffmanEncoder = new QpackHuffmanEncoder();
this.dynamicTable = dynamicTable;
}
/**
* Encode the header field into the header block.
*
* TODO: do we need to support sensitivity detector?
*/
void encodeHeaders(QpackAttributes qpackAttributes, ByteBuf out, ByteBufAllocator allocator, long streamId,
Http3Headers headers) {
final int base = dynamicTable.insertCount();
// Allocate a new buffer as we have to go back and write a variable length base and required insert count
// later.
ByteBuf tmp = allocator.buffer();
try {
int maxDynamicTblIdx = -1;
int requiredInsertCount = 0;
Indices dynamicTableIndices = null;
for (Map.Entry<CharSequence, CharSequence> header : headers) {
CharSequence name = header.getKey();
CharSequence value = header.getValue();
int dynamicTblIdx = encodeHeader(qpackAttributes, tmp, base, name, value);
if (dynamicTblIdx >= 0) {
int req = dynamicTable.addReferenceToEntry(name, value, dynamicTblIdx);
if (dynamicTblIdx > maxDynamicTblIdx) {
maxDynamicTblIdx = dynamicTblIdx;
requiredInsertCount = req;
}
if (dynamicTableIndices == null) {
dynamicTableIndices = new Indices();
}
dynamicTableIndices.add(dynamicTblIdx);
}
}
// Track all the indices that we need to ack later.
if (dynamicTableIndices != null) {
assert streamSectionTrackers != null;
streamSectionTrackers.computeIfAbsent(streamId, __ -> new ArrayDeque<>())
.add(dynamicTableIndices);
}
// https://www.rfc-editor.org/rfc/rfc9204.html#name-encoded-field-section-prefi
// 0 1 2 3 4 5 6 7
// +---+---+---+---+---+---+---+---+
// | Required Insert Count (8+) |
// +---+---------------------------+
// | S | Delta Base (7+) |
// +---+---------------------------+
encodePrefixedInteger(out, (byte) 0b0, 8, dynamicTable.encodedRequiredInsertCount(requiredInsertCount));
if (base >= requiredInsertCount) {
encodePrefixedInteger(out, (byte) 0b0, 7, base - requiredInsertCount);
} else {
encodePrefixedInteger(out, (byte) 0b1000_0000, 7, requiredInsertCount - base - 1);
}
out.writeBytes(tmp);
} finally {
tmp.release();
}
}
void configureDynamicTable(QpackAttributes attributes, long maxTableCapacity, int blockedStreams)
Source
Frequently Asked Questions
What is the QpackEncoder class?
QpackEncoder is a class in the netty codebase, defined in codec-http3/src/main/java/io/netty/handler/codec/http3/QpackEncoder.java.
Where is QpackEncoder defined?
QpackEncoder is defined in codec-http3/src/main/java/io/netty/handler/codec/http3/QpackEncoder.java at line 36.
Analyze Your Own Codebase
Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.
Try Supermodel Free