xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/quiche/http2/hpack/decoder/hpack_whole_entry_buffer.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // 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 #ifndef QUICHE_HTTP2_HPACK_DECODER_HPACK_WHOLE_ENTRY_BUFFER_H_
6 #define QUICHE_HTTP2_HPACK_DECODER_HPACK_WHOLE_ENTRY_BUFFER_H_
7 
8 // HpackWholeEntryBuffer isolates a listener from the fact that an entry may
9 // be split across multiple input buffers, providing one callback per entry.
10 // HpackWholeEntryBuffer requires that the HpackEntryDecoderListener be made in
11 // the correct order, which is tested by hpack_entry_decoder_test.cc.
12 
13 #include <stddef.h>
14 
15 #include "absl/strings/string_view.h"
16 #include "quiche/http2/hpack/decoder/hpack_decoder_string_buffer.h"
17 #include "quiche/http2/hpack/decoder/hpack_decoding_error.h"
18 #include "quiche/http2/hpack/decoder/hpack_entry_decoder_listener.h"
19 #include "quiche/http2/hpack/decoder/hpack_whole_entry_listener.h"
20 #include "quiche/http2/hpack/http2_hpack_constants.h"
21 #include "quiche/common/platform/api/quiche_export.h"
22 
23 namespace http2 {
24 
25 // TODO(jamessynge): Consider renaming HpackEntryDecoderListener to
26 // HpackEntryPartsListener or HpackEntryFragmentsListener.
27 class QUICHE_EXPORT HpackWholeEntryBuffer : public HpackEntryDecoderListener {
28  public:
29   // max_string_size specifies the maximum size of an on-the-wire string (name
30   // or value, plain or Huffman encoded) that will be accepted. See sections
31   // 5.1 and 5.2 of RFC 7541. This is a defense against OOM attacks; HTTP/2
32   // allows a decoder to enforce any limit of the size of the header lists
33   // that it is willing decode, including less than the MAX_HEADER_LIST_SIZE
34   // setting, a setting that is initially unlimited. For example, we might
35   // choose to send a MAX_HEADER_LIST_SIZE of 64KB, and to use that same value
36   // as the upper bound for individual strings.
37   HpackWholeEntryBuffer(HpackWholeEntryListener* listener,
38                         size_t max_string_size);
39   ~HpackWholeEntryBuffer() override;
40 
41   HpackWholeEntryBuffer(const HpackWholeEntryBuffer&) = delete;
42   HpackWholeEntryBuffer& operator=(const HpackWholeEntryBuffer&) = delete;
43 
44   // Set the listener to be notified when a whole entry has been decoded.
45   // The listener may be changed at any time.
46   void set_listener(HpackWholeEntryListener* listener);
47 
48   // Set how much encoded data this decoder is willing to buffer.
49   // TODO(jamessynge): Come up with consistent semantics for this protection
50   // across the various decoders; e.g. should it be for a single string or
51   // a single header entry?
52   void set_max_string_size_bytes(size_t max_string_size_bytes);
53 
54   // Ensure that decoded strings pointed to by the HpackDecoderStringBuffer
55   // instances name_ and value_ are buffered, which allows any underlying
56   // transport buffer to be freed or reused without overwriting the decoded
57   // strings. This is needed only when an HPACK entry is split across transport
58   // buffers. See HpackDecoder::DecodeFragment.
59   void BufferStringsIfUnbuffered();
60 
61   // Was an error detected? After an error has been detected and reported,
62   // no further callbacks will be made to the listener.
error_detected()63   bool error_detected() const { return error_detected_; }
64 
65   // Implement the HpackEntryDecoderListener methods.
66 
67   void OnIndexedHeader(size_t index) override;
68   void OnStartLiteralHeader(HpackEntryType entry_type,
69                             size_t maybe_name_index) override;
70   void OnNameStart(bool huffman_encoded, size_t len) override;
71   void OnNameData(const char* data, size_t len) override;
72   void OnNameEnd() override;
73   void OnValueStart(bool huffman_encoded, size_t len) override;
74   void OnValueData(const char* data, size_t len) override;
75   void OnValueEnd() override;
76   void OnDynamicTableSizeUpdate(size_t size) override;
77 
78  private:
79   void ReportError(HpackDecodingError error);
80 
81   HpackWholeEntryListener* listener_;
82   HpackDecoderStringBuffer name_, value_;
83 
84   // max_string_size_bytes_ specifies the maximum allowed size of an on-the-wire
85   // string. Larger strings will be reported as errors to the listener; the
86   // endpoint should treat these as COMPRESSION errors, which are CONNECTION
87   // level errors.
88   size_t max_string_size_bytes_;
89 
90   // The name index (or zero) of the current header entry with a literal value.
91   size_t maybe_name_index_;
92 
93   // The type of the current header entry (with literals) that is being decoded.
94   HpackEntryType entry_type_;
95 
96   bool error_detected_ = false;
97 };
98 
99 }  // namespace http2
100 
101 #endif  // QUICHE_HTTP2_HPACK_DECODER_HPACK_WHOLE_ENTRY_BUFFER_H_
102