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 
28 cfg_client! {
29     pub(crate) type ClientTransaction = role::Client;
30 }
31 
32 cfg_server! {
33     pub(crate) type ServerTransaction = role::Server;
34 }
35 
36 pub(crate) trait Http1Transaction {
37     type Incoming;
38     type Outgoing: Default;
39     const LOG: &'static str;
parse(bytes: &mut BytesMut, ctx: ParseContext<'_>) -> ParseResult<Self::Incoming>40     fn parse(bytes: &mut BytesMut, ctx: ParseContext<'_>) -> ParseResult<Self::Incoming>;
encode(enc: Encode<'_, Self::Outgoing>, dst: &mut Vec<u8>) -> crate::Result<Encoder>41     fn encode(enc: Encode<'_, Self::Outgoing>, dst: &mut Vec<u8>) -> crate::Result<Encoder>;
42 
on_error(err: &crate::Error) -> Option<MessageHead<Self::Outgoing>>43     fn on_error(err: &crate::Error) -> Option<MessageHead<Self::Outgoing>>;
44 
is_client() -> bool45     fn is_client() -> bool {
46         !Self::is_server()
47     }
48 
is_server() -> bool49     fn is_server() -> bool {
50         !Self::is_client()
51     }
52 
should_error_on_parse_eof() -> bool53     fn should_error_on_parse_eof() -> bool {
54         Self::is_client()
55     }
56 
should_read_first() -> bool57     fn should_read_first() -> bool {
58         Self::is_server()
59     }
60 
update_date()61     fn update_date() {}
62 }
63 
64 /// Result newtype for Http1Transaction::parse.
65 pub(crate) type ParseResult<T> = Result<Option<ParsedMessage<T>>, crate::error::Parse>;
66 
67 #[derive(Debug)]
68 pub(crate) struct ParsedMessage<T> {
69     head: MessageHead<T>,
70     decode: DecodedLength,
71     expect_continue: bool,
72     keep_alive: bool,
73     wants_upgrade: bool,
74 }
75 
76 pub(crate) struct ParseContext<'a> {
77     cached_headers: &'a mut Option<HeaderMap>,
78     req_method: &'a mut Option<Method>,
79     h1_parser_config: ParserConfig,
80     #[cfg(all(feature = "server", feature = "runtime"))]
81     h1_header_read_timeout: Option<Duration>,
82     #[cfg(all(feature = "server", feature = "runtime"))]
83     h1_header_read_timeout_fut: &'a mut Option<Pin<Box<Sleep>>>,
84     #[cfg(all(feature = "server", feature = "runtime"))]
85     h1_header_read_timeout_running: &'a mut bool,
86     preserve_header_case: bool,
87     h09_responses: bool,
88     #[cfg(feature = "ffi")]
89     on_informational: &'a mut Option<crate::ffi::OnInformational>,
90     #[cfg(feature = "ffi")]
91     raw_headers: bool,
92 }
93 
94 /// Passed to Http1Transaction::encode
95 pub(crate) struct Encode<'a, T> {
96     head: &'a mut MessageHead<T>,
97     body: Option<BodyLength>,
98     #[cfg(feature = "server")]
99     keep_alive: bool,
100     req_method: &'a mut Option<Method>,
101     title_case_headers: bool,
102 }
103 
104 /// Extra flags that a request "wants", like expect-continue or upgrades.
105 #[derive(Clone, Copy, Debug)]
106 struct Wants(u8);
107 
108 impl Wants {
109     const EMPTY: Wants = Wants(0b00);
110     const EXPECT: Wants = Wants(0b01);
111     const UPGRADE: Wants = Wants(0b10);
112 
113     #[must_use]
add(self, other: Wants) -> Wants114     fn add(self, other: Wants) -> Wants {
115         Wants(self.0 | other.0)
116     }
117 
contains(&self, other: Wants) -> bool118     fn contains(&self, other: Wants) -> bool {
119         (self.0 & other.0) == other.0
120     }
121 }
122