blob: 0735f6a350724d21c33132d1570c2dfa0392d937 [file] [log] [blame]
QUICHE teamfd50a402018-12-07 22:54:05 -05001// Copyright 2016 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5// HpackDecoderState maintains the HPACK decompressor state; i.e. updates the
6// HPACK dynamic table according to RFC 7541 as the entries in an HPACK block
7// are decoded, and reads from the static and dynamic tables in order to build
8// complete header entries. Calls an HpackDecoderListener with the completely
9// decoded headers (i.e. after resolving table indices into names or values),
10// thus translating the decoded HPACK entries into HTTP/2 headers.
11
12#ifndef QUICHE_HTTP2_HPACK_DECODER_HPACK_DECODER_STATE_H_
13#define QUICHE_HTTP2_HPACK_DECODER_HPACK_DECODER_STATE_H_
14
15#include <stddef.h>
16
17#include <cstdint>
18
19#include "net/third_party/quiche/src/http2/hpack/decoder/hpack_decoder_listener.h"
20#include "net/third_party/quiche/src/http2/hpack/decoder/hpack_decoder_string_buffer.h"
21#include "net/third_party/quiche/src/http2/hpack/decoder/hpack_decoder_tables.h"
bnc0ac0f722020-02-07 07:23:09 -080022#include "net/third_party/quiche/src/http2/hpack/decoder/hpack_decoding_error.h"
QUICHE teamfd50a402018-12-07 22:54:05 -050023#include "net/third_party/quiche/src/http2/hpack/decoder/hpack_whole_entry_listener.h"
24#include "net/third_party/quiche/src/http2/hpack/http2_hpack_constants.h"
bnc641ace72020-01-21 12:24:57 -080025#include "net/third_party/quiche/src/common/platform/api/quiche_export.h"
bnc74646d12019-12-13 09:21:19 -080026#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h"
QUICHE teamfd50a402018-12-07 22:54:05 -050027
28namespace http2 {
29namespace test {
30class HpackDecoderStatePeer;
31} // namespace test
32
bnc641ace72020-01-21 12:24:57 -080033class QUICHE_EXPORT_PRIVATE HpackDecoderState : public HpackWholeEntryListener {
QUICHE teamfd50a402018-12-07 22:54:05 -050034 public:
35 explicit HpackDecoderState(HpackDecoderListener* listener);
36 ~HpackDecoderState() override;
37
38 HpackDecoderState(const HpackDecoderState&) = delete;
39 HpackDecoderState& operator=(const HpackDecoderState&) = delete;
40
41 // Set the listener to be notified when a whole entry has been decoded,
42 // including resolving name or name and value references.
43 // The listener may be changed at any time.
44 HpackDecoderListener* listener() const { return listener_; }
45
46 // Set listener to be notified of insertions into the HPACK dynamic table,
47 // and uses of those entries.
48 void set_tables_debug_listener(
49 HpackDecoderTablesDebugListener* debug_listener);
50
51 // ApplyHeaderTableSizeSetting notifies this object that this endpoint has
52 // received a SETTINGS ACK frame acknowledging an earlier SETTINGS frame from
53 // this endpoint specifying a new value for SETTINGS_HEADER_TABLE_SIZE (the
54 // maximum size of the dynamic table that this endpoint will use to decode
55 // HPACK blocks).
56 // Because a SETTINGS frame can contain SETTINGS_HEADER_TABLE_SIZE values,
57 // the caller must keep track of those multiple changes, and make
58 // corresponding calls to this method. In particular, a call must be made
59 // with the lowest value acknowledged by the peer, and a call must be made
60 // with the final value acknowledged, in that order; additional calls may
61 // be made if additional values were sent. These calls must be made between
62 // decoding the SETTINGS ACK, and before the next HPACK block is decoded.
63 void ApplyHeaderTableSizeSetting(uint32_t max_header_table_size);
64
65 // OnHeaderBlockStart notifies this object that we're starting to decode the
66 // HPACK payload of a HEADERS or PUSH_PROMISE frame.
67 void OnHeaderBlockStart();
68
69 // Implement the HpackWholeEntryListener methods, each of which notifies this
70 // object when an entire entry has been decoded.
71 void OnIndexedHeader(size_t index) override;
72 void OnNameIndexAndLiteralValue(
73 HpackEntryType entry_type,
74 size_t name_index,
75 HpackDecoderStringBuffer* value_buffer) override;
76 void OnLiteralNameAndValue(HpackEntryType entry_type,
77 HpackDecoderStringBuffer* name_buffer,
78 HpackDecoderStringBuffer* value_buffer) override;
79 void OnDynamicTableSizeUpdate(size_t size) override;
bnc0ac0f722020-02-07 07:23:09 -080080 void OnHpackDecodeError(HpackDecodingError error) override;
QUICHE teamfd50a402018-12-07 22:54:05 -050081
82 // OnHeaderBlockEnd notifies this object that an entire HPACK block has been
83 // decoded, which might have extended into CONTINUATION blocks.
84 void OnHeaderBlockEnd();
85
bnc0ac0f722020-02-07 07:23:09 -080086 // Returns error code after an error has been detected and reported.
87 // No further callbacks will be made to the listener.
88 HpackDecodingError error() const { return error_; }
QUICHE teamfd50a402018-12-07 22:54:05 -050089
90 const HpackDecoderTables& decoder_tables_for_test() const {
91 return decoder_tables_;
92 }
93
94 private:
95 friend class test::HpackDecoderStatePeer;
96
97 // Reports an error to the listener IF this is the first error detected.
bnc0ac0f722020-02-07 07:23:09 -080098 void ReportError(HpackDecodingError error);
QUICHE teamfd50a402018-12-07 22:54:05 -050099
100 // The static and dynamic HPACK tables.
101 HpackDecoderTables decoder_tables_;
102
103 // The listener to be notified of headers, the start and end of header
104 // lists, and of errors.
105 HpackDecoderListener* listener_;
106
107 // The most recent HEADER_TABLE_SIZE setting acknowledged by the peer.
108 uint32_t final_header_table_size_;
109
110 // The lowest HEADER_TABLE_SIZE setting acknowledged by the peer; valid until
111 // the next HPACK block is decoded.
112 // TODO(jamessynge): Test raising the HEADER_TABLE_SIZE.
113 uint32_t lowest_header_table_size_;
114
115 // Must the next (first) HPACK entry be a dynamic table size update?
116 bool require_dynamic_table_size_update_;
117
118 // May the next (first or second) HPACK entry be a dynamic table size update?
119 bool allow_dynamic_table_size_update_;
120
121 // Have we already seen a dynamic table size update in this HPACK block?
122 bool saw_dynamic_table_size_update_;
123
124 // Has an error already been detected and reported to the listener?
bnc0ac0f722020-02-07 07:23:09 -0800125 HpackDecodingError error_;
QUICHE teamfd50a402018-12-07 22:54:05 -0500126};
127
128} // namespace http2
129
130#endif // QUICHE_HTTP2_HPACK_DECODER_HPACK_DECODER_STATE_H_