1 use super::StreamId; 2 3 use bytes::BufMut; 4 5 #[derive(Debug, Copy, Clone, PartialEq, Eq)] 6 pub struct Head { 7 kind: Kind, 8 flag: u8, 9 stream_id: StreamId, 10 } 11 12 #[repr(u8)] 13 #[derive(Debug, Copy, Clone, PartialEq, Eq)] 14 pub enum Kind { 15 Data = 0, 16 Headers = 1, 17 Priority = 2, 18 Reset = 3, 19 Settings = 4, 20 PushPromise = 5, 21 Ping = 6, 22 GoAway = 7, 23 WindowUpdate = 8, 24 Continuation = 9, 25 Unknown, 26 } 27 28 // ===== impl Head ===== 29 30 impl Head { new(kind: Kind, flag: u8, stream_id: StreamId) -> Head31 pub fn new(kind: Kind, flag: u8, stream_id: StreamId) -> Head { 32 Head { 33 kind, 34 flag, 35 stream_id, 36 } 37 } 38 39 /// Parse an HTTP/2 frame header parse(header: &[u8]) -> Head40 pub fn parse(header: &[u8]) -> Head { 41 let (stream_id, _) = StreamId::parse(&header[5..]); 42 43 Head { 44 kind: Kind::new(header[3]), 45 flag: header[4], 46 stream_id, 47 } 48 } 49 stream_id(&self) -> StreamId50 pub fn stream_id(&self) -> StreamId { 51 self.stream_id 52 } 53 kind(&self) -> Kind54 pub fn kind(&self) -> Kind { 55 self.kind 56 } 57 flag(&self) -> u858 pub fn flag(&self) -> u8 { 59 self.flag 60 } 61 encode_len(&self) -> usize62 pub fn encode_len(&self) -> usize { 63 super::HEADER_LEN 64 } 65 encode<T: BufMut>(&self, payload_len: usize, dst: &mut T)66 pub fn encode<T: BufMut>(&self, payload_len: usize, dst: &mut T) { 67 debug_assert!(self.encode_len() <= dst.remaining_mut()); 68 69 dst.put_uint(payload_len as u64, 3); 70 dst.put_u8(self.kind as u8); 71 dst.put_u8(self.flag); 72 dst.put_u32(self.stream_id.into()); 73 } 74 } 75 76 // ===== impl Kind ===== 77 78 impl Kind { new(byte: u8) -> Kind79 pub fn new(byte: u8) -> Kind { 80 match byte { 81 0 => Kind::Data, 82 1 => Kind::Headers, 83 2 => Kind::Priority, 84 3 => Kind::Reset, 85 4 => Kind::Settings, 86 5 => Kind::PushPromise, 87 6 => Kind::Ping, 88 7 => Kind::GoAway, 89 8 => Kind::WindowUpdate, 90 9 => Kind::Continuation, 91 _ => Kind::Unknown, 92 } 93 } 94 } 95