1use bytes::{Buf, BufMut, Bytes, BytesMut};
7
8pub const FRAME_HEADER_SIZE: usize = 9;
10
11pub const DEFAULT_MAX_FRAME_SIZE: u32 = 16384;
13
14pub const CONNECTION_PREFACE: &[u8] = b"PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n";
16
17#[derive(Debug, Clone, Copy, PartialEq, Eq)]
19#[repr(u8)]
20pub enum FrameType {
21 Data = 0x0,
22 Headers = 0x1,
23 Priority = 0x2,
24 RstStream = 0x3,
25 Settings = 0x4,
26 PushPromise = 0x5,
27 Ping = 0x6,
28 GoAway = 0x7,
29 WindowUpdate = 0x8,
30 Continuation = 0x9,
31 Unknown(u8),
32}
33
34impl From<u8> for FrameType {
35 fn from(v: u8) -> Self {
36 match v {
37 0x0 => Self::Data,
38 0x1 => Self::Headers,
39 0x2 => Self::Priority,
40 0x3 => Self::RstStream,
41 0x4 => Self::Settings,
42 0x5 => Self::PushPromise,
43 0x6 => Self::Ping,
44 0x7 => Self::GoAway,
45 0x8 => Self::WindowUpdate,
46 0x9 => Self::Continuation,
47 other => Self::Unknown(other),
48 }
49 }
50}
51
52impl From<FrameType> for u8 {
53 fn from(ft: FrameType) -> u8 {
54 match ft {
55 FrameType::Data => 0x0,
56 FrameType::Headers => 0x1,
57 FrameType::Priority => 0x2,
58 FrameType::RstStream => 0x3,
59 FrameType::Settings => 0x4,
60 FrameType::PushPromise => 0x5,
61 FrameType::Ping => 0x6,
62 FrameType::GoAway => 0x7,
63 FrameType::WindowUpdate => 0x8,
64 FrameType::Continuation => 0x9,
65 FrameType::Unknown(v) => v,
66 }
67 }
68}
69
70pub mod flags {
72 pub const END_STREAM: u8 = 0x1;
73 pub const ACK: u8 = 0x1; pub const END_HEADERS: u8 = 0x4;
75 pub const PADDED: u8 = 0x8;
76 pub const PRIORITY: u8 = 0x20;
77}
78
79#[derive(Debug, Clone, Copy, PartialEq, Eq)]
81#[repr(u16)]
82pub enum SettingsId {
83 HeaderTableSize = 0x1,
84 EnablePush = 0x2,
85 MaxConcurrentStreams = 0x3,
86 InitialWindowSize = 0x4,
87 MaxFrameSize = 0x5,
88 MaxHeaderListSize = 0x6,
89 EnableConnectProtocol = 0x8,
90}
91
92impl TryFrom<u16> for SettingsId {
93 type Error = ();
94
95 fn try_from(v: u16) -> Result<Self, Self::Error> {
96 match v {
97 0x1 => Ok(Self::HeaderTableSize),
98 0x2 => Ok(Self::EnablePush),
99 0x3 => Ok(Self::MaxConcurrentStreams),
100 0x4 => Ok(Self::InitialWindowSize),
101 0x5 => Ok(Self::MaxFrameSize),
102 0x6 => Ok(Self::MaxHeaderListSize),
103 0x8 => Ok(Self::EnableConnectProtocol),
104 _ => Err(()),
105 }
106 }
107}
108
109impl From<SettingsId> for u16 {
110 fn from(id: SettingsId) -> Self {
111 id as u16
112 }
113}
114
115#[derive(Debug, Clone, Copy, PartialEq, Eq)]
117#[repr(u32)]
118pub enum ErrorCode {
119 NoError = 0x0,
120 ProtocolError = 0x1,
121 InternalError = 0x2,
122 FlowControlError = 0x3,
123 SettingsTimeout = 0x4,
124 StreamClosed = 0x5,
125 FrameSizeError = 0x6,
126 RefusedStream = 0x7,
127 Cancel = 0x8,
128 CompressionError = 0x9,
129 ConnectError = 0xa,
130 EnhanceYourCalm = 0xb,
131 InadequateSecurity = 0xc,
132 Http11Required = 0xd,
133}
134
135#[derive(Debug, Clone)]
137pub struct FrameHeader {
138 pub length: u32,
139 pub frame_type: FrameType,
140 pub flags: u8,
141 pub stream_id: u32,
142}
143
144impl FrameHeader {
145 pub fn parse(buf: &[u8]) -> Option<Self> {
148 if buf.len() < FRAME_HEADER_SIZE {
149 return None;
150 }
151
152 let length = ((buf[0] as u32) << 16) | ((buf[1] as u32) << 8) | (buf[2] as u32);
153 let frame_type = FrameType::from(buf[3]);
154 let flags = buf[4];
155
156 if (buf[5] & 0x80) != 0 {
159 return None; }
161
162 let stream_id = ((buf[5] as u32 & 0x7f) << 24)
163 | ((buf[6] as u32) << 16)
164 | ((buf[7] as u32) << 8)
165 | (buf[8] as u32);
166
167 Some(Self {
168 length,
169 frame_type,
170 flags,
171 stream_id,
172 })
173 }
174
175 pub fn serialize(&self, buf: &mut BytesMut) {
177 buf.put_u8((self.length >> 16) as u8);
179 buf.put_u8((self.length >> 8) as u8);
180 buf.put_u8(self.length as u8);
181 buf.put_u8(self.frame_type.into());
183 buf.put_u8(self.flags);
185 buf.put_u32(self.stream_id & 0x7fffffff);
188 }
189}
190
191#[derive(Debug, Clone)]
193pub struct SettingsFrame {
194 pub settings: Vec<(u16, u32)>,
198 pub ack: bool,
199}
200
201impl SettingsFrame {
202 pub fn new() -> Self {
204 Self {
205 settings: Vec::new(),
206 ack: false,
207 }
208 }
209
210 pub fn ack() -> Self {
212 Self {
213 settings: Vec::new(),
214 ack: true,
215 }
216 }
217
218 pub fn set<T: Into<u16>>(&mut self, id: T, value: u32) -> &mut Self {
220 self.settings.push((id.into(), value));
221 self
222 }
223
224 pub fn serialize(&self) -> BytesMut {
226 let payload_len = if self.ack { 0 } else { self.settings.len() * 6 };
227 let mut buf = BytesMut::with_capacity(FRAME_HEADER_SIZE + payload_len);
228
229 let header = FrameHeader {
231 length: payload_len as u32,
232 frame_type: FrameType::Settings,
233 flags: if self.ack { flags::ACK } else { 0 },
234 stream_id: 0, };
236 header.serialize(&mut buf);
237
238 if !self.ack {
240 for (id, value) in &self.settings {
241 buf.put_u16(*id);
242 buf.put_u32(*value);
243 }
244 }
245
246 buf
247 }
248
249 pub fn parse(flags: u8, mut payload: Bytes) -> Self {
251 let ack = (flags & flags::ACK) != 0;
252 let mut settings = Vec::new();
253
254 while payload.remaining() >= 6 {
255 let id = payload.get_u16();
256 let value = payload.get_u32();
257 settings.push((id, value));
258 }
259
260 Self { settings, ack }
261 }
262}
263
264impl Default for SettingsFrame {
265 fn default() -> Self {
266 Self::new()
267 }
268}
269
270#[derive(Debug, Clone)]
272pub struct WindowUpdateFrame {
273 pub stream_id: u32,
274 pub increment: u32,
275}
276
277impl WindowUpdateFrame {
278 pub fn new(stream_id: u32, increment: u32) -> Self {
280 Self {
281 stream_id,
282 increment,
283 }
284 }
285
286 pub fn serialize(&self) -> BytesMut {
288 let mut buf = BytesMut::with_capacity(FRAME_HEADER_SIZE + 4);
289
290 let header = FrameHeader {
291 length: 4,
292 frame_type: FrameType::WindowUpdate,
293 flags: 0,
294 stream_id: self.stream_id,
295 };
296 header.serialize(&mut buf);
297
298 buf.put_u32(self.increment & 0x7fffffff);
300
301 buf
302 }
303
304 pub fn parse(stream_id: u32, mut payload: Bytes) -> Option<Self> {
307 if payload.remaining() < 4 {
308 return None;
309 }
310 let increment_raw = payload.get_u32();
311 let increment = increment_raw & 0x7fffffff;
312
313 if increment == 0 {
316 return None;
317 }
318
319 Some(Self {
320 stream_id,
321 increment,
322 })
323 }
324}
325
326#[derive(Debug, Clone)]
328pub struct HeadersFrame {
329 pub stream_id: u32,
330 pub header_block: Bytes,
331 pub end_stream: bool,
332 pub end_headers: bool,
333 pub priority: Option<PriorityData>,
334}
335
336#[derive(Debug, Clone, Copy)]
338pub struct PriorityData {
339 pub exclusive: bool,
340 pub stream_dependency: u32,
341 pub weight: u8,
342}
343
344impl HeadersFrame {
345 pub fn new(stream_id: u32, header_block: Bytes) -> Self {
347 Self {
348 stream_id,
349 header_block,
350 end_stream: false,
351 end_headers: true,
352 priority: None,
353 }
354 }
355
356 pub fn end_stream(mut self, end: bool) -> Self {
358 self.end_stream = end;
359 self
360 }
361
362 pub fn with_priority(mut self, priority: PriorityData) -> Self {
364 self.priority = Some(priority);
365 self
366 }
367
368 pub fn end_headers(mut self, end: bool) -> Self {
370 self.end_headers = end;
371 self
372 }
373
374 pub fn serialize(&self) -> BytesMut {
378 let priority_len = if self.priority.is_some() { 5 } else { 0 };
379 let payload_len = priority_len + self.header_block.len();
380 let mut buf = BytesMut::with_capacity(FRAME_HEADER_SIZE + payload_len);
381
382 let mut frame_flags = 0u8;
383 if self.end_stream {
384 frame_flags |= flags::END_STREAM;
385 }
386 if self.end_headers {
387 frame_flags |= flags::END_HEADERS;
388 }
389 if self.priority.is_some() {
390 frame_flags |= flags::PRIORITY;
391 }
392
393 let header = FrameHeader {
394 length: payload_len as u32,
395 frame_type: FrameType::Headers,
396 flags: frame_flags,
397 stream_id: self.stream_id,
398 };
399 header.serialize(&mut buf);
400
401 if let Some(priority) = &self.priority {
403 let dep = if priority.exclusive {
404 priority.stream_dependency | 0x80000000
405 } else {
406 priority.stream_dependency
407 };
408 buf.put_u32(dep);
409 buf.put_u8(priority.weight);
410 }
411
412 buf.extend_from_slice(&self.header_block);
414
415 buf
416 }
417
418 pub fn parse(stream_id: u32, flags: u8, mut payload: Bytes) -> Result<Self, String> {
421 if stream_id == 0 {
422 return Err("HEADERS frame must have non-zero stream ID".to_string());
423 }
424
425 let end_stream = (flags & flags::END_STREAM) != 0;
426 let end_headers = (flags & flags::END_HEADERS) != 0;
427 let padded = (flags & flags::PADDED) != 0;
428 let priority_flag = (flags & flags::PRIORITY) != 0;
429
430 let pad_len = if padded {
432 if payload.remaining() < 1 {
433 return Err("PADDED HEADERS frame missing padding length".to_string());
434 }
435 let pad_len = payload.get_u8() as usize;
436 if pad_len >= payload.remaining() {
437 return Err("Padding length exceeds payload size".to_string());
438 }
439 pad_len
440 } else {
441 0
442 };
443
444 let priority = if priority_flag {
446 if payload.remaining() < 5 {
447 return Err("HEADERS frame with PRIORITY flag missing priority data".to_string());
448 }
449 let dep_raw = payload.get_u32();
450 let exclusive = (dep_raw & 0x80000000) != 0;
451 let stream_dependency = dep_raw & 0x7fffffff;
452 let weight = payload.get_u8();
453 Some(PriorityData {
454 exclusive,
455 stream_dependency,
456 weight,
457 })
458 } else {
459 None
460 };
461
462 let header_block_len = payload.remaining() - pad_len;
464 if header_block_len == 0 {
465 return Err("HEADERS frame header block is empty".to_string());
466 }
467 let header_block = payload.copy_to_bytes(header_block_len);
468 payload.advance(pad_len);
470
471 Ok(Self {
472 stream_id,
473 header_block,
474 end_stream,
475 end_headers,
476 priority,
477 })
478 }
479}
480
481#[derive(Debug, Clone)]
483pub struct ContinuationFrame {
484 pub stream_id: u32,
485 pub flags: u8,
486 pub header_fragment: Bytes,
487}
488
489impl ContinuationFrame {
490 pub fn new(stream_id: u32, header_fragment: Bytes, end_headers: bool) -> Self {
492 let flags = if end_headers { flags::END_HEADERS } else { 0 };
493 Self {
494 stream_id,
495 flags,
496 header_fragment,
497 }
498 }
499
500 pub fn end_headers(&self) -> bool {
502 self.flags & flags::END_HEADERS != 0
503 }
504
505 pub fn serialize(&self) -> BytesMut {
507 let payload_len = self.header_fragment.len();
508 let mut buf = BytesMut::with_capacity(FRAME_HEADER_SIZE + payload_len);
509
510 let header = FrameHeader {
511 length: payload_len as u32,
512 frame_type: FrameType::Continuation,
513 flags: self.flags,
514 stream_id: self.stream_id,
515 };
516 header.serialize(&mut buf);
517
518 buf.extend_from_slice(&self.header_fragment);
520
521 buf
522 }
523
524 pub fn parse(stream_id: u32, flags: u8, payload: Bytes) -> Result<Self, String> {
526 if stream_id == 0 {
527 return Err("CONTINUATION frame must have non-zero stream ID".to_string());
528 }
529
530 Ok(Self {
531 stream_id,
532 flags,
533 header_fragment: payload,
534 })
535 }
536}
537
538#[derive(Debug, Clone)]
540pub struct DataFrame {
541 pub stream_id: u32,
542 pub data: Bytes,
543 pub end_stream: bool,
544 pub padding_len: u8,
545}
546
547impl DataFrame {
548 pub fn new(stream_id: u32, data: Bytes) -> Self {
550 Self {
551 stream_id,
552 data,
553 end_stream: false,
554 padding_len: 0,
555 }
556 }
557
558 pub fn end_stream(mut self, end: bool) -> Self {
560 self.end_stream = end;
561 self
562 }
563
564 pub fn with_padding(mut self, padding_len: u8) -> Self {
566 self.padding_len = padding_len;
567 self
568 }
569
570 pub fn serialize(&self) -> BytesMut {
572 let payload_len = if self.padding_len > 0 {
573 1 + self.data.len() + self.padding_len as usize
575 } else {
576 self.data.len()
577 };
578
579 let mut buf = BytesMut::with_capacity(FRAME_HEADER_SIZE + payload_len);
580
581 let mut frame_flags = if self.end_stream {
582 flags::END_STREAM
583 } else {
584 0
585 };
586 if self.padding_len > 0 {
587 frame_flags |= flags::PADDED;
588 }
589
590 let header = FrameHeader {
591 length: payload_len as u32,
592 frame_type: FrameType::Data,
593 flags: frame_flags,
594 stream_id: self.stream_id,
595 };
596 header.serialize(&mut buf);
597
598 if self.padding_len > 0 {
600 buf.put_u8(self.padding_len);
601 }
602
603 buf.extend_from_slice(&self.data);
605
606 if self.padding_len > 0 {
608 buf.extend_from_slice(&vec![0u8; self.padding_len as usize]);
609 }
610
611 buf
612 }
613
614 pub fn parse(stream_id: u32, flags: u8, mut payload: Bytes) -> Result<Self, String> {
617 if stream_id == 0 {
618 return Err("DATA frame must have non-zero stream ID".to_string());
619 }
620
621 let end_stream = (flags & flags::END_STREAM) != 0;
622 let padded = (flags & flags::PADDED) != 0;
623
624 let (data, padding_len) = if padded {
625 if payload.remaining() < 1 {
626 return Err("PADDED DATA frame missing padding length".to_string());
627 }
628 let pad_len = payload.get_u8() as usize;
629 if pad_len >= payload.remaining() {
630 return Err("Padding length exceeds payload size".to_string());
631 }
632 let data_len = payload.remaining() - pad_len;
633 let data = payload.copy_to_bytes(data_len);
634 payload.advance(pad_len);
636 (data, pad_len as u8)
637 } else {
638 (payload, 0)
639 };
640
641 Ok(Self {
642 stream_id,
643 data,
644 end_stream,
645 padding_len,
646 })
647 }
648}
649
650#[derive(Debug, Clone)]
652pub struct PingFrame {
653 pub ack: bool,
654 pub data: [u8; 8],
655}
656
657impl PingFrame {
658 pub fn new(data: [u8; 8]) -> Self {
660 Self { ack: false, data }
661 }
662
663 pub fn ack(data: [u8; 8]) -> Self {
665 Self { ack: true, data }
666 }
667
668 pub fn serialize(&self) -> BytesMut {
670 let mut buf = BytesMut::with_capacity(FRAME_HEADER_SIZE + 8);
671
672 let header = FrameHeader {
673 length: 8,
674 frame_type: FrameType::Ping,
675 flags: if self.ack { flags::ACK } else { 0 },
676 stream_id: 0,
677 };
678 header.serialize(&mut buf);
679 buf.extend_from_slice(&self.data);
680
681 buf
682 }
683
684 pub fn parse(flags: u8, payload: &[u8]) -> Option<Self> {
686 if payload.len() != 8 {
687 return None;
688 }
689 let mut data = [0u8; 8];
690 data.copy_from_slice(payload);
691 Some(Self {
692 ack: (flags & flags::ACK) != 0,
693 data,
694 })
695 }
696}
697
698#[derive(Debug, Clone)]
700pub struct GoAwayFrame {
701 pub last_stream_id: u32,
702 pub error_code: ErrorCode,
703 pub debug_data: Bytes,
704}
705
706impl GoAwayFrame {
707 pub fn new(last_stream_id: u32, error_code: ErrorCode) -> Self {
709 Self {
710 last_stream_id,
711 error_code,
712 debug_data: Bytes::new(),
713 }
714 }
715
716 pub fn serialize(&self) -> BytesMut {
718 let payload_len = 8 + self.debug_data.len();
719 let mut buf = BytesMut::with_capacity(FRAME_HEADER_SIZE + payload_len);
720
721 let header = FrameHeader {
722 length: payload_len as u32,
723 frame_type: FrameType::GoAway,
724 flags: 0,
725 stream_id: 0,
726 };
727 header.serialize(&mut buf);
728 buf.put_u32(self.last_stream_id & 0x7fffffff);
729 buf.put_u32(self.error_code as u32);
730 buf.extend_from_slice(&self.debug_data);
731
732 buf
733 }
734
735 pub fn parse(mut payload: Bytes) -> Option<Self> {
737 if payload.remaining() < 8 {
738 return None;
739 }
740 let last_stream_id = payload.get_u32() & 0x7fffffff;
741 let error_code_raw = payload.get_u32();
742 let error_code = match error_code_raw {
743 0x0 => ErrorCode::NoError,
744 0x1 => ErrorCode::ProtocolError,
745 0x2 => ErrorCode::InternalError,
746 0x3 => ErrorCode::FlowControlError,
747 0x4 => ErrorCode::SettingsTimeout,
748 0x5 => ErrorCode::StreamClosed,
749 0x6 => ErrorCode::FrameSizeError,
750 0x7 => ErrorCode::RefusedStream,
751 0x8 => ErrorCode::Cancel,
752 0x9 => ErrorCode::CompressionError,
753 0xa => ErrorCode::ConnectError,
754 0xb => ErrorCode::EnhanceYourCalm,
755 0xc => ErrorCode::InadequateSecurity,
756 0xd => ErrorCode::Http11Required,
757 _ => ErrorCode::ProtocolError,
758 };
759 let debug_data = payload.copy_to_bytes(payload.remaining());
760
761 Some(Self {
762 last_stream_id,
763 error_code,
764 debug_data,
765 })
766 }
767}
768
769#[derive(Debug, Clone)]
771pub struct PriorityFrame {
772 pub stream_id: u32,
773 pub exclusive: bool,
774 pub stream_dependency: u32,
775 pub weight: u8,
776}
777
778impl PriorityFrame {
779 pub fn new(stream_id: u32, stream_dependency: u32, weight: u8, exclusive: bool) -> Self {
781 Self {
782 stream_id,
783 exclusive,
784 stream_dependency,
785 weight,
786 }
787 }
788
789 pub fn serialize(&self) -> BytesMut {
791 let mut buf = BytesMut::with_capacity(FRAME_HEADER_SIZE + 5);
792
793 let header = FrameHeader {
794 length: 5,
795 frame_type: FrameType::Priority,
796 flags: 0,
797 stream_id: self.stream_id,
798 };
799 header.serialize(&mut buf);
800
801 let dep = if self.exclusive {
802 self.stream_dependency | 0x80000000
803 } else {
804 self.stream_dependency
805 };
806 buf.put_u32(dep);
807 buf.put_u8(self.weight);
808
809 buf
810 }
811
812 pub fn parse(stream_id: u32, mut payload: Bytes) -> Result<Self, String> {
814 if stream_id == 0 {
815 return Err("PRIORITY frame must have non-zero stream ID".to_string());
816 }
817 if payload.remaining() < 5 {
818 return Err("PRIORITY frame payload too short".to_string());
819 }
820
821 let dep_raw = payload.get_u32();
822 let exclusive = (dep_raw & 0x80000000) != 0;
823 let stream_dependency = dep_raw & 0x7fffffff;
824 let weight = payload.get_u8();
825
826 if stream_dependency == stream_id {
828 return Err("PRIORITY frame stream cannot depend on itself".to_string());
829 }
830
831 Ok(Self {
832 stream_id,
833 exclusive,
834 stream_dependency,
835 weight,
836 })
837 }
838}
839
840#[derive(Debug, Clone)]
842pub struct PushPromiseFrame {
843 pub stream_id: u32,
844 pub promised_stream_id: u32,
845 pub header_block: Bytes,
846 pub end_headers: bool,
847}
848
849impl PushPromiseFrame {
850 pub fn new(stream_id: u32, promised_stream_id: u32, header_block: Bytes) -> Self {
852 Self {
853 stream_id,
854 promised_stream_id,
855 header_block,
856 end_headers: true,
857 }
858 }
859
860 pub fn end_headers(mut self, end: bool) -> Self {
862 self.end_headers = end;
863 self
864 }
865
866 pub fn serialize(&self) -> BytesMut {
868 let payload_len = 4 + self.header_block.len(); let mut buf = BytesMut::with_capacity(FRAME_HEADER_SIZE + payload_len);
870
871 let header = FrameHeader {
872 length: payload_len as u32,
873 frame_type: FrameType::PushPromise,
874 flags: if self.end_headers {
875 flags::END_HEADERS
876 } else {
877 0
878 },
879 stream_id: self.stream_id,
880 };
881 header.serialize(&mut buf);
882
883 buf.put_u32(self.promised_stream_id & 0x7fffffff);
885 buf.extend_from_slice(&self.header_block);
886
887 buf
888 }
889
890 pub fn parse(stream_id: u32, flags: u8, mut payload: Bytes) -> Result<Self, String> {
892 if stream_id == 0 {
893 return Err("PUSH_PROMISE frame must have non-zero stream ID".to_string());
894 }
895
896 let end_headers = (flags & flags::END_HEADERS) != 0;
897 let padded = (flags & flags::PADDED) != 0;
898
899 let pad_len = if padded {
901 if payload.remaining() < 1 {
902 return Err("PADDED PUSH_PROMISE frame missing padding length".to_string());
903 }
904 let pad_len = payload.get_u8() as usize;
905 if pad_len >= payload.remaining() {
906 return Err("Padding length exceeds payload size".to_string());
907 }
908 pad_len
909 } else {
910 0
911 };
912
913 if payload.remaining() < 4 {
915 return Err("PUSH_PROMISE frame missing promised stream ID".to_string());
916 }
917 let promised_stream_id_raw = payload.get_u32();
918 if (promised_stream_id_raw & 0x80000000) != 0 {
919 return Err("PUSH_PROMISE frame reserved bit set in promised stream ID".to_string());
920 }
921 let promised_stream_id = promised_stream_id_raw & 0x7fffffff;
922
923 let header_block_len = payload.remaining() - pad_len;
925 if header_block_len == 0 {
926 return Err("PUSH_PROMISE frame header block is empty".to_string());
927 }
928 let header_block = payload.copy_to_bytes(header_block_len);
929 payload.advance(pad_len);
931
932 Ok(Self {
933 stream_id,
934 promised_stream_id,
935 header_block,
936 end_headers,
937 })
938 }
939}
940
941#[derive(Debug, Clone)]
943pub struct RstStreamFrame {
944 pub stream_id: u32,
945 pub error_code: ErrorCode,
946}
947
948impl RstStreamFrame {
949 pub fn new(stream_id: u32, error_code: ErrorCode) -> Self {
951 Self {
952 stream_id,
953 error_code,
954 }
955 }
956
957 pub fn serialize(&self) -> BytesMut {
959 let mut buf = BytesMut::with_capacity(FRAME_HEADER_SIZE + 4);
960
961 let header = FrameHeader {
962 length: 4,
963 frame_type: FrameType::RstStream,
964 flags: 0,
965 stream_id: self.stream_id,
966 };
967 header.serialize(&mut buf);
968 buf.put_u32(self.error_code as u32);
969
970 buf
971 }
972
973 pub fn parse(stream_id: u32, mut payload: Bytes) -> Result<Self, String> {
975 if stream_id == 0 {
976 return Err("RST_STREAM frame must have non-zero stream ID".to_string());
977 }
978 if payload.remaining() < 4 {
979 return Err("RST_STREAM frame payload too short".to_string());
980 }
981
982 let error_code_raw = payload.get_u32();
983 let error_code = match error_code_raw {
984 0x0 => ErrorCode::NoError,
985 0x1 => ErrorCode::ProtocolError,
986 0x2 => ErrorCode::InternalError,
987 0x3 => ErrorCode::FlowControlError,
988 0x4 => ErrorCode::SettingsTimeout,
989 0x5 => ErrorCode::StreamClosed,
990 0x6 => ErrorCode::FrameSizeError,
991 0x7 => ErrorCode::RefusedStream,
992 0x8 => ErrorCode::Cancel,
993 0x9 => ErrorCode::CompressionError,
994 0xa => ErrorCode::ConnectError,
995 0xb => ErrorCode::EnhanceYourCalm,
996 0xc => ErrorCode::InadequateSecurity,
997 0xd => ErrorCode::Http11Required,
998 _ => ErrorCode::ProtocolError,
999 };
1000
1001 Ok(Self {
1002 stream_id,
1003 error_code,
1004 })
1005 }
1006}
1007
1008#[cfg(test)]
1009mod tests {
1010 use super::*;
1011
1012 #[test]
1013 fn test_settings_frame_serialization() {
1014 let mut settings = SettingsFrame::new();
1015 settings
1016 .set(SettingsId::HeaderTableSize, 65536)
1017 .set(SettingsId::MaxConcurrentStreams, 1000)
1018 .set(SettingsId::InitialWindowSize, 6291456);
1019
1020 let buf = settings.serialize();
1021
1022 assert_eq!(buf.len(), 27);
1024
1025 assert_eq!(buf[0..3], [0, 0, 18]); assert_eq!(buf[3], 0x4); assert_eq!(buf[4], 0); assert_eq!(buf[5..9], [0, 0, 0, 0]); }
1031
1032 #[test]
1033 fn test_settings_ack_frame() {
1034 let settings = SettingsFrame::ack();
1035 let buf = settings.serialize();
1036
1037 assert_eq!(buf.len(), 9); assert_eq!(buf[0..3], [0, 0, 0]); assert_eq!(buf[3], 0x4); assert_eq!(buf[4], 0x1); }
1042
1043 #[test]
1044 fn test_window_update_frame() {
1045 let frame = WindowUpdateFrame::new(0, 15663105);
1046 let buf = frame.serialize();
1047
1048 assert_eq!(buf.len(), 13); assert_eq!(buf[3], 0x8); }
1051
1052 #[test]
1053 fn test_frame_header_parse() {
1054 let bytes = [0, 0, 18, 0x4, 0, 0, 0, 0, 0];
1055 let header = FrameHeader::parse(&bytes).unwrap();
1056
1057 assert_eq!(header.length, 18);
1058 assert_eq!(header.frame_type, FrameType::Settings);
1059 assert_eq!(header.flags, 0);
1060 assert_eq!(header.stream_id, 0);
1061 }
1062}