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 use crate::h3::frame::Headers;
15 use crate::h3::parts::Parts;
16 use crate::h3::qpack::error::H3Error_QPACK;
17 use crate::h3::qpack::table::DynamicTable;
18 use crate::h3::qpack::{FiledLines, QpackDecoder};
19 
20 pub struct FrameDecoder<'a> {
21     qpack_decoder: QpackDecoder<'a>,
22     headers: Parts,
23     qpack_encoder_buffer: Vec<u8>,
24     remaining_qpack_payload: usize,
25     stream_id: usize,
26 }
27 
28 impl<'a> FrameDecoder<'a> {
new( field_list_size: usize, table: &'a mut DynamicTable, stream_id: usize, ) -> Self29     pub(crate) fn new(
30         field_list_size: usize,
31         table: &'a mut DynamicTable,
32         stream_id: usize,
33     ) -> Self {
34         let frame_decoder = Self {
35             qpack_decoder: QpackDecoder::new(field_list_size, table),
36             headers: Parts::new(),
37             qpack_encoder_buffer: vec![0; 16383],
38             remaining_qpack_payload: 0,
39             stream_id: stream_id,
40         };
41         frame_decoder
42     }
43 
44     /// User call `decode_header` to decode headers.
decode_header(&mut self, headers_payload: &[u8]) -> Result<(), H3Error_QPACK>45     pub(crate) fn decode_header(&mut self, headers_payload: &[u8]) -> Result<(), H3Error_QPACK> {
46         self.qpack_decoder.decode_repr(&headers_payload)
47     }
48 
49     /// User call `finish_decode_header` to finish decode a stream.
finish_decode_header(&mut self)50     pub(crate) fn finish_decode_header(&mut self) {
51         let results = self.qpack_decoder.finish(
52             self.stream_id,
53             &mut self.qpack_encoder_buffer[self.remaining_qpack_payload..],
54         );
55         if let Ok((header, cur_)) = results {
56             self.headers = header;
57             if let Some(cur) = cur_ {
58                 self.remaining_qpack_payload += cur;
59             }
60         }
61     }
62 
63     /// User call `decode_qpack_ins` to decode peer's qpack_encoder_stream.
decode_qpack_ins(&mut self, qpack_ins: &[u8]) -> Result<(), H3Error_QPACK>64     pub(crate) fn decode_qpack_ins(&mut self, qpack_ins: &[u8]) -> Result<(), H3Error_QPACK> {
65         self.qpack_decoder.decode_ins(&qpack_ins)
66     }
67 }
68 #[cfg(test)]
69 mod ut_headers_decode {
70     use crate::h3::decoder::FrameDecoder;
71     use crate::h3::qpack::table::DynamicTable;
72     use crate::h3::qpack::QpackDecoder;
73     use crate::test_util::decode;
74     #[test]
literal_field_line_with_name_reference()75     fn literal_field_line_with_name_reference() {
76         println!("run literal_field_line_with_name_reference");
77         let mut table = DynamicTable::with_empty();
78         table.update_size(1024);
79         let mut f_decoder = FrameDecoder::new(16383, &mut table, 0);
80         f_decoder.decode_header(&decode("0000510b2f696e6465782e68746d6c").unwrap());
81         f_decoder.finish_decode_header();
82         let (pseudo, map) = f_decoder.headers.into_parts();
83         assert_eq!(pseudo.path, Some(String::from("/index.html")));
84         println!("passed");
85     }
86 }
87