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