1use super::error::Http2ParseError;
4use super::types::{Http2FrameType, Http2StreamId};
5
6pub const HTTP2_CLIENT_PREFACE: &[u8; 24] = b"PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n";
8
9#[derive(Clone, Copy, Debug, Eq, PartialEq)]
11pub struct Http2ClientPreface<'a> {
12 bytes: &'a [u8],
13}
14
15impl<'a> Http2ClientPreface<'a> {
16 pub fn parse(bytes: &'a [u8]) -> Result<Self, Http2ParseError> {
18 if bytes.len() < HTTP2_CLIENT_PREFACE.len() {
19 return Err(Http2ParseError::Incomplete {
20 required: HTTP2_CLIENT_PREFACE.len(),
21 available: bytes.len(),
22 });
23 }
24 for (offset, (&actual, &expected)) in
25 bytes.iter().zip(HTTP2_CLIENT_PREFACE.iter()).enumerate()
26 {
27 if actual != expected {
28 return Err(Http2ParseError::ClientPrefaceMismatch {
29 offset,
30 expected,
31 actual,
32 });
33 }
34 }
35 Ok(Self {
36 bytes: &bytes[..HTTP2_CLIENT_PREFACE.len()],
37 })
38 }
39
40 pub fn as_bytes(&self) -> &'a [u8] {
42 self.bytes
43 }
44}
45
46#[derive(Clone, Copy, Debug, Eq, PartialEq)]
48pub struct Http2Frame<'a> {
49 bytes: &'a [u8],
50}
51
52impl<'a> Http2Frame<'a> {
53 pub(super) fn from_validated(bytes: &'a [u8]) -> Self {
54 Self { bytes }
55 }
56
57 pub fn parse(bytes: &'a [u8], maximum_payload: usize) -> Result<Self, Http2ParseError> {
59 let length = frame_length(bytes, maximum_payload)?;
60 Ok(Self {
61 bytes: &bytes[..length],
62 })
63 }
64
65 pub fn payload_length(&self) -> usize {
67 usize::from(self.bytes[0]) << 16
68 | usize::from(self.bytes[1]) << 8
69 | usize::from(self.bytes[2])
70 }
71
72 pub fn frame_type(&self) -> Http2FrameType {
74 Http2FrameType::new(self.bytes[3])
75 }
76
77 pub fn flags(&self) -> u8 {
79 self.bytes[4]
80 }
81
82 pub fn stream_id(&self) -> Http2StreamId {
84 Http2StreamId::new(u32::from_be_bytes([
85 self.bytes[5],
86 self.bytes[6],
87 self.bytes[7],
88 self.bytes[8],
89 ]))
90 }
91
92 pub fn payload(&self) -> &'a [u8] {
94 &self.bytes[9..]
95 }
96
97 pub fn as_bytes(&self) -> &'a [u8] {
99 self.bytes
100 }
101}
102
103#[derive(Debug, Eq, PartialEq)]
105pub struct Http2FrameMut<'a> {
106 bytes: &'a mut [u8],
107}
108
109impl<'a> Http2FrameMut<'a> {
110 pub fn parse(bytes: &'a mut [u8], maximum_payload: usize) -> Result<Self, Http2ParseError> {
112 let length = frame_length(bytes, maximum_payload)?;
113 Ok(Self {
114 bytes: &mut bytes[..length],
115 })
116 }
117
118 pub(crate) fn from_validated(bytes: &'a mut [u8]) -> Self {
119 Self { bytes }
120 }
121
122 pub fn payload_length(&self) -> usize {
124 usize::from(self.bytes[0]) << 16
125 | usize::from(self.bytes[1]) << 8
126 | usize::from(self.bytes[2])
127 }
128
129 pub fn frame_type(&self) -> Http2FrameType {
131 Http2FrameType::new(self.bytes[3])
132 }
133
134 pub fn flags(&self) -> u8 {
136 self.bytes[4]
137 }
138
139 pub fn stream_id(&self) -> Http2StreamId {
141 Http2StreamId::new(u32::from_be_bytes([
142 self.bytes[5],
143 self.bytes[6],
144 self.bytes[7],
145 self.bytes[8],
146 ]))
147 }
148
149 pub fn payload(&self) -> &[u8] {
151 &self.bytes[9..]
152 }
153
154 pub fn payload_mut(&mut self) -> &mut [u8] {
156 &mut self.bytes[9..]
157 }
158
159 pub fn as_bytes(&self) -> &[u8] {
161 self.bytes
162 }
163}
164
165fn frame_length(bytes: &[u8], maximum_payload: usize) -> Result<usize, Http2ParseError> {
166 const HEADER_LENGTH: usize = 9;
167
168 if bytes.len() < HEADER_LENGTH {
169 return Err(Http2ParseError::Incomplete {
170 required: HEADER_LENGTH,
171 available: bytes.len(),
172 });
173 }
174 let payload_length =
175 usize::from(bytes[0]) << 16 | usize::from(bytes[1]) << 8 | usize::from(bytes[2]);
176 if payload_length > maximum_payload {
177 return Err(Http2ParseError::PayloadTooLarge {
178 maximum: maximum_payload,
179 actual: payload_length,
180 });
181 }
182 let required =
183 HEADER_LENGTH
184 .checked_add(payload_length)
185 .ok_or(Http2ParseError::PayloadTooLarge {
186 maximum: maximum_payload,
187 actual: payload_length,
188 })?;
189 if bytes.len() < required {
190 return Err(Http2ParseError::Incomplete {
191 required,
192 available: bytes.len(),
193 });
194 }
195 Ok(required)
196}