• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 std::convert::TryFrom;
15 
16 use crate::error::HttpError;
17 use crate::h2::{ErrorCode, H2Error, Parts, PseudoHeaders};
18 use crate::headers;
19 
20 /// Mask for the END_STREAM flag.
21 /// When set, indicates that the sender will not send further frames for this
22 /// stream.
23 pub(crate) const END_STREAM_MASK: u8 = 0x01;
24 
25 /// Mask for the RST_STREAM flag.
26 /// When set, indicates that the stream is being terminated.
27 pub(crate) const RST_STREAM_MASK: u8 = 0x03;
28 
29 /// Mask for the END_HEADERS flag.
30 /// When set, indicates that this frame contains an entire header block and not
31 /// a fragment.
32 pub(crate) const END_HEADERS_MASK: u8 = 0x04;
33 
34 /// Mask for the PADDED flag.
35 /// When set, indicates that the frame payload is followed by a padding field.
36 pub(crate) const PADDED_MASK: u8 = 0x08;
37 
38 /// Mask for the HEADERS_PRIORITY flag.
39 /// When set, indicates that the headers frame also contains the priority
40 /// information.
41 pub(crate) const HEADERS_PRIORITY_MASK: u8 = 0x20;
42 
43 /// Mask for the ACK flag
44 pub(crate) const ACK_MASK: u8 = 0x1;
45 
46 /// HTTP/2 frame structure, including the stream ID, flags, and payload
47 /// information. The frame type information is represented by the `Payload`
48 /// type. This structure represents the fundamental unit of communication in
49 /// HTTP/2.
50 #[derive(Clone)]
51 pub struct Frame {
52     id: StreamId,
53     flags: FrameFlags,
54     payload: Payload,
55 }
56 
57 /// Enum representing the type of HTTP/2 frame.
58 /// Each HTTP/2 frame type serves a unique role in the communication process.
59 #[derive(PartialEq, Eq, Debug)]
60 pub enum FrameType {
61     Data = 0x0,
62     Headers = 0x1,
63     Priority = 0x2,
64     RstStream = 0x03,
65     Settings = 0x4,
66     PushPromise = 0x5,
67     Ping = 0x6,
68     Goaway = 0x7,
69     WindowUpdate = 0x8,
70     Continuation = 0x9,
71     // add more frame types as needed
72 }
73 
74 /// Enum representing the payload of an HTTP/2 frame.
75 /// The payload differs based on the type of frame.
76 #[derive(Clone)]
77 pub enum Payload {
78     /// HEADERS frame payload.
79     Headers(Headers),
80     /// DATA frame payload.
81     Data(Data),
82     /// PRIORITY frame payload.
83     Priority(Priority),
84     /// RST_STREAM frame payload.
85     RstStream(RstStream),
86     /// PING frame payload.
87     Ping(Ping),
88     /// SETTINGS frame payload.
89     Settings(Settings),
90     /// GOAWAY frame payload.
91     Goaway(Goaway),
92     /// WINDOW_UPDATE frame payload.
93     WindowUpdate(WindowUpdate),
94     /// PUSH_PROMISE
95     PushPromise(PushPromise),
96 }
97 
98 /// Enum representing the different settings that can be included in a SETTINGS
99 /// frame. Each setting has a different role in the HTTP/2 communication
100 /// process.
101 #[derive(Clone, PartialEq, Eq, Debug)]
102 pub enum Setting {
103     /// SETTINGS_HEADER_TABLE_SIZE
104     HeaderTableSize(u32),
105     /// SETTINGS_ENABLE_PUSH
106     EnablePush(bool),
107     /// SETTINGS_MAX_CONCURRENT_STREAMS
108     MaxConcurrentStreams(u32),
109     /// SETTINGS_INITIAL_WINDOW_SIZE
110     InitialWindowSize(u32),
111     /// SETTINGS_MAX_FRAME_SIZE
112     MaxFrameSize(u32),
113     /// SETTINGS_MAX_HEADER_LIST_SIZE
114     MaxHeaderListSize(u32),
115 }
116 
117 type StreamId = usize;
118 
119 /// HTTP/2 frame flags.
120 #[derive(Clone)]
121 pub struct FrameFlags(u8);
122 
123 /// HTTP/2 HEADERS frame's payload, contains pseudo headers and other headers.
124 #[derive(Clone)]
125 pub struct Headers {
126     parts: Parts,
127 }
128 
129 /// HTTP/2 DATA frame's payload, contains all content after padding is removed.
130 /// The DATA frame defines the payload data of an HTTP/2 request or response.
131 #[derive(Clone)]
132 pub struct Data {
133     data: Vec<u8>,
134 }
135 
136 /// Represents the PRIORITY frame payload.
137 /// The PRIORITY frame specifies the sender-advised priority of a stream.
138 #[derive(Clone)]
139 pub struct Priority {
140     exclusive: bool,
141     stream_dependency: u32,
142     weight: u8,
143 }
144 
145 /// The RST_STREAM frame allows for immediate termination of a stream.
146 /// RST_STREAM is sent to request cancellation of a stream or to indicate an
147 /// error situation.
148 #[derive(Clone)]
149 pub struct RstStream {
150     error_code: u32,
151 }
152 
153 /// Represents the PING frame payload.
154 /// The PING frame is a mechanism for measuring a minimal round-trip time from
155 /// the sender.
156 #[derive(Clone)]
157 pub struct Ping {
158     /// The opaque data of PING
159     pub data: [u8; 8],
160 }
161 
162 /// Represents the SETTINGS frame payload.
163 /// The SETTINGS frame conveys configuration parameters that affect how
164 /// endpoints communicate.
165 #[derive(Clone)]
166 pub struct Settings {
167     settings: Vec<Setting>,
168 }
169 
170 /// Represents the GOAWAY frame payload.
171 /// The GOAWAY frame is used to initiate shutdown of a connection or to signal
172 /// serious error conditions.
173 #[derive(Clone)]
174 pub struct Goaway {
175     error_code: u32,
176     last_stream_id: StreamId,
177     debug_data: Vec<u8>,
178 }
179 
180 /// Represents the WINDOW_UPDATE frame payload.
181 /// The WINDOW_UPDATE frame is used to implement flow control in HTTP/2.
182 #[derive(Clone)]
183 pub struct WindowUpdate {
184     window_size_increment: u32,
185 }
186 
187 /// Represents the PUSH_PROMISE frame payload.
188 /// The PUSH_PROMISE frame is used to notify the peer endpoint in advance of
189 /// streams the sender intends to initiate.
190 #[derive(Clone)]
191 pub struct PushPromise {
192     promised_stream_id: u32,
193     parts: Parts,
194 }
195 
196 /// A Builder of SETTINGS payload.
197 pub struct SettingsBuilder {
198     settings: Vec<Setting>,
199 }
200 
201 impl Frame {
202     /// Returns the stream identifier (`StreamId`) of the frame.
stream_id(&self) -> StreamId203     pub fn stream_id(&self) -> StreamId {
204         self.id
205     }
206 
207     /// Constructs a new `Frame` with the given `StreamId`, `FrameFlags`,
208     /// `Payload`.
new(id: StreamId, flags: FrameFlags, payload: Payload) -> Self209     pub fn new(id: StreamId, flags: FrameFlags, payload: Payload) -> Self {
210         Frame { id, flags, payload }
211     }
212 
213     /// Returns a reference to the frame's flags (`FrameFlags`).
flags(&self) -> &FrameFlags214     pub fn flags(&self) -> &FrameFlags {
215         &self.flags
216     }
217 
218     /// Returns a reference to the frame's payload (`Payload`).
payload(&self) -> &Payload219     pub fn payload(&self) -> &Payload {
220         &self.payload
221     }
222 
223     /// Returns a mutable reference to the frame's payload (`Payload`).
224     /// This can be used to modify the payload of the frame.
payload_mut(&mut self) -> &mut Payload225     pub(crate) fn payload_mut(&mut self) -> &mut Payload {
226         &mut self.payload
227     }
228 }
229 
230 impl FrameFlags {
231     /// Creates a new `FrameFlags` instance with the given `flags` byte.
new(flags: u8) -> Self232     pub fn new(flags: u8) -> Self {
233         FrameFlags(flags)
234     }
235 
236     /// Creates a new `FrameFlags` instance with no flags set.
empty() -> Self237     pub fn empty() -> Self {
238         FrameFlags(0)
239     }
240 
241     /// Judges the END_FLOW Flag is true.
is_end_stream(&self) -> bool242     pub fn is_end_stream(&self) -> bool {
243         self.0 & END_STREAM_MASK == END_STREAM_MASK
244     }
245 
246     /// Judges the END_HEADERS Flag is true.
is_end_headers(&self) -> bool247     pub fn is_end_headers(&self) -> bool {
248         self.0 & END_HEADERS_MASK == END_HEADERS_MASK
249     }
250 
251     /// Judges the PADDED Flag is true.
is_padded(&self) -> bool252     pub fn is_padded(&self) -> bool {
253         self.0 & PADDED_MASK == PADDED_MASK
254     }
255 
256     /// Judge the ACK flag is true.
is_ack(&self) -> bool257     pub fn is_ack(&self) -> bool {
258         self.0 & ACK_MASK == ACK_MASK
259     }
260 
261     /// Get Flags octet.
bits(&self) -> u8262     pub fn bits(&self) -> u8 {
263         self.0
264     }
265 
266     /// Sets the END_STREAM flag.
set_end_stream(&mut self, end_stream: bool)267     pub fn set_end_stream(&mut self, end_stream: bool) {
268         if end_stream {
269             self.0 |= END_STREAM_MASK;
270         } else {
271             self.0 &= !END_STREAM_MASK;
272         }
273     }
274 
275     /// Sets the END_HEADERS flag.
set_end_headers(&mut self, end_headers: bool)276     pub fn set_end_headers(&mut self, end_headers: bool) {
277         if end_headers {
278             self.0 |= END_HEADERS_MASK;
279         } else {
280             self.0 &= !END_HEADERS_MASK;
281         }
282     }
283 
284     /// Sets the PADDED flag.
set_padded(&mut self, padded: bool)285     pub fn set_padded(&mut self, padded: bool) {
286         if padded {
287             self.0 |= PADDED_MASK;
288         } else {
289             self.0 &= !PADDED_MASK;
290         }
291     }
292 }
293 
294 impl Payload {
295     /// Returns a reference to the Headers if the Payload is of the Headers
296     /// variant. If the Payload is not of the Headers variant, returns None.
as_headers(&self) -> Option<&Headers>297     pub(crate) fn as_headers(&self) -> Option<&Headers> {
298         if let Payload::Headers(headers) = self {
299             Some(headers)
300         } else {
301             None
302         }
303     }
304 
305     /// Returns the type of the frame (`FrameType`) that this payload would be
306     /// associated with. The returned `FrameType` is determined based on the
307     /// variant of the Payload.
frame_type(&self) -> FrameType308     pub fn frame_type(&self) -> FrameType {
309         match self {
310             Payload::Headers(_) => FrameType::Headers,
311             Payload::Data(_) => FrameType::Data,
312             Payload::Priority(_) => FrameType::Priority,
313             Payload::Ping(_) => FrameType::Ping,
314             Payload::RstStream(_) => FrameType::RstStream,
315             Payload::Settings(_) => FrameType::Settings,
316             Payload::Goaway(_) => FrameType::Goaway,
317             Payload::WindowUpdate(_) => FrameType::WindowUpdate,
318             Payload::PushPromise(_) => FrameType::PushPromise,
319         }
320     }
321 }
322 
323 impl Headers {
324     /// Creates a new Headers instance from the provided Parts.
new(parts: Parts) -> Self325     pub fn new(parts: Parts) -> Self {
326         Headers { parts }
327     }
328 
329     /// Returns pseudo headers and other headers as tuples.
parts(&self) -> (&PseudoHeaders, &headers::Headers)330     pub fn parts(&self) -> (&PseudoHeaders, &headers::Headers) {
331         self.parts.parts()
332     }
333 
334     /// Returns a copy of the internal parts of the Headers.
get_parts(&self) -> Parts335     pub(crate) fn get_parts(&self) -> Parts {
336         self.parts.clone()
337     }
338 }
339 
340 impl Data {
341     /// Creates a new Data instance containing the provided data.
new(data: Vec<u8>) -> Self342     pub fn new(data: Vec<u8>) -> Self {
343         Data { data }
344     }
345 
346     /// Return the `Vec` that contains the data payload.
data(&self) -> &Vec<u8>347     pub fn data(&self) -> &Vec<u8> {
348         &self.data
349     }
350 }
351 
352 impl Settings {
353     /// Creates a new Settings instance containing the provided settings.
new(settings: Vec<Setting>) -> Self354     pub fn new(settings: Vec<Setting>) -> Self {
355         Settings { settings }
356     }
357 
358     /// Returns a slice of the settings.
get_settings(&self) -> &[Setting]359     pub fn get_settings(&self) -> &[Setting] {
360         &self.settings
361     }
362 
363     /// Adds or updates a setting.
update_setting(&mut self, setting: Setting)364     pub(crate) fn update_setting(&mut self, setting: Setting) {
365         let setting_id = setting.setting_identifier();
366         if let Some(existing_setting) = self
367             .settings
368             .iter_mut()
369             .find(|s| s.setting_identifier() == setting_id)
370         {
371             *existing_setting = setting;
372         } else {
373             self.settings.push(setting);
374         }
375     }
376 
377     /// Returns the total length of the settings when encoded.
encoded_len(&self) -> usize378     pub fn encoded_len(&self) -> usize {
379         let settings_count = self.settings.len();
380         // Each setting has a 2-byte ID and a 4-byte value
381         let setting_size = 6;
382         settings_count * setting_size
383     }
384 }
385 
386 impl Setting {
387     /// Returns the identifier associated with the setting.
setting_identifier(&self) -> u16388     pub fn setting_identifier(&self) -> u16 {
389         match self {
390             Setting::HeaderTableSize(_) => 0x01,
391             Setting::EnablePush(_) => 0x02,
392             Setting::MaxConcurrentStreams(_) => 0x03,
393             Setting::InitialWindowSize(_) => 0x04,
394             Setting::MaxFrameSize(_) => 0x05,
395             Setting::MaxHeaderListSize(_) => 0x06,
396         }
397     }
398 }
399 
400 impl SettingsBuilder {
401     /// `SettingsBuilder` constructor.
new() -> Self402     pub fn new() -> Self {
403         SettingsBuilder { settings: vec![] }
404     }
405 
406     /// SETTINGS_HEADER_TABLE_SIZE (0x01) setting.
header_table_size(mut self, size: u32) -> Self407     pub fn header_table_size(mut self, size: u32) -> Self {
408         self.settings.push(Setting::HeaderTableSize(size));
409         self
410     }
411 
412     /// SETTINGS_ENABLE_PUSH (0x02) setting.
enable_push(mut self, is_enable: bool) -> Self413     pub fn enable_push(mut self, is_enable: bool) -> Self {
414         self.settings.push(Setting::EnablePush(is_enable));
415         self
416     }
417 
418     /// SETTINGS_MAX_FRAME_SIZE (0x05) setting.
max_frame_size(mut self, size: u32) -> Self419     pub fn max_frame_size(mut self, size: u32) -> Self {
420         self.settings.push(Setting::MaxFrameSize(size));
421         self
422     }
423 
424     /// SETTINGS_MAX_HEADER_LIST_SIZE (0x06) setting.
max_header_list_size(mut self, size: u32) -> Self425     pub fn max_header_list_size(mut self, size: u32) -> Self {
426         self.settings.push(Setting::MaxHeaderListSize(size));
427         self
428     }
429 
430     /// Consumes the Builder and constructs a SETTINGS payload.
431     ///
432     /// # Examples
433     ///
434     /// ```
435     /// use ylong_http::h2::SettingsBuilder;
436     ///
437     /// let settings = SettingsBuilder::new()
438     ///     .enable_push(true)
439     ///     .header_table_size(4096)
440     ///     .max_frame_size(2 << 13)
441     ///     .build();
442     /// ```
build(self) -> Settings443     pub fn build(self) -> Settings {
444         Settings::new(self.settings)
445     }
446 }
447 
448 impl Default for SettingsBuilder {
default() -> Self449     fn default() -> Self {
450         Self::new()
451     }
452 }
453 
454 impl Goaway {
455     /// Creates a new Goaway instance with the provided error code, last stream
456     /// ID, and debug data.
new(error_code: u32, last_stream_id: StreamId, debug_data: Vec<u8>) -> Self457     pub fn new(error_code: u32, last_stream_id: StreamId, debug_data: Vec<u8>) -> Self {
458         Goaway {
459             error_code,
460             last_stream_id,
461             debug_data,
462         }
463     }
464 
465     /// Returns a slice of the debug data.
get_debug_data(&self) -> &[u8]466     pub fn get_debug_data(&self) -> &[u8] {
467         &self.debug_data
468     }
469 
470     /// Returns the identifier of the last stream processed by the sender.
get_last_stream_id(&self) -> StreamId471     pub fn get_last_stream_id(&self) -> StreamId {
472         self.last_stream_id
473     }
474 
475     /// Returns the error code.
get_error_code(&self) -> u32476     pub fn get_error_code(&self) -> u32 {
477         self.error_code
478     }
479 
480     /// Returns the total length of the Goaway frame when encoded.
encoded_len(&self) -> usize481     pub fn encoded_len(&self) -> usize {
482         8 + self.debug_data.len() // 4-byte Last-Stream-ID + 4-byte Error Code +
483                                   // Debug Data length
484     }
485 }
486 
487 impl WindowUpdate {
488     /// Creates a new WindowUpdate instance with the provided window size
489     /// increment.
new(window_size_increment: u32) -> Self490     pub fn new(window_size_increment: u32) -> Self {
491         WindowUpdate {
492             window_size_increment,
493         }
494     }
495 
496     /// Returns the window size increment.
get_increment(&self) -> u32497     pub(crate) fn get_increment(&self) -> u32 {
498         self.window_size_increment
499     }
500 
501     /// Returns the length of the WindowUpdate frame when encoded.
encoded_len(&self) -> usize502     pub fn encoded_len(&self) -> usize {
503         4 // 4-byte window size increment
504     }
505 }
506 
507 impl Priority {
508     /// Creates a new Priority instance with the provided exclusive flag, stream
509     /// dependency, and weight.
new(exclusive: bool, stream_dependency: u32, weight: u8) -> Self510     pub fn new(exclusive: bool, stream_dependency: u32, weight: u8) -> Self {
511         Priority {
512             exclusive,
513             stream_dependency,
514             weight,
515         }
516     }
517 
518     /// Returns whether the stream is exclusive.
get_exclusive(&self) -> bool519     pub fn get_exclusive(&self) -> bool {
520         self.exclusive
521     }
522 
523     /// Returns the stream dependency.
get_stream_dependency(&self) -> u32524     pub fn get_stream_dependency(&self) -> u32 {
525         self.stream_dependency
526     }
527 
528     /// Returns the weight of the stream.
get_weight(&self) -> u8529     pub fn get_weight(&self) -> u8 {
530         self.weight
531     }
532 }
533 
534 impl RstStream {
535     /// Creates a new RstStream instance with the provided error code.
new(error_code: u32) -> Self536     pub fn new(error_code: u32) -> Self {
537         Self { error_code }
538     }
539 
540     /// Returns the error code associated with the RstStream.
error_code(&self) -> u32541     pub fn error_code(&self) -> u32 {
542         self.error_code
543     }
544 
545     /// GET the `ErrorCode` of `RstStream`
error(&self, id: u32) -> Result<H2Error, HttpError>546     pub fn error(&self, id: u32) -> Result<H2Error, HttpError> {
547         Ok(H2Error::StreamError(
548             id,
549             ErrorCode::try_from(self.error_code)?,
550         ))
551     }
552 }
553 
554 impl Ping {
555     /// Creates a new Ping instance with the provided data.
new(data: [u8; 8]) -> Self556     pub fn new(data: [u8; 8]) -> Self {
557         Ping { data }
558     }
559 
560     /// Returns the data associated with the Ping.
data(&self) -> [u8; 8]561     pub fn data(&self) -> [u8; 8] {
562         self.data
563     }
564 }
565 
566 impl PushPromise {
567     /// `PushPromise` constructor.
new(promised_stream_id: u32, parts: Parts) -> Self568     pub fn new(promised_stream_id: u32, parts: Parts) -> Self {
569         Self {
570             promised_stream_id,
571             parts,
572         }
573     }
574 }
575 
576 #[cfg(test)]
577 mod ut_frame {
578     use super::*;
579     use crate::h2::Parts;
580 
581     /// UT test cases for `SettingsBuilder`.
582     ///
583     /// # Brief
584     /// 1. Creates a `SettingsBuilder`.
585     /// 2. Sets various setting parameters using builder methods.
586     /// 3. Builds a `Settings` object.
587     /// 4. Gets a reference to the underlying `Vec<Setting>` from the `Settings`
588     ///    object.
589     /// 5. Iterates over each setting in the `Vec<Setting>` and checks whether
590     ///    it matches the expected value.
591     #[test]
ut_settings_builder()592     fn ut_settings_builder() {
593         let settings = SettingsBuilder::new()
594             .header_table_size(4096)
595             .enable_push(true)
596             .max_frame_size(16384)
597             .max_header_list_size(8192)
598             .build();
599 
600         let mut setting_iter = settings.get_settings().iter();
601         // Check that the first setting is as expected
602         assert_eq!(setting_iter.next(), Some(&Setting::HeaderTableSize(4096)));
603         // Check that the second setting is as expected
604         assert_eq!(setting_iter.next(), Some(&Setting::EnablePush(true)));
605         // Check that the third setting is as expected
606         assert_eq!(setting_iter.next(), Some(&Setting::MaxFrameSize(16384)));
607         // Check that the fourth setting is as expected
608         assert_eq!(setting_iter.next(), Some(&Setting::MaxHeaderListSize(8192)));
609         // Check that there are no more settings
610         assert_eq!(setting_iter.next(), None);
611     }
612 
613     /// UT test cases for `Ping`.
614     ///
615     /// # Brief
616     /// 1. Creates a `Ping` instance with specific data.
617     /// 2. Checks if the data of the `Ping` instance is correct.
618     #[test]
ut_ping()619     fn ut_ping() {
620         let data = [1, 2, 3, 4, 5, 6, 7, 8];
621         let ping = Ping::new(data);
622         assert_eq!(ping.data(), data);
623     }
624 
625     /// UT test cases for `Setting`.
626     ///
627     /// # Brief
628     /// 1. Creates a `Setting` instance for each possible variant with a
629     ///    specific value.
630     /// 2. Checks if the identifier of the `Setting` instance is correct.
631     #[test]
ut_setting()632     fn ut_setting() {
633         let setting_header_table_size = Setting::HeaderTableSize(4096);
634         assert_eq!(setting_header_table_size.setting_identifier(), 0x01);
635 
636         let setting_enable_push = Setting::EnablePush(true);
637         assert_eq!(setting_enable_push.setting_identifier(), 0x02);
638 
639         let setting_max_concurrent_streams = Setting::MaxConcurrentStreams(100);
640         assert_eq!(setting_max_concurrent_streams.setting_identifier(), 0x03);
641 
642         let setting_initial_window_size = Setting::InitialWindowSize(5000);
643         assert_eq!(setting_initial_window_size.setting_identifier(), 0x04);
644 
645         let setting_max_frame_size = Setting::MaxFrameSize(16384);
646         assert_eq!(setting_max_frame_size.setting_identifier(), 0x05);
647 
648         let setting_max_header_list_size = Setting::MaxHeaderListSize(8192);
649         assert_eq!(setting_max_header_list_size.setting_identifier(), 0x06);
650     }
651 
652     /// UT test cases for `Settings`.
653     ///
654     /// # Brief
655     /// 1. Creates a `Settings` instance with a list of settings.
656     /// 2. Checks if the list of settings in the `Settings` instance is correct.
657     /// 3. Checks if the encoded length of the settings is correct.
658     #[test]
ut_settings()659     fn ut_settings() {
660         let settings_list = vec![
661             Setting::HeaderTableSize(4096),
662             Setting::EnablePush(true),
663             Setting::MaxFrameSize(16384),
664             Setting::MaxHeaderListSize(8192),
665         ];
666         let settings = Settings::new(settings_list.clone());
667         assert_eq!(settings.get_settings(), settings_list.as_slice());
668 
669         let encoded_len = settings.encoded_len();
670         assert_eq!(encoded_len, settings_list.len() * 6);
671     }
672 
673     /// UT test cases for `Payload`.
674     ///
675     /// # Brief
676     /// 1. Creates an instance of `Payload` for each possible variant.
677     /// 2. Checks if the `frame_type` of the `Payload` instance is correct.
678     /// 3. Checks if `as_headers` method returns Some or None correctly.
679     #[test]
ut_payload()680     fn ut_payload() {
681         let payload_headers = Payload::Headers(Headers::new(Parts::new()));
682         assert_eq!(payload_headers.frame_type(), FrameType::Headers);
683         assert!(payload_headers.as_headers().is_some());
684 
685         let payload_data = Payload::Data(Data::new(b"hh".to_vec()));
686         assert_eq!(payload_data.frame_type(), FrameType::Data);
687         assert!(payload_data.as_headers().is_none());
688 
689         let payload_priority = Payload::Priority(Priority::new(true, 1, 10));
690         assert_eq!(payload_priority.frame_type(), FrameType::Priority);
691         assert!(payload_priority.as_headers().is_none());
692 
693         let payload_rst_stream = Payload::RstStream(RstStream::new(20));
694         assert_eq!(payload_rst_stream.frame_type(), FrameType::RstStream);
695         assert!(payload_rst_stream.as_headers().is_none());
696 
697         let payload_ping = Payload::Ping(Ping::new([0; 8]));
698         assert_eq!(payload_ping.frame_type(), FrameType::Ping);
699         assert!(payload_ping.as_headers().is_none());
700 
701         let payload_goaway = Payload::Goaway(Goaway::new(30, 20, vec![0; 0]));
702         assert_eq!(payload_goaway.frame_type(), FrameType::Goaway);
703         assert!(payload_goaway.as_headers().is_none());
704 
705         let payload_window_update = Payload::WindowUpdate(WindowUpdate::new(1024));
706         assert_eq!(payload_window_update.frame_type(), FrameType::WindowUpdate);
707         assert!(payload_window_update.as_headers().is_none());
708 
709         let payload_push_promise = Payload::PushPromise(PushPromise::new(3, Parts::new()));
710         assert_eq!(payload_push_promise.frame_type(), FrameType::PushPromise);
711         assert!(payload_push_promise.as_headers().is_none());
712     }
713 }
714