1use super::*;
3
4fn wire_type(kind: FrameType) -> u8 {
5 match kind {
6 FrameType::Data => 0,
7 FrameType::Headers => 1,
8 FrameType::Priority => 2,
9 FrameType::RstStream => 3,
10 FrameType::Settings => 4,
11 FrameType::PushPromise => 5,
12 FrameType::Ping => 6,
13 FrameType::GoAway => 7,
14 FrameType::WindowUpdate => 8,
15 FrameType::Continuation => 9,
16 FrameType::Unknown(value) => value,
17 }
18}
19fn append_frame(out: &mut Vec<u8>, id: i32, kind: FrameType, flags: u8, payload: &[u8]) {
20 let length = (payload.len() as u32).to_be_bytes();
21 out.extend_from_slice(&length[1..]);
22 out.extend_from_slice(&[wire_type(kind), flags]);
23 out.extend_from_slice(&(id as u32).to_be_bytes());
24 out.extend_from_slice(payload);
25}
26impl Http2Session {
27 pub(super) fn queue_frame(&mut self, id: i32, kind: FrameType, flags: u8, payload: &[u8]) {
28 let mut bytes = Vec::with_capacity(9 + payload.len());
29 append_frame(&mut bytes, id, kind, flags, payload);
30 self.outgoing.push_back(Outgoing::Frame {
31 bytes,
32 id,
33 kind,
34 flags,
35 });
36 }
37 fn queue_headers(&mut self, id: i32, fields: &[HeaderField<'_>], end: bool) -> Result<()> {
38 let mut size = 0usize;
39 let fields = fields
40 .iter()
41 .map(|field| {
42 size = size
43 .saturating_add(field.name.len())
44 .saturating_add(field.value.len())
45 .saturating_add(32);
46 let name = std::str::from_utf8(field.name).map_err(|e| error(1, e.to_string()))?;
47 let value =
48 std::str::from_utf8(field.value).map_err(|e| error(1, e.to_string()))?;
49 Ok((name.to_owned(), value.to_owned()))
50 })
51 .collect::<Result<Vec<_>>>()?;
52 if size > self.peer.max_header_list_size as usize {
53 return Err(error(11, "peer header budget exceeded"));
54 }
55 let mut block = BytesMut::new();
56 self.encoder.encode(&fields, &mut block);
57 self.outgoing.push_back(Outgoing::Headers {
58 id,
59 block: block.as_slice().to_vec(),
60 end,
61 });
62 Ok(())
63 }
64 pub fn submit_request(
68 &mut self,
69 fields: &[HeaderField<'_>],
70 provider: Option<DataProvider>,
71 ) -> Result<i32> {
72 self.check_live()?;
73 if self.role != Http2Role::Client
74 || self.sent_goaway.is_some()
75 || self.received_goaway.is_some()
76 {
77 return Err(error(7, "connection cannot open another request"));
78 }
79 if self.streams.values().filter(|s| !s.close_emitted).count()
80 >= self.peer.max_concurrent_streams as usize
81 {
82 return Err(error(7, "peer concurrency limit reached"));
83 }
84 let id = self.next_id;
85 let next = id
86 .checked_add(2)
87 .ok_or_else(|| error(7, "stream IDs exhausted"))?;
88 self.queue_headers(id, fields, provider.is_none())?;
89 let mut stream = Stream::new(self.local, self.peer);
90 stream.provider = provider;
91 self.streams.insert(id, stream);
92 self.next_id = next;
93 Ok(id)
94 }
95 pub fn submit_response(
99 &mut self,
100 id: i32,
101 fields: &[HeaderField<'_>],
102 provider: Option<DataProvider>,
103 ) -> Result<()> {
104 self.check_stream_send(id)?;
105 self.queue_headers(id, fields, provider.is_none())?;
106 self.streams
107 .get_mut(&id)
108 .ok_or_else(|| error(5, "unknown stream"))?
109 .provider = provider;
110 Ok(())
111 }
112 pub fn submit_headers(&mut self, flags: u8, id: i32, fields: &[HeaderField<'_>]) -> Result<()> {
116 self.check_stream_send(id)?;
117 self.queue_headers(id, fields, flags & 1 != 0)
118 }
119 pub fn submit_trailer(&mut self, id: i32, fields: &[HeaderField<'_>]) -> Result<()> {
123 self.check_stream_send(id)?;
124 if self.streams[&id].provider.is_some() {
125 return Err(error(1, "body source has not finished"));
126 }
127 self.queue_headers(id, fields, true)
128 }
129 fn check_stream_send(&self, id: i32) -> Result<()> {
130 self.check_live()?;
131 if self
132 .streams
133 .get(&id)
134 .is_none_or(|s| s.local_closed || s.reset)
135 {
136 return Err(error(5, "stream cannot send"));
137 }
138 Ok(())
139 }
140 pub fn resume_data(&mut self, id: i32) -> Result<()> {
144 self.check_stream_send(id)?;
145 self.streams
146 .get_mut(&id)
147 .ok_or_else(|| error(5, "unknown stream"))?
148 .deferred = false;
149 Ok(())
150 }
151 pub fn submit_rst_stream(&mut self, id: i32, code: u32) -> Result<()> {
155 let stream = self
156 .streams
157 .get_mut(&id)
158 .ok_or_else(|| error(1, "unknown reset stream"))?;
159 if stream.reset || stream.close_emitted {
160 return Ok(());
161 }
162 stream.provider = None;
163 stream.reset = true;
164 let unconsumed = std::mem::take(&mut stream.unconsumed);
165 self.credit_connection(unconsumed)?;
166 self.queue_frame(id, FrameType::RstStream, 0, &code.to_be_bytes());
167 Ok(())
168 }
169 pub fn submit_goaway(&mut self, last: i32, code: u32, debug: &[u8]) -> Result<()> {
173 if last < 0 || debug.len() + 8 > self.peer.max_frame_size as usize {
174 return Err(error(6, "invalid GOAWAY"));
175 }
176 let last = self.sent_goaway.map_or(last, |old| old.min(last));
177 let mut bytes = Vec::with_capacity(8 + debug.len());
178 bytes.extend_from_slice(&(last as u32).to_be_bytes());
179 bytes.extend_from_slice(&code.to_be_bytes());
180 bytes.extend_from_slice(debug);
181 self.queue_frame(0, FrameType::GoAway, 0, &bytes);
182 self.sent_goaway = Some(last);
183 Ok(())
184 }
185 pub fn mem_send(&mut self) -> Result<&[u8]> {
189 self.check_live()?;
190 self.output.clear();
191 if let Some(item) = self.outgoing.pop_front() {
192 self.serialize(item);
193 } else {
194 self.send_body()?;
195 }
196 Ok(&self.output)
197 }
198 fn serialize(&mut self, item: Outgoing) {
199 let (id, kind, flags) = match item {
200 Outgoing::Frame {
201 bytes,
202 id,
203 kind,
204 flags,
205 } => {
206 self.output.extend_from_slice(&bytes);
207 (id, kind, flags)
208 }
209 Outgoing::Headers { id, block, end } => {
210 let max = self.peer.max_frame_size as usize;
211 let total = block.len().max(1).div_ceil(max);
212 if block.is_empty() {
213 append_frame(
214 &mut self.output,
215 id,
216 FrameType::Headers,
217 4 | u8::from(end),
218 &[],
219 );
220 }
221 for (index, chunk) in block.chunks(max).enumerate() {
222 let kind = if index == 0 {
223 FrameType::Headers
224 } else {
225 FrameType::Continuation
226 };
227 let flags = if index == 0 { u8::from(end) } else { 0 }
228 | if index + 1 == total { 4 } else { 0 };
229 append_frame(&mut self.output, id, kind, flags, chunk);
230 }
231 (id, FrameType::Headers, u8::from(end))
232 }
233 };
234 self.events.push_back(SessionEvent::FrameSend {
235 stream_id: id,
236 frame_type: kind,
237 flags,
238 });
239 if kind == FrameType::RstStream {
240 if let Some(stream) = self.streams.get_mut(&id)
241 && !stream.close_emitted
242 {
243 stream.close_emitted = true;
244 let code =
245 u32::from_be_bytes(self.output[9..13].try_into().expect("reset payload"));
246 self.events.push_back(SessionEvent::StreamClose {
247 stream_id: id,
248 error_code: code,
249 });
250 }
251 } else if flags & 1 != 0 && matches!(kind, FrameType::Headers | FrameType::Data) {
252 if let Some(stream) = self.streams.get_mut(&id) {
253 stream.local_closed = true;
254 }
255 self.close_if_complete(id);
256 }
257 }
258 fn send_body(&mut self) -> Result<()> {
259 let ids: Vec<_> = self
260 .streams
261 .range((
262 std::ops::Bound::Excluded(self.last_sent),
263 std::ops::Bound::Unbounded,
264 ))
265 .chain(self.streams.range(..=self.last_sent))
266 .map(|(id, _)| *id)
267 .collect();
268 for id in ids {
269 let stream = self.streams.get_mut(&id).expect("existing stream");
270 if stream.deferred || stream.reset || stream.local_closed {
271 continue;
272 }
273 let Some(provider) = &mut stream.provider else {
274 continue;
275 };
276 let max = self
277 .send_window
278 .min(stream.send_window)
279 .max(0)
280 .min(self.peer.max_frame_size.into()) as usize;
281 let (data, eof, trailers) = match provider.0.read(max) {
282 DataPoll::Copy(bytes) => {
283 if bytes.len() > max {
284 return Err(error(2, "body producer exceeded permitted length"));
285 }
286 if bytes.is_empty() {
287 continue;
288 }
289 (bytes.to_vec(), false, false)
290 }
291 DataPoll::Deferred => {
292 stream.deferred = true;
293 continue;
294 }
295 DataPoll::Eof => (Vec::new(), true, false),
296 DataPoll::EofWithTrailers => (Vec::new(), true, true),
297 };
298 if eof {
299 stream.provider = None;
300 }
301 if trailers {
302 continue;
303 }
304 stream.send_window -= data.len() as i64;
305 self.send_window -= data.len() as i64;
306 let mut bytes = Vec::with_capacity(9 + data.len());
307 append_frame(&mut bytes, id, FrameType::Data, u8::from(eof), &data);
308 self.last_sent = id;
309 self.serialize(Outgoing::Frame {
310 bytes,
311 id,
312 kind: FrameType::Data,
313 flags: u8::from(eof),
314 });
315 break;
316 }
317 Ok(())
318 }
319}