blob: c3b28a3e10b0ad37b4a46d948df8a3562f4af37f [file] [log] [blame]
QUICHE teama6ef0a62019-03-07 20:34:33 -05001// Copyright (c) 2018 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_QUIC_CORE_QPACK_QPACK_DECODER_H_
6#define QUICHE_QUIC_CORE_QPACK_QPACK_DECODER_H_
7
8#include <cstdint>
9#include <memory>
10
11#include "net/third_party/quiche/src/quic/core/qpack/qpack_decoder_stream_sender.h"
12#include "net/third_party/quiche/src/quic/core/qpack/qpack_encoder_stream_receiver.h"
13#include "net/third_party/quiche/src/quic/core/qpack/qpack_header_table.h"
14#include "net/third_party/quiche/src/quic/core/qpack/qpack_progressive_decoder.h"
15#include "net/third_party/quiche/src/quic/core/quic_types.h"
16#include "net/third_party/quiche/src/quic/platform/api/quic_export.h"
17#include "net/third_party/quiche/src/quic/platform/api/quic_string_piece.h"
18
19namespace quic {
20
21// QPACK decoder class. Exactly one instance should exist per QUIC connection.
22// This class vends a new QpackProgressiveDecoder instance for each new header
23// list to be encoded.
24class QUIC_EXPORT_PRIVATE QpackDecoder
25 : public QpackEncoderStreamReceiver::Delegate {
26 public:
27 // Interface for receiving notification that an error has occurred on the
28 // encoder stream. This MUST be treated as a connection error of type
29 // HTTP_QPACK_ENCODER_STREAM_ERROR.
30 class QUIC_EXPORT_PRIVATE EncoderStreamErrorDelegate {
31 public:
32 virtual ~EncoderStreamErrorDelegate() {}
33
34 virtual void OnEncoderStreamError(QuicStringPiece error_message) = 0;
35 };
36
37 QpackDecoder(
38 EncoderStreamErrorDelegate* encoder_stream_error_delegate,
39 QpackDecoderStreamSender::Delegate* decoder_stream_sender_delegate);
40 ~QpackDecoder() override;
41
42 // Set maximum capacity of dynamic table.
43 // This method must only be called at most once.
44 void SetMaximumDynamicTableCapacity(uint64_t maximum_dynamic_table_capacity);
45
46 // Signal to the peer's encoder that a stream is reset. This lets the peer's
47 // encoder know that no more header blocks will be processed on this stream,
48 // therefore references to dynamic table entries shall not prevent their
49 // eviction.
50 // This method should be called regardless of whether a header block is being
51 // decoded on that stream, because a header block might be in flight from the
52 // peer.
53 // This method should be called every time a request or push stream is reset
54 // for any reason: for example, client cancels request, or a decoding error
55 // occurs and HeadersHandlerInterface::OnDecodingErrorDetected() is called.
56 // This method should also be called if the stream is reset by the peer,
57 // because the peer's encoder can only evict entries referenced by header
58 // blocks once it receives acknowledgement from this endpoint that the stream
59 // is reset.
60 // However, this method should not be called if the stream is closed normally
61 // using the FIN bit.
62 void OnStreamReset(QuicStreamId stream_id);
63
64 // Factory method to create a QpackProgressiveDecoder for decoding a header
65 // block. |handler| must remain valid until the returned
66 // QpackProgressiveDecoder instance is destroyed or the decoder calls
67 // |handler->OnHeaderBlockEnd()|.
68 std::unique_ptr<QpackProgressiveDecoder> DecodeHeaderBlock(
69 QuicStreamId stream_id,
70 QpackProgressiveDecoder::HeadersHandlerInterface* handler);
71
72 // Decode data received on the encoder stream.
73 void DecodeEncoderStreamData(QuicStringPiece data);
74
75 // QpackEncoderStreamReceiver::Delegate implementation
76 void OnInsertWithNameReference(bool is_static,
77 uint64_t name_index,
78 QuicStringPiece value) override;
79 void OnInsertWithoutNameReference(QuicStringPiece name,
80 QuicStringPiece value) override;
81 void OnDuplicate(uint64_t index) override;
82 void OnSetDynamicTableCapacity(uint64_t capacity) override;
83 void OnErrorDetected(QuicStringPiece error_message) override;
84
85 private:
86 // The encoder stream uses relative index (but different from the kind of
87 // relative index used on a request stream). This method converts relative
88 // index to absolute index (zero based). It returns true on success, or false
89 // if conversion fails due to overflow/underflow.
90 bool EncoderStreamRelativeIndexToAbsoluteIndex(
91 uint64_t relative_index,
92 uint64_t* absolute_index) const;
93
94 EncoderStreamErrorDelegate* const encoder_stream_error_delegate_;
95 QpackEncoderStreamReceiver encoder_stream_receiver_;
96 QpackDecoderStreamSender decoder_stream_sender_;
97 QpackHeaderTable header_table_;
98};
99
100} // namespace quic
101
102#endif // QUICHE_QUIC_CORE_QPACK_QPACK_DECODER_H_