1 use crate::hpack; 2 3 use bytes::Bytes; 4 5 use std::fmt; 6 7 /// A helper macro that unpacks a sequence of 4 bytes found in the buffer with 8 /// the given identifier, starting at the given offset, into the given integer 9 /// type. Obviously, the integer type should be able to support at least 4 10 /// bytes. 11 /// 12 /// # Examples 13 /// 14 /// ```ignore 15 /// # // We ignore this doctest because the macro is not exported. 16 /// let buf: [u8; 4] = [0, 0, 0, 1]; 17 /// assert_eq!(1u32, unpack_octets_4!(buf, 0, u32)); 18 /// ``` 19 macro_rules! unpack_octets_4 { 20 // TODO: Get rid of this macro 21 ($buf:expr, $offset:expr, $tip:ty) => { 22 (($buf[$offset + 0] as $tip) << 24) 23 | (($buf[$offset + 1] as $tip) << 16) 24 | (($buf[$offset + 2] as $tip) << 8) 25 | (($buf[$offset + 3] as $tip) << 0) 26 }; 27 } 28 29 #[cfg(test)] 30 mod tests { 31 #[test] test_unpack_octets_4()32 fn test_unpack_octets_4() { 33 let buf: [u8; 4] = [0, 0, 0, 1]; 34 assert_eq!(1u32, unpack_octets_4!(buf, 0, u32)); 35 } 36 } 37 38 mod data; 39 mod go_away; 40 mod head; 41 mod headers; 42 mod ping; 43 mod priority; 44 mod reason; 45 mod reset; 46 mod settings; 47 mod stream_id; 48 mod util; 49 mod window_update; 50 51 pub use self::data::Data; 52 pub use self::go_away::GoAway; 53 pub use self::head::{Head, Kind}; 54 pub use self::headers::{ 55 parse_u64, Continuation, Headers, Pseudo, PushPromise, PushPromiseHeaderError, 56 }; 57 pub use self::ping::Ping; 58 pub use self::priority::{Priority, StreamDependency}; 59 pub use self::reason::Reason; 60 pub use self::reset::Reset; 61 pub use self::settings::Settings; 62 pub use self::stream_id::{StreamId, StreamIdOverflow}; 63 pub use self::window_update::WindowUpdate; 64 65 #[cfg(feature = "unstable")] 66 pub use crate::hpack::BytesStr; 67 68 // Re-export some constants 69 70 pub use self::settings::{ 71 DEFAULT_INITIAL_WINDOW_SIZE, DEFAULT_MAX_FRAME_SIZE, DEFAULT_SETTINGS_HEADER_TABLE_SIZE, 72 MAX_MAX_FRAME_SIZE, 73 }; 74 75 pub type FrameSize = u32; 76 77 pub const HEADER_LEN: usize = 9; 78 79 #[derive(Eq, PartialEq)] 80 pub enum Frame<T = Bytes> { 81 Data(Data<T>), 82 Headers(Headers), 83 Priority(Priority), 84 PushPromise(PushPromise), 85 Settings(Settings), 86 Ping(Ping), 87 GoAway(GoAway), 88 WindowUpdate(WindowUpdate), 89 Reset(Reset), 90 } 91 92 impl<T> Frame<T> { map<F, U>(self, f: F) -> Frame<U> where F: FnOnce(T) -> U,93 pub fn map<F, U>(self, f: F) -> Frame<U> 94 where 95 F: FnOnce(T) -> U, 96 { 97 use self::Frame::*; 98 99 match self { 100 Data(frame) => frame.map(f).into(), 101 Headers(frame) => frame.into(), 102 Priority(frame) => frame.into(), 103 PushPromise(frame) => frame.into(), 104 Settings(frame) => frame.into(), 105 Ping(frame) => frame.into(), 106 GoAway(frame) => frame.into(), 107 WindowUpdate(frame) => frame.into(), 108 Reset(frame) => frame.into(), 109 } 110 } 111 } 112 113 impl<T> fmt::Debug for Frame<T> { fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result114 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { 115 use self::Frame::*; 116 117 match *self { 118 Data(ref frame) => fmt::Debug::fmt(frame, fmt), 119 Headers(ref frame) => fmt::Debug::fmt(frame, fmt), 120 Priority(ref frame) => fmt::Debug::fmt(frame, fmt), 121 PushPromise(ref frame) => fmt::Debug::fmt(frame, fmt), 122 Settings(ref frame) => fmt::Debug::fmt(frame, fmt), 123 Ping(ref frame) => fmt::Debug::fmt(frame, fmt), 124 GoAway(ref frame) => fmt::Debug::fmt(frame, fmt), 125 WindowUpdate(ref frame) => fmt::Debug::fmt(frame, fmt), 126 Reset(ref frame) => fmt::Debug::fmt(frame, fmt), 127 } 128 } 129 } 130 131 /// Errors that can occur during parsing an HTTP/2 frame. 132 #[derive(Debug, Clone, PartialEq, Eq)] 133 pub enum Error { 134 /// A length value other than 8 was set on a PING message. 135 BadFrameSize, 136 137 /// The padding length was larger than the frame-header-specified 138 /// length of the payload. 139 TooMuchPadding, 140 141 /// An invalid setting value was provided 142 InvalidSettingValue, 143 144 /// An invalid window update value 145 InvalidWindowUpdateValue, 146 147 /// The payload length specified by the frame header was not the 148 /// value necessary for the specific frame type. 149 InvalidPayloadLength, 150 151 /// Received a payload with an ACK settings frame 152 InvalidPayloadAckSettings, 153 154 /// An invalid stream identifier was provided. 155 /// 156 /// This is returned if a SETTINGS or PING frame is received with a stream 157 /// identifier other than zero. 158 InvalidStreamId, 159 160 /// A request or response is malformed. 161 MalformedMessage, 162 163 /// An invalid stream dependency ID was provided 164 /// 165 /// This is returned if a HEADERS or PRIORITY frame is received with an 166 /// invalid stream identifier. 167 InvalidDependencyId, 168 169 /// Failed to perform HPACK decoding 170 Hpack(hpack::DecoderError), 171 } 172