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