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_TEST_TOOLS_QPACK_QPACK_OFFLINE_DECODER_H_ 6 #define QUICHE_QUIC_TEST_TOOLS_QPACK_QPACK_OFFLINE_DECODER_H_ 7 8 #include <list> 9 10 #include "absl/strings/string_view.h" 11 #include "quiche/quic/core/qpack/qpack_decoder.h" 12 #include "quiche/quic/core/quic_error_codes.h" 13 #include "quiche/quic/test_tools/qpack/qpack_decoder_test_utils.h" 14 #include "quiche/quic/test_tools/qpack/qpack_test_utils.h" 15 #include "quiche/spdy/core/http2_header_block.h" 16 17 namespace quic { 18 19 // A decoder to read encoded data from a file, decode it, and compare to 20 // a list of expected header lists read from another file. File format is 21 // described at 22 // https://github.com/quicwg/base-drafts/wiki/QPACK-Offline-Interop. 23 class QpackOfflineDecoder : public QpackDecoder::EncoderStreamErrorDelegate { 24 public: 25 QpackOfflineDecoder(); 26 ~QpackOfflineDecoder() override = default; 27 28 // Read encoded header blocks and encoder stream data from |input_filename| 29 // and decode them, read expected header lists from 30 // |expected_headers_filename|, and compare decoded header lists to expected 31 // ones. Returns true if there is an equal number of them and the 32 // corresponding ones match, false otherwise. 33 bool DecodeAndVerifyOfflineData(absl::string_view input_filename, 34 absl::string_view expected_headers_filename); 35 36 // QpackDecoder::EncoderStreamErrorDelegate implementation: 37 void OnEncoderStreamError(QuicErrorCode error_code, 38 absl::string_view error_message) override; 39 40 private: 41 // Data structure to hold TestHeadersHandler and QpackProgressiveDecoder until 42 // decoding of a header header block (and all preceding header blocks) is 43 // complete. 44 struct Decoder { 45 std::unique_ptr<test::TestHeadersHandler> headers_handler; 46 std::unique_ptr<QpackProgressiveDecoder> progressive_decoder; 47 uint64_t stream_id; 48 }; 49 50 // Parse decoder parameters from |input_filename| and set up |qpack_decoder_| 51 // accordingly. 52 bool ParseInputFilename(absl::string_view input_filename); 53 54 // Read encoded header blocks and encoder stream data from |input_filename|, 55 // pass them to |qpack_decoder_| for decoding, and add decoded header lists to 56 // |decoded_header_lists_|. 57 bool DecodeHeaderBlocksFromFile(absl::string_view input_filename); 58 59 // Read expected header lists from |expected_headers_filename| and verify 60 // decoded header lists in |decoded_header_lists_| against them. 61 bool VerifyDecodedHeaderLists(absl::string_view expected_headers_filename); 62 63 // Parse next header list from |*expected_headers_data| into 64 // |*expected_header_list|, removing consumed data from the beginning of 65 // |*expected_headers_data|. Returns true on success, false if parsing fails. 66 bool ReadNextExpectedHeaderList(absl::string_view* expected_headers_data, 67 spdy::Http2HeaderBlock* expected_header_list); 68 69 // Compare two header lists. Allow for different orders of certain headers as 70 // described at 71 // https://github.com/qpackers/qifs/blob/master/encoded/qpack-03/h2o/README.md. 72 bool CompareHeaderBlocks(spdy::Http2HeaderBlock decoded_header_list, 73 spdy::Http2HeaderBlock expected_header_list); 74 75 bool encoder_stream_error_detected_; 76 test::NoopQpackStreamSenderDelegate decoder_stream_sender_delegate_; 77 std::unique_ptr<QpackDecoder> qpack_decoder_; 78 79 // Objects necessary for decoding, one list element for each header block. 80 std::list<Decoder> decoders_; 81 82 // Decoded header lists. 83 std::list<spdy::Http2HeaderBlock> decoded_header_lists_; 84 }; 85 86 } // namespace quic 87 88 #endif // QUICHE_QUIC_TEST_TOOLS_QPACK_QPACK_OFFLINE_DECODER_H_ 89