1 // Copyright (c) 2019 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_DECODED_HEADERS_ACCUMULATOR_H_ 6 #define QUICHE_QUIC_CORE_QPACK_QPACK_DECODED_HEADERS_ACCUMULATOR_H_ 7 8 #include <cstddef> 9 #include <string> 10 11 #include "absl/strings/string_view.h" 12 #include "quiche/quic/core/http/quic_header_list.h" 13 #include "quiche/quic/core/qpack/qpack_progressive_decoder.h" 14 #include "quiche/quic/core/quic_error_codes.h" 15 #include "quiche/quic/core/quic_types.h" 16 #include "quiche/quic/platform/api/quic_export.h" 17 18 namespace quic { 19 20 class QpackDecoder; 21 22 // A class that creates and owns a QpackProgressiveDecoder instance, accumulates 23 // decoded headers in a QuicHeaderList, and keeps track of uncompressed and 24 // compressed size so that it can be passed to 25 // QuicHeaderList::OnHeaderBlockEnd(). 26 class QUICHE_EXPORT QpackDecodedHeadersAccumulator 27 : public QpackProgressiveDecoder::HeadersHandlerInterface { 28 public: 29 // Visitor interface to signal success or error. 30 // Exactly one method will be called. 31 // Methods may be called synchronously from Decode() and EndHeaderBlock(), 32 // or asynchronously. 33 // Method implementations are allowed to destroy |this|. 34 class QUICHE_EXPORT Visitor { 35 public: 36 virtual ~Visitor() = default; 37 38 // Called when headers are successfully decoded. If the uncompressed header 39 // list size including an overhead for each header field exceeds the limit 40 // specified via |max_header_list_size| in QpackDecodedHeadersAccumulator 41 // constructor, then |header_list_size_limit_exceeded| will be true, and 42 // |headers| will be empty but will still have the correct compressed and 43 // uncompressed size 44 // information. 45 virtual void OnHeadersDecoded(QuicHeaderList headers, 46 bool header_list_size_limit_exceeded) = 0; 47 48 // Called when an error has occurred. 49 virtual void OnHeaderDecodingError(QuicErrorCode error_code, 50 absl::string_view error_message) = 0; 51 }; 52 53 QpackDecodedHeadersAccumulator(QuicStreamId id, QpackDecoder* qpack_decoder, 54 Visitor* visitor, size_t max_header_list_size); 55 virtual ~QpackDecodedHeadersAccumulator() = default; 56 57 // QpackProgressiveDecoder::HeadersHandlerInterface implementation. 58 // These methods should only be called by |decoder_|. 59 void OnHeaderDecoded(absl::string_view name, 60 absl::string_view value) override; 61 void OnDecodingCompleted() override; 62 void OnDecodingErrorDetected(QuicErrorCode error_code, 63 absl::string_view error_message) override; 64 65 // Decode payload data. 66 // Must not be called if an error has been detected. 67 // Must not be called after EndHeaderBlock(). 68 void Decode(absl::string_view data); 69 70 // Signal end of HEADERS frame. 71 // Must not be called if an error has been detected. 72 // Must not be called more that once. 73 void EndHeaderBlock(); 74 75 private: 76 std::unique_ptr<QpackProgressiveDecoder> decoder_; 77 Visitor* visitor_; 78 // Maximum header list size including overhead. 79 size_t max_header_list_size_; 80 // Uncompressed header list size including overhead, for enforcing the limit. 81 size_t uncompressed_header_bytes_including_overhead_; 82 QuicHeaderList quic_header_list_; 83 // Uncompressed header list size with overhead, 84 // for passing in to QuicHeaderList::OnHeaderBlockEnd(). 85 size_t uncompressed_header_bytes_without_overhead_; 86 // Compressed header list size 87 // for passing in to QuicHeaderList::OnHeaderBlockEnd(). 88 size_t compressed_header_bytes_; 89 90 // True if the header size limit has been exceeded. 91 // Input data is still fed to QpackProgressiveDecoder. 92 bool header_list_size_limit_exceeded_; 93 94 // The following two members are only used for QUICHE_DCHECKs. 95 96 // True if headers have been completedly and successfully decoded. 97 bool headers_decoded_; 98 // True if an error has been detected during decoding. 99 bool error_detected_; 100 }; 101 102 } // namespace quic 103 104 #endif // QUICHE_QUIC_CORE_QPACK_QPACK_DECODED_HEADERS_ACCUMULATOR_H_ 105