use std::fmt;
macro_rules! unpack_octets_4 {
($buf:expr, $offset:expr, $tip:ty) => {
(($buf[$offset + 0] as $tip) << 24)
| (($buf[$offset + 1] as $tip) << 16)
| (($buf[$offset + 2] as $tip) << 8)
| (($buf[$offset + 3] as $tip) << 0)
};
}
#[cfg(test)]
mod tests {
#[test]
fn test_unpack_octets_4() {
let buf: [u8; 4] = [0, 0, 0, 1];
assert_eq!(1u32, unpack_octets_4!(buf, 0, u32));
}
}
mod data;
mod go_away;
mod head;
mod headers;
mod ping;
mod priority;
mod protocol;
mod reason;
mod reset;
mod settings;
mod stream_id;
mod util;
mod window_update;
pub use self::data::Data;
pub use self::go_away::GoAway;
pub use self::head::{Head, Kind};
pub use self::headers::{Headers, PseudoHeaders};
pub use self::ping::Ping;
pub use self::priority::{Priority, StreamDependency};
pub use self::protocol::Protocol;
pub use self::reason::Reason;
pub use self::reset::Reset;
pub use self::settings::Settings;
pub use self::stream_id::{StreamId, StreamIdOverflow};
pub use self::window_update::WindowUpdate;
pub use self::settings::{
DEFAULT_INITIAL_WINDOW_SIZE, DEFAULT_MAX_FRAME_SIZE, DEFAULT_SETTINGS_HEADER_TABLE_SIZE,
MAX_INITIAL_WINDOW_SIZE, MAX_MAX_FRAME_SIZE,
};
use crate::hpack;
pub type FrameSize = u32;
pub type WindowSize = u32;
pub const HEADER_LEN: usize = 9;
#[derive(Clone)]
pub enum Frame {
Data(Data),
Headers(Headers),
Priority(Priority),
Settings(Settings),
Ping(Ping),
GoAway(GoAway),
WindowUpdate(WindowUpdate),
Reset(Reset),
}
impl fmt::Debug for Frame {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
use self::Frame::*;
match *self {
Data(ref frame) => fmt::Debug::fmt(frame, fmt),
Headers(ref frame) => fmt::Debug::fmt(frame, fmt),
Priority(ref frame) => fmt::Debug::fmt(frame, fmt),
Settings(ref frame) => fmt::Debug::fmt(frame, fmt),
Ping(ref frame) => fmt::Debug::fmt(frame, fmt),
GoAway(ref frame) => fmt::Debug::fmt(frame, fmt),
WindowUpdate(ref frame) => fmt::Debug::fmt(frame, fmt),
Reset(ref frame) => fmt::Debug::fmt(frame, fmt),
}
}
}
#[derive(thiserror::Error, Debug, Copy, Clone, PartialEq, Eq)]
pub enum FrameError {
#[error("A length value other than 8 was set on a PING message")]
BadFrameSize,
#[error("Frame size exceeded")]
MaxFrameSize,
#[error("The padding length was larger than the frame-header-specified length of the payload")]
TooMuchPadding,
#[error("An invalid setting value was provided")]
InvalidSettingValue,
#[error(
"The payload length specified by the frame header was not the value necessary for the specific frame type"
)]
InvalidPayloadLength,
#[error("Received a payload with an ACK settings frame")]
InvalidPayloadAckSettings,
#[error("An invalid stream identifier was provided")]
InvalidStreamId,
#[error("A request or response is malformed")]
MalformedMessage,
#[error("An invalid stream dependency ID was provided")]
InvalidDependencyId,
#[error("An invalid preface")]
InvalidPreface,
#[error("Unexpected push promise")]
UnexpectedPushPromise,
#[error("{0}")]
Continuation(#[from] FrameContinuationError),
#[error("{0}")]
Hpack(#[from] hpack::DecoderError),
}
#[derive(thiserror::Error, Debug, Copy, Clone, PartialEq, Eq)]
pub enum FrameContinuationError {
#[error("Continuation frame is expected")]
Expected,
#[error("Continuation frame is unexpected")]
Unexpected,
#[error("Continuation frame's stream id is unexpected")]
UnknownStreamId,
#[error("Max left over size")]
MaxLeftoverSize,
#[error("Malformed frame")]
Malformed,
}