1 use 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 /// ```rust 15 /// let buf: [u8; 4] = [0, 0, 0, 1]; 16 /// assert_eq!(1u32, unpack_octets_4!(buf, 0, u32)); 17 /// ``` 18 #[macro_escape] 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 mod data; 30 mod go_away; 31 mod head; 32 mod headers; 33 mod ping; 34 mod priority; 35 mod reason; 36 mod reset; 37 mod settings; 38 mod stream_id; 39 mod util; 40 mod window_update; 41 42 pub use self::data::Data; 43 pub use self::go_away::GoAway; 44 pub use self::head::{Head, Kind}; 45 pub use self::headers::{Continuation, Headers, Pseudo, PushPromise}; 46 pub use self::ping::Ping; 47 pub use self::priority::{Priority, StreamDependency}; 48 pub use self::reason::Reason; 49 pub use self::reset::Reset; 50 pub use self::settings::Settings; 51 pub use self::stream_id::{StreamId, StreamIdOverflow}; 52 pub use self::window_update::WindowUpdate; 53 54 // Re-export some constants 55 56 pub use self::settings::{ 57 DEFAULT_INITIAL_WINDOW_SIZE, 58 DEFAULT_MAX_FRAME_SIZE, 59 DEFAULT_SETTINGS_HEADER_TABLE_SIZE, 60 MAX_INITIAL_WINDOW_SIZE, 61 MAX_MAX_FRAME_SIZE, 62 }; 63 64 pub type FrameSize = u32; 65 66 pub const HEADER_LEN: usize = 9; 67 68 #[derive(Eq, PartialEq)] 69 pub enum Frame<T = Bytes> { 70 Data(Data<T>), 71 Headers(Headers), 72 Priority(Priority), 73 PushPromise(PushPromise), 74 Settings(Settings), 75 Ping(Ping), 76 GoAway(GoAway), 77 WindowUpdate(WindowUpdate), 78 Reset(Reset), 79 } 80 81 impl<T> Frame<T> { map<F, U>(self, f: F) -> Frame<U> where F: FnOnce(T) -> U,82 pub fn map<F, U>(self, f: F) -> Frame<U> 83 where 84 F: FnOnce(T) -> U, 85 { 86 use self::Frame::*; 87 88 match self { 89 Data(frame) => frame.map(f).into(), 90 Headers(frame) => frame.into(), 91 Priority(frame) => frame.into(), 92 PushPromise(frame) => frame.into(), 93 Settings(frame) => frame.into(), 94 Ping(frame) => frame.into(), 95 GoAway(frame) => frame.into(), 96 WindowUpdate(frame) => frame.into(), 97 Reset(frame) => frame.into(), 98 } 99 } 100 } 101 102 impl<T> fmt::Debug for Frame<T> { fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result103 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { 104 use self::Frame::*; 105 106 match *self { 107 Data(ref frame) => write!(fmt, "Frame::Data({:?})", frame), 108 Headers(ref frame) => write!(fmt, "Frame::Headers({:?})", frame), 109 Priority(ref frame) => write!(fmt, "Frame::Priority({:?})", frame), 110 PushPromise(ref frame) => write!(fmt, "Frame::PushPromise({:?})", frame), 111 Settings(ref frame) => write!(fmt, "Frame::Settings({:?})", frame), 112 Ping(ref frame) => write!(fmt, "Frame::Ping({:?})", frame), 113 GoAway(ref frame) => write!(fmt, "Frame::GoAway({:?})", frame), 114 WindowUpdate(ref frame) => write!(fmt, "Frame::WindowUpdate({:?})", frame), 115 Reset(ref frame) => write!(fmt, "Frame::Reset({:?})", frame), 116 } 117 } 118 } 119 120 /// Errors that can occur during parsing an HTTP/2 frame. 121 #[derive(Debug, Clone, PartialEq, Eq)] 122 pub enum Error { 123 /// A length value other than 8 was set on a PING message. 124 BadFrameSize, 125 126 /// The padding length was larger than the frame-header-specified 127 /// length of the payload. 128 TooMuchPadding, 129 130 /// An invalid setting value was provided 131 InvalidSettingValue, 132 133 /// An invalid window update value 134 InvalidWindowUpdateValue, 135 136 /// The payload length specified by the frame header was not the 137 /// value necessary for the specific frame type. 138 InvalidPayloadLength, 139 140 /// Received a payload with an ACK settings frame 141 InvalidPayloadAckSettings, 142 143 /// An invalid stream identifier was provided. 144 /// 145 /// This is returned if a SETTINGS or PING frame is received with a stream 146 /// identifier other than zero. 147 InvalidStreamId, 148 149 /// A request or response is malformed. 150 MalformedMessage, 151 152 /// An invalid stream dependency ID was provided 153 /// 154 /// This is returned if a HEADERS or PRIORITY frame is received with an 155 /// invalid stream identifier. 156 InvalidDependencyId, 157 158 /// Failed to perform HPACK decoding 159 Hpack(hpack::DecoderError), 160 } 161