1pub use encoder::encode_int;
30pub use encoder::encode_str;
31
32pub const INDEXED: u8 = 0b1000_0000;
33pub const INDEXED_WITH_POST_BASE: u8 = 0b0001_0000;
34pub const LITERAL: u8 = 0b0010_0000;
35pub const LITERAL_WITH_NAME_REF: u8 = 0b0100_0000;
36
37pub type Result<T> = std::result::Result<T, Error>;
44
45#[derive(Clone, Copy, Debug, PartialEq, Eq)]
47pub enum Error {
48 BufferTooShort,
50
51 InflatedHuffmanEncoding,
53
54 InvalidHuffmanEncoding,
56
57 InvalidStaticTableIndex,
59
60 InvalidHeaderValue,
62
63 HeaderListTooLarge,
65}
66
67impl std::fmt::Display for Error {
68 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
69 write!(f, "{self:?}")
70 }
71}
72
73impl std::error::Error for Error {
74 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
75 None
76 }
77}
78
79impl From<octets::BufferTooShortError> for Error {
80 fn from(_err: octets::BufferTooShortError) -> Self {
81 Error::BufferTooShort
82 }
83}
84
85#[cfg(test)]
86mod tests {
87 use crate::*;
88
89 use super::*;
90
91 #[test]
92 fn encode_decode() {
93 let mut encoded = [0u8; 240];
94
95 let headers = vec![
96 h3::Header::new(b":path", b"/rsrc.php/v3/yn/r/rIPZ9Qkrdd9.png"),
97 h3::Header::new(b"accept-encoding", b"gzip, deflate, br"),
98 h3::Header::new(b"accept-language", b"en-US,en;q=0.9"),
99 h3::Header::new(b"user-agent", b"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.70 Safari/537.36"),
100 h3::Header::new(b"accept", b"image/webp,image/apng,image/*,*/*;q=0.8"),
101 h3::Header::new(b"referer", b"https://static.xx.fbcdn.net/rsrc.php/v3/yT/l/0,cross/dzXGESIlGQQ.css"),
102 h3::Header::new(b":authority", b"static.xx.fbcdn.net"),
103 h3::Header::new(b":scheme", b"https"),
104 h3::Header::new(b":method", b"GET"),
105 ];
106
107 let mut enc = Encoder::new();
108 assert_eq!(enc.encode(&headers, &mut encoded), Ok(240));
109
110 let mut dec = Decoder::new();
111 assert_eq!(dec.decode(&encoded, u64::MAX), Ok(headers));
112 }
113
114 #[test]
115 fn lower_case() {
116 let mut encoded = [0u8; 35];
117
118 let headers_expected = vec![
119 h3::Header::new(b":status", b"200"),
120 h3::Header::new(b":path", b"/HeLlO"),
121 h3::Header::new(b"woot", b"woot"),
122 h3::Header::new(b"hello", b"WorlD"),
123 h3::Header::new(b"foo", b"BaR"),
124 ];
125
126 let headers_in = vec![
128 h3::Header::new(b":StAtUs", b"200"),
129 h3::Header::new(b":PaTh", b"/HeLlO"),
130 h3::Header::new(b"WooT", b"woot"),
131 h3::Header::new(b"hello", b"WorlD"),
132 h3::Header::new(b"fOo", b"BaR"),
133 ];
134
135 let mut enc = Encoder::new();
136 assert_eq!(enc.encode(&headers_in, &mut encoded), Ok(35));
137
138 let mut dec = Decoder::new();
139 let headers_out = dec.decode(&encoded, u64::MAX).unwrap();
140
141 assert_eq!(headers_expected, headers_out);
142
143 let headers_in = vec![
145 h3::HeaderRef::new(b":StAtUs", b"200"),
146 h3::HeaderRef::new(b":PaTh", b"/HeLlO"),
147 h3::HeaderRef::new(b"WooT", b"woot"),
148 h3::HeaderRef::new(b"hello", b"WorlD"),
149 h3::HeaderRef::new(b"fOo", b"BaR"),
150 ];
151
152 let mut enc = Encoder::new();
153 assert_eq!(enc.encode(&headers_in, &mut encoded), Ok(35));
154
155 let mut dec = Decoder::new();
156 let headers_out = dec.decode(&encoded, u64::MAX).unwrap();
157
158 assert_eq!(headers_expected, headers_out);
159 }
160
161 #[test]
162 fn lower_ascii_range() {
163 let mut encoded = [0u8; 50];
164 let mut enc = Encoder::new();
165
166 let headers1 = vec![h3::Header::new(b"location", b" ")];
168 assert_eq!(enc.encode(&headers1, &mut encoded), Ok(19));
169
170 let headers2 = vec![h3::Header::new(b"a", b"")];
172 assert_eq!(enc.encode(&headers2, &mut encoded), Ok(20));
173
174 let headers3 = vec![h3::Header::new(b" ", b"hello")];
175 assert_eq!(enc.encode(&headers3, &mut encoded), Ok(24));
176 }
177
178 #[test]
179 fn extended_ascii_range() {
180 let mut encoded = [0u8; 50];
181 let mut enc = Encoder::new();
182
183 let name = b"location";
184 let value = "£££££££££££££££";
185
186 let headers1 = vec![h3::Header::new(name, value.as_bytes())];
188 assert_eq!(enc.encode(&headers1, &mut encoded), Ok(34));
189
190 let value = "ððððððððððððððð";
192 let headers2 = vec![h3::Header::new(b"a", value.as_bytes())];
193 assert_eq!(enc.encode(&headers2, &mut encoded), Ok(35));
194
195 let headers3 = vec![h3::Header::new(value.as_bytes(), b"hello")];
196 assert_eq!(enc.encode(&headers3, &mut encoded), Ok(39));
197 }
198}
199
200pub use decoder::Decoder;
201pub use encoder::Encoder;
202
203mod decoder;
204mod encoder;
205mod huffman;
206mod static_table;