summaryrefslogtreecommitdiffstats
path: root/third_party/rust/h2/src/frame/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/h2/src/frame/mod.rs')
-rw-r--r--third_party/rust/h2/src/frame/mod.rs171
1 files changed, 171 insertions, 0 deletions
diff --git a/third_party/rust/h2/src/frame/mod.rs b/third_party/rust/h2/src/frame/mod.rs
new file mode 100644
index 0000000000..0e8e7035c3
--- /dev/null
+++ b/third_party/rust/h2/src/frame/mod.rs
@@ -0,0 +1,171 @@
+use crate::hpack;
+
+use bytes::Bytes;
+
+use std::fmt;
+
+/// A helper macro that unpacks a sequence of 4 bytes found in the buffer with
+/// the given identifier, starting at the given offset, into the given integer
+/// type. Obviously, the integer type should be able to support at least 4
+/// bytes.
+///
+/// # Examples
+///
+/// ```ignore
+/// # // We ignore this doctest because the macro is not exported.
+/// let buf: [u8; 4] = [0, 0, 0, 1];
+/// assert_eq!(1u32, unpack_octets_4!(buf, 0, u32));
+/// ```
+macro_rules! unpack_octets_4 {
+ // TODO: Get rid of this macro
+ ($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 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::{
+ parse_u64, Continuation, Headers, Pseudo, PushPromise, PushPromiseHeaderError,
+};
+pub use self::ping::Ping;
+pub use self::priority::{Priority, StreamDependency};
+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;
+
+#[cfg(feature = "unstable")]
+pub use crate::hpack::BytesStr;
+
+// Re-export some constants
+
+pub use self::settings::{
+ DEFAULT_INITIAL_WINDOW_SIZE, DEFAULT_MAX_FRAME_SIZE, DEFAULT_SETTINGS_HEADER_TABLE_SIZE,
+ MAX_MAX_FRAME_SIZE,
+};
+
+pub type FrameSize = u32;
+
+pub const HEADER_LEN: usize = 9;
+
+#[derive(Eq, PartialEq)]
+pub enum Frame<T = Bytes> {
+ Data(Data<T>),
+ Headers(Headers),
+ Priority(Priority),
+ PushPromise(PushPromise),
+ Settings(Settings),
+ Ping(Ping),
+ GoAway(GoAway),
+ WindowUpdate(WindowUpdate),
+ Reset(Reset),
+}
+
+impl<T> Frame<T> {
+ pub fn map<F, U>(self, f: F) -> Frame<U>
+ where
+ F: FnOnce(T) -> U,
+ {
+ use self::Frame::*;
+
+ match self {
+ Data(frame) => frame.map(f).into(),
+ Headers(frame) => frame.into(),
+ Priority(frame) => frame.into(),
+ PushPromise(frame) => frame.into(),
+ Settings(frame) => frame.into(),
+ Ping(frame) => frame.into(),
+ GoAway(frame) => frame.into(),
+ WindowUpdate(frame) => frame.into(),
+ Reset(frame) => frame.into(),
+ }
+ }
+}
+
+impl<T> fmt::Debug for Frame<T> {
+ 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),
+ PushPromise(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),
+ }
+ }
+}
+
+/// Errors that can occur during parsing an HTTP/2 frame.
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub enum Error {
+ /// A length value other than 8 was set on a PING message.
+ BadFrameSize,
+
+ /// The padding length was larger than the frame-header-specified
+ /// length of the payload.
+ TooMuchPadding,
+
+ /// An invalid setting value was provided
+ InvalidSettingValue,
+
+ /// An invalid window update value
+ InvalidWindowUpdateValue,
+
+ /// The payload length specified by the frame header was not the
+ /// value necessary for the specific frame type.
+ InvalidPayloadLength,
+
+ /// Received a payload with an ACK settings frame
+ InvalidPayloadAckSettings,
+
+ /// An invalid stream identifier was provided.
+ ///
+ /// This is returned if a SETTINGS or PING frame is received with a stream
+ /// identifier other than zero.
+ InvalidStreamId,
+
+ /// A request or response is malformed.
+ MalformedMessage,
+
+ /// An invalid stream dependency ID was provided
+ ///
+ /// This is returned if a HEADERS or PRIORITY frame is received with an
+ /// invalid stream identifier.
+ InvalidDependencyId,
+
+ /// Failed to perform HPACK decoding
+ Hpack(hpack::DecoderError),
+}