1 // Copyright (c) 2023 Huawei Device Co., Ltd. 2 // Licensed under the Apache License, Version 2.0 (the "License"); 3 // you may not use this file except in compliance with the License. 4 // You may obtain a copy of the License at 5 // 6 // http://www.apache.org/licenses/LICENSE-2.0 7 // 8 // Unless required by applicable law or agreed to in writing, software 9 // distributed under the License is distributed on an "AS IS" BASIS, 10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 pub mod decoder; 15 pub mod encoder; 16 pub(crate) mod error; 17 pub mod format; 18 mod integer; 19 pub mod table; 20 pub(crate) use decoder::{FieldDecodeState, FiledLines, QpackDecoder}; 21 pub(crate) use encoder::{DecoderInst, QpackEncoder}; 22 23 use crate::h3::qpack::format::decoder::Name; 24 25 pub(crate) struct RequireInsertCount(usize); 26 27 pub(crate) struct DeltaBase(usize); 28 29 #[derive(Copy, Clone, PartialEq, Eq)] 30 pub(crate) struct EncoderInstPrefixBit(u8); 31 32 #[derive(Copy, Clone, PartialEq, Eq)] 33 pub(crate) struct DecoderInstPrefixBit(u8); 34 35 #[derive(Copy, Clone, PartialEq, Eq)] 36 pub(crate) struct ReprPrefixBit(u8); 37 38 /// # Prefix bit: 39 /// ## Encoder Instructions: 40 /// SET_CAP: 0x20 41 /// INSERT_WITH_INDEX: 0x80 42 /// INSERT_WITH_LITERAL: 0x40 43 /// DUPLICATE: 0x00 44 /// 45 /// ## Decoder Instructions: 46 /// ACK: 0x80 47 /// STREAM_CANCEL: 0x40 48 /// INSERT_COUNT_INCREMENT: 0x00 49 /// 50 /// ## Representation: 51 /// INDEXED: 0x80 52 /// INDEXEDWITHPOSTINDEX: 0x10 53 /// LITERALWITHINDEXING: 0x40 54 /// LITERALWITHPOSTINDEXING: 0x00 55 /// LITERALWITHLITERALNAME: 0x20 56 57 impl DecoderInstPrefixBit { 58 pub(crate) const ACK: Self = Self(0x80); 59 pub(crate) const STREAM_CANCEL: Self = Self(0x40); 60 pub(crate) const INSERT_COUNT_INCREMENT: Self = Self(0x00); 61 from_u8(byte: u8) -> Self62 pub(crate) fn from_u8(byte: u8) -> Self { 63 match byte { 64 x if x & 0x80 == 0x80 => Self::ACK, 65 x if x & 0xC0 == 0x40 => Self::STREAM_CANCEL, 66 x if x & 0xC0 == 0x0 => Self::INSERT_COUNT_INCREMENT, 67 _ => unreachable!(), 68 } 69 } 70 prefix_index_mask(&self) -> PrefixMask71 pub(crate) fn prefix_index_mask(&self) -> PrefixMask { 72 match self.0 { 73 0x80 => PrefixMask::ACK, 74 0x40 => PrefixMask::STREAM_CANCEL, 75 0x0 => PrefixMask::INSERT_COUNT_INCREMENT, 76 _ => unreachable!(), 77 } 78 } 79 prefix_midbit_value(&self) -> MidBit80 pub(crate) fn prefix_midbit_value(&self) -> MidBit { 81 MidBit { 82 n: None, 83 t: None, 84 h: None, 85 } 86 } 87 } 88 89 impl EncoderInstPrefixBit { 90 pub(crate) const SET_CAP: Self = Self(0x20); 91 pub(crate) const INSERT_WITH_INDEX: Self = Self(0x80); 92 pub(crate) const INSERT_WITH_LITERAL: Self = Self(0x40); 93 pub(crate) const DUPLICATE: Self = Self(0x00); 94 from_u8(byte: u8) -> Self95 pub(crate) fn from_u8(byte: u8) -> Self { 96 match byte { 97 x if x >= 0x80 => Self::INSERT_WITH_INDEX, 98 x if x >= 0x40 => Self::INSERT_WITH_LITERAL, 99 x if x >= 0x20 => Self::SET_CAP, 100 _ => Self::DUPLICATE, 101 } 102 } 103 prefix_index_mask(&self) -> PrefixMask104 pub(crate) fn prefix_index_mask(&self) -> PrefixMask { 105 match self.0 { 106 0x80 => PrefixMask::INSERT_WITH_INDEX, 107 0x40 => PrefixMask::INSERT_WITH_LITERAL, 108 0x20 => PrefixMask::SET_CAP, 109 _ => PrefixMask::DUPLICATE, 110 } 111 } 112 prefix_midbit_value(&self, byte: u8) -> MidBit113 pub(crate) fn prefix_midbit_value(&self, byte: u8) -> MidBit { 114 match self.0 { 115 0x80 => MidBit { 116 n: None, 117 t: Some((byte & 0x40) != 0), 118 h: None, 119 }, 120 0x40 => MidBit { 121 n: None, 122 t: None, 123 h: Some((byte & 0x20) != 0), 124 }, 125 0x20 => MidBit { 126 n: None, 127 t: None, 128 h: None, 129 }, 130 _ => MidBit { 131 n: None, 132 t: None, 133 h: None, 134 }, 135 } 136 } 137 } 138 139 impl ReprPrefixBit { 140 // 此处的值为前缀1的位置,并没有实际意义 141 pub(crate) const INDEXED: Self = Self(0x80); 142 pub(crate) const INDEXEDWITHPOSTINDEX: Self = Self(0x10); 143 pub(crate) const LITERALWITHINDEXING: Self = Self(0x40); 144 pub(crate) const LITERALWITHPOSTINDEXING: Self = Self(0x00); 145 pub(crate) const LITERALWITHLITERALNAME: Self = Self(0x20); 146 147 /// Creates a `PrefixBit` from a byte. The interface will convert the 148 /// incoming byte to the most suitable prefix bit. from_u8(byte: u8) -> Self149 pub(crate) fn from_u8(byte: u8) -> Self { 150 match byte { 151 x if x >= 0x80 => Self::INDEXED, 152 x if x >= 0x40 => Self::LITERALWITHINDEXING, 153 x if x >= 0x20 => Self::LITERALWITHLITERALNAME, 154 x if x >= 0x10 => Self::INDEXEDWITHPOSTINDEX, 155 _ => Self::LITERALWITHPOSTINDEXING, 156 } 157 } 158 159 /// Returns the corresponding `PrefixIndexMask` according to the current 160 /// prefix bit. prefix_index_mask(&self) -> PrefixMask161 pub(crate) fn prefix_index_mask(&self) -> PrefixMask { 162 match self.0 { 163 0x80 => PrefixMask::INDEXED, 164 0x40 => PrefixMask::INDEXING_WITH_NAME, 165 0x20 => PrefixMask::INDEXING_WITH_LITERAL, 166 0x10 => PrefixMask::INDEXED_WITH_POST_NAME, 167 _ => PrefixMask::INDEXING_WITH_LITERAL, 168 } 169 } 170 171 /// Unlike Hpack, QPACK has some special value for the first byte of an 172 /// integer. Like T indicating whether the reference is into the static 173 /// or dynamic table. prefix_midbit_value(&self, byte: u8) -> MidBit174 pub(crate) fn prefix_midbit_value(&self, byte: u8) -> MidBit { 175 match self.0 { 176 0x80 => MidBit { 177 n: None, 178 t: Some((byte & 0x40) != 0), 179 h: None, 180 }, 181 0x40 => MidBit { 182 n: Some((byte & 0x20) != 0), 183 t: Some((byte & 0x10) != 0), 184 h: None, 185 }, 186 0x20 => MidBit { 187 n: Some((byte & 0x10) != 0), 188 t: None, 189 h: Some((byte & 0x08) != 0), 190 }, 191 0x10 => MidBit { 192 n: None, 193 t: None, 194 h: None, 195 }, 196 _ => MidBit { 197 n: Some((byte & 0x08) != 0), 198 t: None, 199 h: None, 200 }, 201 } 202 } 203 } 204 205 pub(crate) enum EncoderInstruction { 206 SetCap { 207 capacity: usize, 208 }, 209 InsertWithIndex { 210 mid_bit: MidBit, 211 name: Name, 212 value: Vec<u8>, 213 }, 214 InsertWithLiteral { 215 mid_bit: MidBit, 216 name: Name, 217 value: Vec<u8>, 218 }, 219 Duplicate { 220 index: usize, 221 }, 222 } 223 224 pub(crate) enum DecoderInstruction { 225 Ack { stream_id: usize }, 226 StreamCancel { stream_id: usize }, 227 InsertCountIncrement { increment: usize }, 228 } 229 230 pub(crate) enum Representation { 231 /// An indexed field line format identifies an entry in the static table or 232 /// an entry in the dynamic table with an absolute index less than the 233 /// value of the Base. 0 1 2 3 4 5 6 7 234 /// +---+---+---+---+---+---+---+---+ 235 /// | 1 | T | Index (6+) | 236 /// +---+---+-----------------------+ 237 /// This format starts with the '1' 1-bit pattern, followed by the 'T' bit, 238 /// indicating whether the reference is into the static or dynamic 239 /// table. The 6-bit prefix integer (Section 4.1.1) that follows is used 240 /// to locate the table entry for the field line. When T=1, the number 241 /// represents the static table index; when T=0, the number is the relative 242 /// index of the entry in the dynamic table. 243 FieldSectionPrefix { 244 require_insert_count: RequireInsertCount, 245 signal: bool, 246 delta_base: DeltaBase, 247 }, 248 249 Indexed { 250 mid_bit: MidBit, 251 index: usize, 252 }, 253 IndexedWithPostIndex { 254 index: usize, 255 }, 256 LiteralWithIndexing { 257 mid_bit: MidBit, 258 name: Name, 259 value: Vec<u8>, 260 }, 261 LiteralWithPostIndexing { 262 mid_bit: MidBit, 263 name: Name, 264 value: Vec<u8>, 265 }, 266 LiteralWithLiteralName { 267 mid_bit: MidBit, 268 name: Name, 269 value: Vec<u8>, 270 }, 271 } 272 273 // impl debug for Representation 274 275 pub(crate) struct MidBit { 276 //'N', indicates whether an intermediary is permitted to add this field line to the dynamic 277 // table on subsequent hops. 278 n: Option<bool>, 279 //'T', indicating whether the reference is into the static or dynamic table. 280 t: Option<bool>, 281 //'H', indicating whether is represented as a Huffman-encoded. 282 h: Option<bool>, 283 } 284 285 pub(crate) struct PrefixMask(u8); 286 287 impl PrefixMask { 288 pub(crate) const REQUIRE_INSERT_COUNT: Self = Self(0xff); 289 pub(crate) const DELTA_BASE: Self = Self(0x7f); 290 pub(crate) const INDEXED: Self = Self(0x3f); 291 pub(crate) const SET_CAP: Self = Self(0x1f); 292 pub(crate) const INSERT_WITH_INDEX: Self = Self(0x3f); 293 pub(crate) const INSERT_WITH_LITERAL: Self = Self(0x1f); 294 pub(crate) const DUPLICATE: Self = Self(0x1f); 295 pub(crate) const ACK: Self = Self(0x7f); 296 pub(crate) const STREAM_CANCEL: Self = Self(0x3f); 297 pub(crate) const INSERT_COUNT_INCREMENT: Self = Self(0x3f); 298 pub(crate) const INDEXING_WITH_NAME: Self = Self(0x0f); 299 pub(crate) const INDEXING_WITH_POST_NAME: Self = Self(0x07); 300 pub(crate) const INDEXING_WITH_LITERAL: Self = Self(0x07); 301 pub(crate) const INDEXED_WITH_POST_NAME: Self = Self(0x0f); 302 } 303