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