QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 1 | // 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 | |
| 19 | namespace 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. |
| 24 | class 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_ |