Home / Class/ QpackEncoder Class — netty Architecture

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)

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