blob: 0e6e31b88a9d814f180a110b11db7b1924902e95 [file] [log] [blame]
// 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 "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<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 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_