summaryrefslogtreecommitdiff
path: root/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoded_headers_accumulator.h
blob: e194a98ebc5461c0934494318f39330b13dfd345 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
// Copyright (c) 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef QUICHE_QUIC_CORE_QPACK_QPACK_DECODED_HEADERS_ACCUMULATOR_H_
#define QUICHE_QUIC_CORE_QPACK_QPACK_DECODED_HEADERS_ACCUMULATOR_H_

#include <cstddef>
#include <string>

#include "absl/strings/string_view.h"
#include "net/third_party/quiche/src/quic/core/http/quic_header_list.h"
#include "net/third_party/quiche/src/quic/core/qpack/qpack_progressive_decoder.h"
#include "net/third_party/quiche/src/quic/core/quic_types.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_export.h"

namespace quic {

class QpackDecoder;

// A class that creates and owns a QpackProgressiveDecoder instance, accumulates
// decoded headers in a QuicHeaderList, and keeps track of uncompressed and
// compressed size so that it can be passed to
// QuicHeaderList::OnHeaderBlockEnd().
class QUIC_EXPORT_PRIVATE QpackDecodedHeadersAccumulator
    : public QpackProgressiveDecoder::HeadersHandlerInterface {
 public:
  // Visitor interface to signal success or error.
  // Exactly one method will be called.
  // Methods may be called synchronously from Decode() and EndHeaderBlock(),
  // or asynchronously.
  // Method implementations are allowed to destroy |this|.
  class QUIC_EXPORT_PRIVATE Visitor {
   public:
    virtual ~Visitor() = default;

    // Called when headers are successfully decoded.  If the uncompressed header
    // list size including an overhead for each header field exceeds the limit
    // specified via |max_header_list_size| in QpackDecodedHeadersAccumulator
    // constructor, then |header_list_size_limit_exceeded| will be true, and
    // |headers| will be empty but will still have the correct compressed and
    // uncompressed size
    // information.
    virtual void OnHeadersDecoded(QuicHeaderList headers,
                                  bool header_list_size_limit_exceeded) = 0;

    // Called when an error has occurred.
    virtual void OnHeaderDecodingError(absl::string_view error_message) = 0;
  };

  QpackDecodedHeadersAccumulator(QuicStreamId id,
                                 QpackDecoder* qpack_decoder,
                                 Visitor* visitor,
                                 size_t max_header_list_size);
  virtual ~QpackDecodedHeadersAccumulator() = default;

  // QpackProgressiveDecoder::HeadersHandlerInterface implementation.
  // These methods should only be called by |decoder_|.
  void OnHeaderDecoded(absl::string_view name,
                       absl::string_view value) override;
  void OnDecodingCompleted() override;
  void OnDecodingErrorDetected(absl::string_view error_message) override;

  // Decode payload data.
  // Must not be called if an error has been detected.
  // Must not be called after EndHeaderBlock().
  void Decode(absl::string_view data);

  // Signal end of HEADERS frame.
  // Must not be called if an error has been detected.
  // Must not be called more that once.
  void EndHeaderBlock();

 private:
  std::unique_ptr<QpackProgressiveDecoder> decoder_;
  Visitor* visitor_;
  // Maximum header list size including overhead.
  size_t max_header_list_size_;
  // Uncompressed header list size including overhead, for enforcing the limit.
  size_t uncompressed_header_bytes_including_overhead_;
  QuicHeaderList quic_header_list_;
  // Uncompressed header list size with overhead,
  // for passing in to QuicHeaderList::OnHeaderBlockEnd().
  size_t uncompressed_header_bytes_without_overhead_;
  // Compressed header list size
  // for passing in to QuicHeaderList::OnHeaderBlockEnd().
  size_t compressed_header_bytes_;

  // True if the header size limit has been exceeded.
  // Input data is still fed to QpackProgressiveDecoder.
  bool header_list_size_limit_exceeded_;

  // The following two members are only used for DCHECKs.

  // True if headers have been completedly and successfully decoded.
  bool headers_decoded_;
  // True if an error has been detected during decoding.
  bool error_detected_;
};

}  // namespace quic

#endif  // QUICHE_QUIC_CORE_QPACK_QPACK_DECODED_HEADERS_ACCUMULATOR_H_