1 use bytes::BytesMut; 2 use http::{HeaderMap, Method}; 3 use httparse::ParserConfig; 4 5 use crate::body::DecodedLength; 6 use crate::proto::{BodyLength, MessageHead}; 7 8 pub(crate) use self::conn::Conn; 9 pub(crate) use self::decode::Decoder; 10 pub(crate) use self::dispatch::Dispatcher; 11 pub(crate) use self::encode::{EncodedBuf, Encoder}; 12 //TODO: move out of h1::io 13 pub(crate) use self::io::MINIMUM_MAX_BUFFER_SIZE; 14 15 mod conn; 16 mod decode; 17 pub(crate) mod dispatch; 18 mod encode; 19 mod io; 20 mod role; 21 22 23 cfg_client! { 24 pub(crate) type ClientTransaction = role::Client; 25 } 26 27 cfg_server! { 28 pub(crate) type ServerTransaction = role::Server; 29 } 30 31 pub(crate) trait Http1Transaction { 32 type Incoming; 33 type Outgoing: Default; 34 const LOG: &'static str; parse(bytes: &mut BytesMut, ctx: ParseContext<'_>) -> ParseResult<Self::Incoming>35 fn parse(bytes: &mut BytesMut, ctx: ParseContext<'_>) -> ParseResult<Self::Incoming>; encode(enc: Encode<'_, Self::Outgoing>, dst: &mut Vec<u8>) -> crate::Result<Encoder>36 fn encode(enc: Encode<'_, Self::Outgoing>, dst: &mut Vec<u8>) -> crate::Result<Encoder>; 37 on_error(err: &crate::Error) -> Option<MessageHead<Self::Outgoing>>38 fn on_error(err: &crate::Error) -> Option<MessageHead<Self::Outgoing>>; 39 is_client() -> bool40 fn is_client() -> bool { 41 !Self::is_server() 42 } 43 is_server() -> bool44 fn is_server() -> bool { 45 !Self::is_client() 46 } 47 should_error_on_parse_eof() -> bool48 fn should_error_on_parse_eof() -> bool { 49 Self::is_client() 50 } 51 should_read_first() -> bool52 fn should_read_first() -> bool { 53 Self::is_server() 54 } 55 update_date()56 fn update_date() {} 57 } 58 59 /// Result newtype for Http1Transaction::parse. 60 pub(crate) type ParseResult<T> = Result<Option<ParsedMessage<T>>, crate::error::Parse>; 61 62 #[derive(Debug)] 63 pub(crate) struct ParsedMessage<T> { 64 head: MessageHead<T>, 65 decode: DecodedLength, 66 expect_continue: bool, 67 keep_alive: bool, 68 wants_upgrade: bool, 69 } 70 71 pub(crate) struct ParseContext<'a> { 72 cached_headers: &'a mut Option<HeaderMap>, 73 req_method: &'a mut Option<Method>, 74 h1_parser_config: ParserConfig, 75 preserve_header_case: bool, 76 h09_responses: bool, 77 #[cfg(feature = "ffi")] 78 on_informational: &'a mut Option<crate::ffi::OnInformational>, 79 #[cfg(feature = "ffi")] 80 raw_headers: bool, 81 } 82 83 /// Passed to Http1Transaction::encode 84 pub(crate) struct Encode<'a, T> { 85 head: &'a mut MessageHead<T>, 86 body: Option<BodyLength>, 87 #[cfg(feature = "server")] 88 keep_alive: bool, 89 req_method: &'a mut Option<Method>, 90 title_case_headers: bool, 91 } 92 93 /// Extra flags that a request "wants", like expect-continue or upgrades. 94 #[derive(Clone, Copy, Debug)] 95 struct Wants(u8); 96 97 impl Wants { 98 const EMPTY: Wants = Wants(0b00); 99 const EXPECT: Wants = Wants(0b01); 100 const UPGRADE: Wants = Wants(0b10); 101 102 #[must_use] add(self, other: Wants) -> Wants103 fn add(self, other: Wants) -> Wants { 104 Wants(self.0 | other.0) 105 } 106 contains(&self, other: Wants) -> bool107 fn contains(&self, other: Wants) -> bool { 108 (self.0 & other.0) == other.0 109 } 110 } 111