1use super::table::{Index, Table};
2use super::{huffman, Header};
3
4use bytes::{BufMut, BytesMut};
5use http::header::{HeaderName, HeaderValue};
6
7const DEFAULT_MAX_ALLOWED_SIZE: usize = 4 * 1024;
8
9#[derive(Debug)]
10pub struct Encoder {
11 table: Table,
12 max_allowed_size: usize,
13 size_update: Option<SizeUpdate>,
14 scratch: BytesMut,
21}
22
23#[derive(Debug, Copy, Clone, Eq, PartialEq)]
24enum SizeUpdate {
25 One(usize),
26 Two(usize, usize), }
28
29impl Encoder {
30 pub fn new(max_size: usize, capacity: usize) -> Encoder {
31 let max_size = max_size.min(DEFAULT_MAX_ALLOWED_SIZE);
32
33 Encoder {
34 table: Table::new(max_size, capacity),
35 max_allowed_size: DEFAULT_MAX_ALLOWED_SIZE,
36 size_update: None,
37 scratch: BytesMut::new(),
38 }
39 }
40
41 #[cfg(test)]
42 fn set_max_allowed_size(&mut self, max: usize) {
43 self.max_allowed_size = max;
44
45 if self.table.max_size() > max {
46 self.update_max_size(max);
47 }
48 }
49
50 pub(crate) fn take_scratch(&mut self) -> BytesMut {
57 std::mem::take(&mut self.scratch)
58 }
59
60 pub(crate) fn return_scratch(&mut self, scratch: BytesMut) {
62 self.scratch = scratch;
63 }
64
65 pub fn update_max_size(&mut self, val: usize) {
69 let val = val.min(self.max_allowed_size);
70
71 match self.size_update {
72 Some(SizeUpdate::One(old)) => {
73 if val > old {
74 if old > self.table.max_size() {
75 self.size_update = Some(SizeUpdate::One(val));
76 } else {
77 self.size_update = Some(SizeUpdate::Two(old, val));
78 }
79 } else {
80 self.size_update = Some(SizeUpdate::One(val));
81 }
82 }
83 Some(SizeUpdate::Two(min, _)) => {
84 if val < min {
85 self.size_update = Some(SizeUpdate::One(val));
86 } else {
87 self.size_update = Some(SizeUpdate::Two(min, val));
88 }
89 }
90 None => {
91 if val != self.table.max_size() {
92 self.size_update = Some(SizeUpdate::One(val));
95 }
96 }
97 }
98 }
99
100 pub fn encode<I>(&mut self, headers: I, dst: &mut BytesMut)
102 where
103 I: IntoIterator<Item = Header<Option<HeaderName>>>,
104 {
105 let span = tracing::trace_span!("hpack::encode");
106 let _e = span.enter();
107
108 self.encode_size_updates(dst);
109
110 let mut last_index = None;
111
112 for header in headers {
113 match header.reify() {
114 Ok(header) => {
117 let index = self.table.index(header);
118 self.encode_header(&index, dst);
119
120 last_index = Some(index);
121 }
122 Err(value) => {
127 self.encode_header_without_name(
128 last_index.as_ref().unwrap_or_else(|| {
129 panic!("encoding header without name, but no previous index to use for name");
130 }),
131 &value,
132 dst,
133 );
134 }
135 }
136 }
137 }
138
139 fn encode_size_updates(&mut self, dst: &mut BytesMut) {
140 match self.size_update.take() {
141 Some(SizeUpdate::One(val)) => {
142 self.table.resize(val);
143 encode_size_update(val, dst);
144 }
145 Some(SizeUpdate::Two(min, max)) => {
146 self.table.resize(min);
147 self.table.resize(max);
148 encode_size_update(min, dst);
149 encode_size_update(max, dst);
150 }
151 None => {}
152 }
153 }
154
155 fn encode_header(&mut self, index: &Index, dst: &mut BytesMut) {
156 match *index {
157 Index::Indexed(idx, _) => {
158 encode_int(idx, 7, 0x80, dst);
159 }
160 Index::Name(idx, _) => {
161 let header = self.table.resolve(index);
162
163 encode_not_indexed(idx, header.value_slice(), header.is_sensitive(), dst);
164 }
165 Index::Inserted(_) => {
166 let header = self.table.resolve(index);
167
168 assert!(!header.is_sensitive());
169
170 dst.put_u8(0b0100_0000);
171
172 encode_str(header.name().as_slice(), dst);
173 encode_str(header.value_slice(), dst);
174 }
175 Index::InsertedValue(idx, _) => {
176 let header = self.table.resolve(index);
177
178 assert!(!header.is_sensitive());
179
180 encode_int(idx, 6, 0b0100_0000, dst);
181 encode_str(header.value_slice(), dst);
182 }
183 Index::NotIndexed(_) => {
184 let header = self.table.resolve(index);
185
186 encode_not_indexed2(
187 header.name().as_slice(),
188 header.value_slice(),
189 header.is_sensitive(),
190 dst,
191 );
192 }
193 }
194 }
195
196 fn encode_header_without_name(
197 &mut self,
198 last: &Index,
199 value: &HeaderValue,
200 dst: &mut BytesMut,
201 ) {
202 match *last {
203 Index::Indexed(..)
204 | Index::Name(..)
205 | Index::Inserted(..)
206 | Index::InsertedValue(..) => {
207 let idx = self.table.resolve_idx(last);
208
209 encode_not_indexed(idx, value.as_ref(), value.is_sensitive(), dst);
210 }
211 Index::NotIndexed(_) => {
212 let last = self.table.resolve(last);
213
214 encode_not_indexed2(
215 last.name().as_slice(),
216 value.as_ref(),
217 value.is_sensitive(),
218 dst,
219 );
220 }
221 }
222 }
223}
224
225impl Default for Encoder {
226 fn default() -> Encoder {
227 Encoder::new(4096, 0)
228 }
229}
230
231fn encode_size_update(val: usize, dst: &mut BytesMut) {
232 encode_int(val, 5, 0b0010_0000, dst)
233}
234
235fn encode_not_indexed(name: usize, value: &[u8], sensitive: bool, dst: &mut BytesMut) {
236 if sensitive {
237 encode_int(name, 4, 0b10000, dst);
238 } else {
239 encode_int(name, 4, 0, dst);
240 }
241
242 encode_str(value, dst);
243}
244
245fn encode_not_indexed2(name: &[u8], value: &[u8], sensitive: bool, dst: &mut BytesMut) {
246 if sensitive {
247 dst.put_u8(0b10000);
248 } else {
249 dst.put_u8(0);
250 }
251
252 encode_str(name, dst);
253 encode_str(value, dst);
254}
255
256fn encode_str(val: &[u8], dst: &mut BytesMut) {
257 if !val.is_empty() {
258 let idx = position(dst);
259
260 dst.put_u8(0);
262
263 huffman::encode(val, dst);
265
266 let huff_len = position(dst) - (idx + 1);
267
268 if encode_int_one_byte(huff_len, 7) {
269 dst[idx] = 0x80 | huff_len as u8;
271 } else {
272 const PLACEHOLDER_LEN: usize = 8;
274 let mut buf = [0u8; PLACEHOLDER_LEN];
275
276 let head_len = {
277 let mut head_dst = &mut buf[..];
278 encode_int(huff_len, 7, 0x80, &mut head_dst);
279 PLACEHOLDER_LEN - head_dst.remaining_mut()
280 };
281
282 dst.put_slice(&buf[1..head_len]);
284
285 for i in 0..huff_len {
287 let src_i = idx + 1 + (huff_len - (i + 1));
288 let dst_i = idx + head_len + (huff_len - (i + 1));
289 dst[dst_i] = dst[src_i];
290 }
291
292 for i in 0..head_len {
294 dst[idx + i] = buf[i];
295 }
296 }
297 } else {
298 dst.put_u8(0);
300 }
301}
302
303fn encode_int<B: BufMut>(
305 mut value: usize, prefix_bits: usize, first_byte: u8, dst: &mut B,
309) {
310 if encode_int_one_byte(value, prefix_bits) {
311 dst.put_u8(first_byte | value as u8);
312 return;
313 }
314
315 let low = (1 << prefix_bits) - 1;
316
317 value -= low;
318
319 dst.put_u8(first_byte | low as u8);
320
321 while value >= 128 {
322 dst.put_u8(0b1000_0000 | value as u8);
323
324 value >>= 7;
325 }
326
327 dst.put_u8(value as u8);
328}
329
330fn encode_int_one_byte(value: usize, prefix_bits: usize) -> bool {
332 value < (1 << prefix_bits) - 1
333}
334
335fn position(buf: &BytesMut) -> usize {
336 buf.len()
337}
338
339#[cfg(test)]
340mod test {
341 use super::*;
342 use http::*;
343
344 #[test]
345 fn test_encode_method_get() {
346 let mut encoder = Encoder::default();
347 let res = encode(&mut encoder, vec![method("GET")]);
348 assert_eq!(*res, [0x80 | 2]);
349 assert_eq!(encoder.table.len(), 0);
350 }
351
352 #[test]
353 fn test_encode_method_post() {
354 let mut encoder = Encoder::default();
355 let res = encode(&mut encoder, vec![method("POST")]);
356 assert_eq!(*res, [0x80 | 3]);
357 assert_eq!(encoder.table.len(), 0);
358 }
359
360 #[test]
361 fn test_encode_method_patch() {
362 let mut encoder = Encoder::default();
363 let res = encode(&mut encoder, vec![method("PATCH")]);
364
365 assert_eq!(res[0], 0b01000000 | 2); assert_eq!(res[1], 0x80 | 5); assert_eq!("PATCH", huff_decode(&res[2..7]));
369 assert_eq!(encoder.table.len(), 1);
370
371 let res = encode(&mut encoder, vec![method("PATCH")]);
372
373 assert_eq!(1 << 7 | 62, res[0]);
374 assert_eq!(1, res.len());
375 }
376
377 #[test]
378 fn test_encode_indexed_name_literal_value() {
379 let mut encoder = Encoder::default();
380 let res = encode(&mut encoder, vec![header("content-language", "foo")]);
381
382 assert_eq!(res[0], 0b01000000 | 27); assert_eq!(res[1], 0x80 | 2); assert_eq!("foo", huff_decode(&res[2..4]));
386
387 let res = encode(&mut encoder, vec![header("content-language", "bar")]);
389 assert_eq!(res[0], 0b01000000 | 27); assert_eq!(res[1], 0x80 | 3); assert_eq!("bar", huff_decode(&res[2..5]));
392 }
393
394 #[test]
395 fn test_repeated_headers_are_indexed() {
396 let mut encoder = Encoder::default();
397 let res = encode(&mut encoder, vec![header("foo", "hello")]);
398
399 assert_eq!(&[0b01000000, 0x80 | 2], &res[0..2]);
400 assert_eq!("foo", huff_decode(&res[2..4]));
401 assert_eq!(0x80 | 4, res[4]);
402 assert_eq!("hello", huff_decode(&res[5..]));
403 assert_eq!(9, res.len());
404
405 assert_eq!(1, encoder.table.len());
406
407 let res = encode(&mut encoder, vec![header("foo", "hello")]);
408 assert_eq!([0x80 | 62], *res);
409
410 assert_eq!(encoder.table.len(), 1);
411 }
412
413 #[test]
414 fn test_evicting_headers() {
415 let mut encoder = Encoder::default();
416
417 for i in 0..64 {
419 let key = format!("x-hello-world-{:02}", i);
420 let res = encode(&mut encoder, vec![header(&key, &key)]);
421
422 assert_eq!(&[0b01000000, 0x80 | 12], &res[0..2]);
423 assert_eq!(key, huff_decode(&res[2..14]));
424 assert_eq!(0x80 | 12, res[14]);
425 assert_eq!(key, huff_decode(&res[15..]));
426 assert_eq!(27, res.len());
427
428 let res = encode(&mut encoder, vec![header(&key, &key)]);
430
431 assert_eq!(0x80, res[0] & 0x80);
433 }
434
435 assert_eq!(4096, encoder.table.size());
436 assert_eq!(64, encoder.table.len());
437
438 for i in 0..64 {
440 let key = format!("x-hello-world-{:02}", i);
441 let res = encode(&mut encoder, vec![header(&key, &key)]);
442 assert_eq!(0x80, res[0] & 0x80);
443 }
444
445 let key = "x-hello-world-64";
447 let res = encode(&mut encoder, vec![header(key, key)]);
448
449 assert_eq!(&[0b01000000, 0x80 | 12], &res[0..2]);
450 assert_eq!(key, huff_decode(&res[2..14]));
451 assert_eq!(0x80 | 12, res[14]);
452 assert_eq!(key, huff_decode(&res[15..]));
453 assert_eq!(27, res.len());
454
455 assert_eq!(64, encoder.table.len());
456
457 for i in 1..65 {
459 let key = format!("x-hello-world-{:02}", i);
460 let res = encode(&mut encoder, vec![header(&key, &key)]);
461 assert_eq!(0x80 | (61 + (65 - i)), res[0]);
462 }
463 }
464
465 #[test]
466 fn test_large_headers_are_not_indexed() {
467 let mut encoder = Encoder::new(128, 0);
468 let key = "hello-world-hello-world-HELLO-zzz";
469
470 let res = encode(&mut encoder, vec![header(key, key)]);
471
472 assert_eq!(&[0, 0x80 | 25], &res[..2]);
473
474 assert_eq!(0, encoder.table.len());
475 assert_eq!(0, encoder.table.size());
476 }
477
478 #[test]
479 fn test_sensitive_headers_are_never_indexed() {
480 use http::header::HeaderValue;
481
482 let name = "my-password".parse().unwrap();
483 let mut value = HeaderValue::from_bytes(b"12345").unwrap();
484 value.set_sensitive(true);
485
486 let header = Header::Field {
487 name: Some(name),
488 value,
489 };
490
491 let mut encoder = Encoder::default();
494 let res = encode(&mut encoder, vec![header]);
495
496 assert_eq!(&[0b10000, 0x80 | 8], &res[..2]);
497 assert_eq!("my-password", huff_decode(&res[2..10]));
498 assert_eq!(0x80 | 4, res[10]);
499 assert_eq!("12345", huff_decode(&res[11..]));
500
501 let name = "authorization".parse().unwrap();
503 let mut value = HeaderValue::from_bytes(b"12345").unwrap();
504 value.set_sensitive(true);
505
506 let header = Header::Field {
507 name: Some(name),
508 value,
509 };
510
511 let mut encoder = Encoder::default();
512 let res = encode(&mut encoder, vec![header]);
513
514 assert_eq!(&[0b11111, 8], &res[..2]);
515 assert_eq!(0x80 | 4, res[2]);
516 assert_eq!("12345", huff_decode(&res[3..]));
517
518 let _ = encode(
522 &mut encoder,
523 vec![self::header("my-password", "not-so-secret")],
524 );
525
526 let name = "my-password".parse().unwrap();
527 let mut value = HeaderValue::from_bytes(b"12345").unwrap();
528 value.set_sensitive(true);
529
530 let header = Header::Field {
531 name: Some(name),
532 value,
533 };
534 let res = encode(&mut encoder, vec![header]);
535
536 assert_eq!(&[0b11111, 47], &res[..2]);
537 assert_eq!(0x80 | 4, res[2]);
538 assert_eq!("12345", huff_decode(&res[3..]));
539 }
540
541 #[test]
542 fn test_content_length_value_not_indexed() {
543 let mut encoder = Encoder::default();
544 let res = encode(&mut encoder, vec![header("content-length", "1234")]);
545
546 assert_eq!(&[15, 13, 0x80 | 3], &res[0..3]);
547 assert_eq!("1234", huff_decode(&res[3..]));
548 assert_eq!(6, res.len());
549 }
550
551 #[test]
552 fn test_encoding_headers_with_same_name() {
553 let mut encoder = Encoder::default();
554 let name = "hello";
555
556 let _ = encode(&mut encoder, vec![header(name, "one")]);
558
559 let res = encode(&mut encoder, vec![header(name, "two")]);
561 assert_eq!(&[0x40 | 62, 0x80 | 3], &res[0..2]);
562 assert_eq!("two", huff_decode(&res[2..]));
563 assert_eq!(5, res.len());
564
565 let res = encode(&mut encoder, vec![header(name, "one")]);
567 assert_eq!(&[0x80 | 63], &res[..]);
568
569 let res = encode(&mut encoder, vec![header(name, "two")]);
571 assert_eq!(&[0x80 | 62], &res[..]);
572 }
573
574 #[test]
575 fn test_evicting_headers_when_multiple_of_same_name_are_in_table() {
576 let mut encoder = Encoder::new(76, 0);
578
579 let _ = encode(&mut encoder, vec![header("foo", "bar")]);
580 assert_eq!(1, encoder.table.len());
581
582 let _ = encode(&mut encoder, vec![header("bar", "foo")]);
583 assert_eq!(2, encoder.table.len());
584
585 let res = encode(&mut encoder, vec![header("foo", "baz")]);
588 assert_eq!(&[0x40 | 63, 0, 0x80 | 3], &res[..3]);
589 assert_eq!(2, encoder.table.len());
590
591 let res = encode(&mut encoder, vec![header("foo", "baz")]);
593 assert_eq!(&[0x80 | 62], &res[..]);
594 assert_eq!(2, encoder.table.len());
595 }
596
597 #[test]
598 fn test_max_size_zero() {
599 let mut encoder = Encoder::new(0, 0);
601 let res = encode(&mut encoder, vec![method("GET")]);
602 assert_eq!(*res, [0x80 | 2]);
603 assert_eq!(encoder.table.len(), 0);
604
605 let res = encode(&mut encoder, vec![header("foo", "bar")]);
606 assert_eq!(&[0, 0x80 | 2], &res[..2]);
607 assert_eq!("foo", huff_decode(&res[2..4]));
608 assert_eq!(0x80 | 3, res[4]);
609 assert_eq!("bar", huff_decode(&res[5..8]));
610 assert_eq!(0, encoder.table.len());
611
612 let res = encode(&mut encoder, vec![header("transfer-encoding", "chunked")]);
614 assert_eq!(&[15, 42, 0x80 | 6], &res[..3]);
615 assert_eq!("chunked", huff_decode(&res[3..]));
616 }
617
618 #[test]
619 fn test_update_max_size_combos() {
620 let mut encoder = Encoder::default();
621 assert!(encoder.size_update.is_none());
622 assert_eq!(4096, encoder.table.max_size());
623
624 encoder.update_max_size(4096); assert!(encoder.size_update.is_none());
626
627 encoder.update_max_size(0);
628 assert_eq!(Some(SizeUpdate::One(0)), encoder.size_update);
629
630 encoder.update_max_size(100);
631 assert_eq!(Some(SizeUpdate::Two(0, 100)), encoder.size_update);
632
633 let mut encoder = Encoder::default();
634 encoder.set_max_allowed_size(8000);
635 encoder.update_max_size(8000);
636 assert_eq!(Some(SizeUpdate::One(8000)), encoder.size_update);
637
638 encoder.update_max_size(100);
639 assert_eq!(Some(SizeUpdate::One(100)), encoder.size_update);
640
641 encoder.update_max_size(8000);
642 assert_eq!(Some(SizeUpdate::Two(100, 8000)), encoder.size_update);
643
644 encoder.update_max_size(4000);
645 assert_eq!(Some(SizeUpdate::Two(100, 4000)), encoder.size_update);
646
647 encoder.update_max_size(50);
648 assert_eq!(Some(SizeUpdate::One(50)), encoder.size_update);
649 }
650
651 #[test]
652 fn test_resizing_table() {
653 let mut encoder = Encoder::default();
654
655 let _ = encode(&mut encoder, vec![header("foo", "bar")]);
657
658 encoder.update_max_size(1);
659 assert_eq!(1, encoder.table.len());
660
661 let res = encode(&mut encoder, vec![method("GET")]);
662 assert_eq!(&[32 | 1, 0x80 | 2], &res[..]);
663 assert_eq!(0, encoder.table.len());
664
665 let res = encode(&mut encoder, vec![header("foo", "bar")]);
666 assert_eq!(0, res[0]);
667
668 encoder.update_max_size(100);
669 let res = encode(&mut encoder, vec![header("foo", "bar")]);
670 assert_eq!(&[32 | 31, 69, 64], &res[..3]);
671
672 encoder.update_max_size(0);
673 let res = encode(&mut encoder, vec![header("foo", "bar")]);
674 assert_eq!(&[32, 0], &res[..2]);
675 }
676
677 #[test]
678 fn test_decreasing_table_size_without_eviction() {
679 let mut encoder = Encoder::default();
680
681 let _ = encode(&mut encoder, vec![header("foo", "bar")]);
683
684 encoder.update_max_size(100);
685 assert_eq!(1, encoder.table.len());
686
687 let res = encode(&mut encoder, vec![header("foo", "bar")]);
688 assert_eq!(&[32 | 31, 69, 0x80 | 62], &res[..]);
689 }
690
691 #[test]
692 fn test_nameless_header() {
693 let mut encoder = Encoder::default();
694
695 let res = encode(
696 &mut encoder,
697 vec![
698 Header::Field {
699 name: Some("hello".parse().unwrap()),
700 value: HeaderValue::from_bytes(b"world").unwrap(),
701 },
702 Header::Field {
703 name: None,
704 value: HeaderValue::from_bytes(b"zomg").unwrap(),
705 },
706 ],
707 );
708
709 assert_eq!(&[0x40, 0x80 | 4], &res[0..2]);
710 assert_eq!("hello", huff_decode(&res[2..6]));
711 assert_eq!(0x80 | 4, res[6]);
712 assert_eq!("world", huff_decode(&res[7..11]));
713
714 assert_eq!(&[15, 47, 0x80 | 3], &res[11..14]);
716 assert_eq!("zomg", huff_decode(&res[14..]));
717 }
718
719 #[test]
720 fn test_large_size_update() {
721 let mut encoder = Encoder::default();
722 encoder.set_max_allowed_size(usize::MAX);
723
724 encoder.update_max_size(1912930560);
725 assert_eq!(Some(SizeUpdate::One(1912930560)), encoder.size_update);
726
727 let mut dst = BytesMut::with_capacity(6);
728 encoder.encode_size_updates(&mut dst);
729 assert_eq!([63, 225, 129, 148, 144, 7], &dst[..]);
730 }
731
732 #[test]
733 fn test_large_size_update_is_capped() {
734 let mut encoder = Encoder::new(0, 0);
735
736 encoder.update_max_size(1912930560);
737 assert_eq!(
738 Some(SizeUpdate::One(DEFAULT_MAX_ALLOWED_SIZE)),
739 encoder.size_update
740 );
741
742 let mut dst = BytesMut::with_capacity(3);
743 encoder.encode_size_updates(&mut dst);
744 assert_eq!([63, 225, 31], &dst[..]);
745 assert_eq!(DEFAULT_MAX_ALLOWED_SIZE, encoder.table.max_size());
746 }
747
748 #[test]
749 #[ignore]
750 fn test_evicted_overflow() {
751 }
753
754 fn encode(e: &mut Encoder, hdrs: Vec<Header<Option<HeaderName>>>) -> BytesMut {
755 let mut dst = BytesMut::with_capacity(1024);
756 e.encode(hdrs, &mut dst);
757 dst
758 }
759
760 fn method(s: &str) -> Header<Option<HeaderName>> {
761 Header::Method(Method::from_bytes(s.as_bytes()).unwrap())
762 }
763
764 fn header(name: &str, val: &str) -> Header<Option<HeaderName>> {
765 let name = HeaderName::from_bytes(name.as_bytes()).unwrap();
766 let value = HeaderValue::from_bytes(val.as_bytes()).unwrap();
767
768 Header::Field {
769 name: Some(name),
770 value,
771 }
772 }
773
774 fn huff_decode(src: &[u8]) -> BytesMut {
775 let mut buf = BytesMut::new();
776 huffman::decode(src, &mut buf).unwrap()
777 }
778}