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