1 // Copyright 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_INSTRUCTION_DECODER_H_ 6 #define QUICHE_QUIC_CORE_QPACK_QPACK_INSTRUCTION_DECODER_H_ 7 8 #include <cstddef> 9 #include <cstdint> 10 #include <string> 11 12 #include "absl/strings/string_view.h" 13 #include "quiche/http2/hpack/huffman/hpack_huffman_decoder.h" 14 #include "quiche/http2/hpack/varint/hpack_varint_decoder.h" 15 #include "quiche/quic/core/qpack/qpack_instructions.h" 16 #include "quiche/quic/platform/api/quic_export.h" 17 18 namespace quic { 19 20 // Generic instruction decoder class. Takes a QpackLanguage that describes a 21 // language, that is, a set of instruction opcodes together with a list of 22 // fields that follow each instruction. 23 class QUICHE_EXPORT QpackInstructionDecoder { 24 public: 25 enum class ErrorCode { 26 INTEGER_TOO_LARGE, 27 STRING_LITERAL_TOO_LONG, 28 HUFFMAN_ENCODING_ERROR, 29 }; 30 31 // Delegate is notified each time an instruction is decoded or when an error 32 // occurs. 33 class QUICHE_EXPORT Delegate { 34 public: 35 virtual ~Delegate() = default; 36 37 // Called when an instruction (including all its fields) is decoded. 38 // |instruction| points to an entry in |language|. 39 // Returns true if decoded fields are valid. 40 // Returns false otherwise, in which case QpackInstructionDecoder stops 41 // decoding: Delegate methods will not be called, and Decode() must not be 42 // called. Implementations are allowed to destroy the 43 // QpackInstructionDecoder instance synchronously if OnInstructionDecoded() 44 // returns false. 45 virtual bool OnInstructionDecoded(const QpackInstruction* instruction) = 0; 46 47 // Called by QpackInstructionDecoder if an error has occurred. 48 // No more data is processed afterwards. 49 // Implementations are allowed to destroy the QpackInstructionDecoder 50 // instance synchronously. 51 virtual void OnInstructionDecodingError( 52 ErrorCode error_code, absl::string_view error_message) = 0; 53 }; 54 55 // Both |*language| and |*delegate| must outlive this object. 56 QpackInstructionDecoder(const QpackLanguage* language, Delegate* delegate); 57 QpackInstructionDecoder() = delete; 58 QpackInstructionDecoder(const QpackInstructionDecoder&) = delete; 59 QpackInstructionDecoder& operator=(const QpackInstructionDecoder&) = delete; 60 61 // Provide a data fragment to decode. Must not be called after an error has 62 // occurred. Must not be called with empty |data|. Return true on success, 63 // false on error (in which case Delegate::OnInstructionDecodingError() is 64 // called synchronously). 65 bool Decode(absl::string_view data); 66 67 // Returns true if no decoding has taken place yet or if the last instruction 68 // has been entirely parsed. 69 bool AtInstructionBoundary() const; 70 71 // Accessors for decoded values. Should only be called for fields that are 72 // part of the most recently decoded instruction, and only after |this| calls 73 // Delegate::OnInstructionDecoded() but before Decode() is called again. s_bit()74 bool s_bit() const { return s_bit_; } varint()75 uint64_t varint() const { return varint_; } varint2()76 uint64_t varint2() const { return varint2_; } name()77 const std::string& name() const { return name_; } value()78 const std::string& value() const { return value_; } 79 80 private: 81 enum class State { 82 // Identify instruction. 83 kStartInstruction, 84 // Start decoding next field. 85 kStartField, 86 // Read a single bit. 87 kReadBit, 88 // Start reading integer. 89 kVarintStart, 90 // Resume reading integer. 91 kVarintResume, 92 // Done reading integer. 93 kVarintDone, 94 // Read string. 95 kReadString, 96 // Done reading string. 97 kReadStringDone 98 }; 99 100 // One method for each state. They each return true on success, false on 101 // error (in which case |this| might already be destroyed). Some take input 102 // data and set |*bytes_consumed| to the number of octets processed. Some 103 // take input data but do not consume any bytes. Some do not take any 104 // arguments because they only change internal state. 105 bool DoStartInstruction(absl::string_view data); 106 bool DoStartField(); 107 bool DoReadBit(absl::string_view data); 108 bool DoVarintStart(absl::string_view data, size_t* bytes_consumed); 109 bool DoVarintResume(absl::string_view data, size_t* bytes_consumed); 110 bool DoVarintDone(); 111 bool DoReadString(absl::string_view data, size_t* bytes_consumed); 112 bool DoReadStringDone(); 113 114 // Identify instruction based on opcode encoded in |byte|. 115 // Returns a pointer to an element of |*language_|. 116 const QpackInstruction* LookupOpcode(uint8_t byte) const; 117 118 // Stops decoding and calls Delegate::OnInstructionDecodingError(). 119 void OnError(ErrorCode error_code, absl::string_view error_message); 120 121 // Describes the language used for decoding. 122 const QpackLanguage* const language_; 123 124 // The Delegate to notify of decoded instructions and errors. 125 Delegate* const delegate_; 126 127 // Storage for decoded field values. 128 bool s_bit_; 129 uint64_t varint_; 130 uint64_t varint2_; 131 std::string name_; 132 std::string value_; 133 // Whether the currently decoded header name or value is Huffman encoded. 134 bool is_huffman_encoded_; 135 // Length of string being read into |name_| or |value_|. 136 size_t string_length_; 137 138 // Decoder instance for decoding integers. 139 http2::HpackVarintDecoder varint_decoder_; 140 141 // Decoder instance for decoding Huffman encoded strings. 142 http2::HpackHuffmanDecoder huffman_decoder_; 143 144 // True if a decoding error has been detected by QpackInstructionDecoder. 145 // Only used in QUICHE_DCHECKs. 146 bool error_detected_; 147 148 // Decoding state. 149 State state_; 150 151 // Instruction currently being decoded. 152 const QpackInstruction* instruction_; 153 154 // Field currently being decoded. 155 QpackInstructionFields::const_iterator field_; 156 }; 157 158 } // namespace quic 159 160 #endif // QUICHE_QUIC_CORE_QPACK_QPACK_INSTRUCTION_DECODER_H_ 161