diff options
Diffstat (limited to 'third_party/rust/h2/src/frame/window_update.rs')
-rw-r--r-- | third_party/rust/h2/src/frame/window_update.rs | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/third_party/rust/h2/src/frame/window_update.rs b/third_party/rust/h2/src/frame/window_update.rs new file mode 100644 index 0000000000..eed2ce17ec --- /dev/null +++ b/third_party/rust/h2/src/frame/window_update.rs @@ -0,0 +1,62 @@ +use crate::frame::{self, Error, Head, Kind, StreamId}; + +use bytes::BufMut; + +const SIZE_INCREMENT_MASK: u32 = 1 << 31; + +#[derive(Debug, Copy, Clone, Eq, PartialEq)] +pub struct WindowUpdate { + stream_id: StreamId, + size_increment: u32, +} + +impl WindowUpdate { + pub fn new(stream_id: StreamId, size_increment: u32) -> WindowUpdate { + WindowUpdate { + stream_id, + size_increment, + } + } + + pub fn stream_id(&self) -> StreamId { + self.stream_id + } + + pub fn size_increment(&self) -> u32 { + self.size_increment + } + + /// Builds a `WindowUpdate` frame from a raw frame. + pub fn load(head: Head, payload: &[u8]) -> Result<WindowUpdate, Error> { + debug_assert_eq!(head.kind(), crate::frame::Kind::WindowUpdate); + if payload.len() != 4 { + return Err(Error::BadFrameSize); + } + + // Clear the most significant bit, as that is reserved and MUST be ignored + // when received. + let size_increment = unpack_octets_4!(payload, 0, u32) & !SIZE_INCREMENT_MASK; + + if size_increment == 0 { + return Err(Error::InvalidWindowUpdateValue); + } + + Ok(WindowUpdate { + stream_id: head.stream_id(), + size_increment, + }) + } + + pub fn encode<B: BufMut>(&self, dst: &mut B) { + tracing::trace!("encoding WINDOW_UPDATE; id={:?}", self.stream_id); + let head = Head::new(Kind::WindowUpdate, 0, self.stream_id); + head.encode(4, dst); + dst.put_u32(self.size_increment); + } +} + +impl<B> From<WindowUpdate> for frame::Frame<B> { + fn from(src: WindowUpdate) -> Self { + frame::Frame::WindowUpdate(src) + } +} |