1use crate::hpack;
2
3use bytes::Bytes;
4
5use std::fmt;
6
7macro_rules! unpack_octets_4 {
20 ($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)]
30mod tests {
31 #[test]
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
38mod data;
39mod go_away;
40mod head;
41mod headers;
42mod ping;
43mod priority;
44mod reason;
45mod reset;
46mod settings;
47mod stream_id;
48mod util;
49mod window_update;
50
51pub use self::data::Data;
52pub use self::go_away::GoAway;
53pub use self::head::{Head, Kind};
54pub use self::headers::{
55 parse_u64, Continuation, Headers, Pseudo, PseudoId, PseudoOrder, PseudoOrderBuilder,
56 PushPromise, PushPromiseHeaderError,
57};
58pub use self::ping::Ping;
59pub use self::priority::{Priority, StreamDependency};
60pub use self::reason::Reason;
61pub use self::reset::Reset;
62pub use self::settings::{Setting, SettingId, Settings, SettingsOrder, SettingsOrderBuilder};
63pub use self::stream_id::{StreamId, StreamIdOverflow};
64pub use self::window_update::WindowUpdate;
65
66#[cfg(feature = "unstable")]
67pub use crate::hpack::BytesStr;
68
69pub use self::settings::{
72 DEFAULT_INITIAL_WINDOW_SIZE, DEFAULT_MAX_FRAME_SIZE, DEFAULT_SETTINGS_HEADER_TABLE_SIZE,
73 MAX_MAX_FRAME_SIZE,
74};
75
76pub type FrameSize = u32;
77
78pub const HEADER_LEN: usize = 9;
79
80#[derive(Eq, PartialEq)]
81pub enum Frame<T = Bytes> {
82 Data(Data<T>),
83 Headers(Headers),
84 Priority(Priority),
85 PushPromise(PushPromise),
86 Settings(Settings),
87 Ping(Ping),
88 GoAway(GoAway),
89 WindowUpdate(WindowUpdate),
90 Reset(Reset),
91}
92
93impl<T> Frame<T> {
94 pub fn map<F, U>(self, f: F) -> Frame<U>
95 where
96 F: FnOnce(T) -> U,
97 {
98 use self::Frame::*;
99
100 match self {
101 Data(frame) => frame.map(f).into(),
102 Headers(frame) => frame.into(),
103 Priority(frame) => frame.into(),
104 PushPromise(frame) => frame.into(),
105 Settings(frame) => frame.into(),
106 Ping(frame) => frame.into(),
107 GoAway(frame) => frame.into(),
108 WindowUpdate(frame) => frame.into(),
109 Reset(frame) => frame.into(),
110 }
111 }
112}
113
114impl<T> fmt::Debug for Frame<T> {
115 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
116 use self::Frame::*;
117
118 match *self {
119 Data(ref frame) => fmt::Debug::fmt(frame, fmt),
120 Headers(ref frame) => fmt::Debug::fmt(frame, fmt),
121 Priority(ref frame) => fmt::Debug::fmt(frame, fmt),
122 PushPromise(ref frame) => fmt::Debug::fmt(frame, fmt),
123 Settings(ref frame) => fmt::Debug::fmt(frame, fmt),
124 Ping(ref frame) => fmt::Debug::fmt(frame, fmt),
125 GoAway(ref frame) => fmt::Debug::fmt(frame, fmt),
126 WindowUpdate(ref frame) => fmt::Debug::fmt(frame, fmt),
127 Reset(ref frame) => fmt::Debug::fmt(frame, fmt),
128 }
129 }
130}
131
132#[derive(Debug, Clone, PartialEq, Eq)]
134pub enum Error {
135 BadFrameSize,
137
138 TooMuchPadding,
141
142 InvalidSettingValue,
144
145 InvalidWindowUpdateValue,
147
148 InvalidPayloadLength,
151
152 InvalidPayloadAckSettings,
154
155 InvalidStreamId,
160
161 MalformedMessage,
163
164 InvalidDependencyId,
169
170 Hpack(hpack::DecoderError),
172}