// 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 #include #include "absl/strings/string_view.h" #include "quiche/quic/core/http/quic_header_list.h" #include "quiche/quic/core/qpack/qpack_progressive_decoder.h" #include "quiche/quic/core/quic_error_codes.h" #include "quiche/quic/core/quic_types.h" #include "quiche/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(QuicErrorCode error_code, 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(QuicErrorCode error_code, 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 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 QUICHE_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_