net_wire/http2/builder/
raw.rs1use super::super::error::Http2BuildError;
4use super::super::frame::Http2FrameMut;
5use super::super::types::{Http2FrameType, Http2StreamId};
6
7pub(super) const FRAME_HEADER_LENGTH: usize = 9;
8pub(super) const MAXIMUM_PAYLOAD: usize = 0x00ff_ffff;
9
10pub(super) fn write_frame_envelope(
11 buffer: &mut [u8],
12 payload_length: usize,
13 frame_type: Http2FrameType,
14 flags: u8,
15 stream_id: Http2StreamId,
16 maximum_payload: usize,
17) -> Result<&mut [u8], Http2BuildError> {
18 let maximum_payload = maximum_payload.min(MAXIMUM_PAYLOAD);
19 if payload_length > maximum_payload {
20 return Err(Http2BuildError::PayloadTooLarge {
21 maximum: maximum_payload,
22 actual: payload_length,
23 });
24 }
25 let required = FRAME_HEADER_LENGTH.checked_add(payload_length).ok_or(
26 Http2BuildError::PayloadTooLarge {
27 maximum: maximum_payload,
28 actual: payload_length,
29 },
30 )?;
31 if buffer.len() < required {
32 return Err(Http2BuildError::BufferTooShort {
33 required,
34 available: buffer.len(),
35 });
36 }
37
38 let bytes = &mut buffer[..required];
39 let payload_length = payload_length as u32;
40 bytes[0] = (payload_length >> 16) as u8;
41 bytes[1] = (payload_length >> 8) as u8;
42 bytes[2] = payload_length as u8;
43 bytes[3] = frame_type.raw();
44 bytes[4] = flags;
45 bytes[5..FRAME_HEADER_LENGTH].copy_from_slice(&stream_id.raw().to_be_bytes());
46 Ok(bytes)
47}
48
49pub struct Http2FrameBuilder<'a, 'b> {
51 buffer: &'a mut [u8],
52 frame_type: Http2FrameType,
53 flags: u8,
54 stream_id: Http2StreamId,
55 payload: &'b [u8],
56}
57
58impl<'a, 'b> Http2FrameBuilder<'a, 'b> {
59 pub fn new(
61 buffer: &'a mut [u8],
62 frame_type: Http2FrameType,
63 flags: u8,
64 stream_id: Http2StreamId,
65 payload: &'b [u8],
66 ) -> Self {
67 Self {
68 buffer,
69 frame_type,
70 flags,
71 stream_id,
72 payload,
73 }
74 }
75
76 pub fn build(self) -> Result<Http2FrameMut<'a>, Http2BuildError> {
78 self.build_with_maximum(MAXIMUM_PAYLOAD)
79 }
80
81 pub fn build_with_maximum(
83 self,
84 maximum_payload: usize,
85 ) -> Result<Http2FrameMut<'a>, Http2BuildError> {
86 if self.stream_id.has_reserved_bit() {
87 return Err(Http2BuildError::ReservedStreamId);
88 }
89 let bytes = write_frame_envelope(
90 self.buffer,
91 self.payload.len(),
92 self.frame_type,
93 self.flags,
94 self.stream_id,
95 maximum_payload,
96 )?;
97 bytes[FRAME_HEADER_LENGTH..].copy_from_slice(self.payload);
98 Ok(Http2FrameMut::from_validated(bytes))
99 }
100}