1use crate::{
7 Conn, Error, HttpContext, Upgrade,
8 conn::{ConnInner, H1Status, HeadError},
9 graceful_close::GracefulClose,
10};
11use futures_lite::io::{AsyncRead, AsyncWrite};
12use std::{
13 fmt::{self, Debug, Formatter},
14 future::Future,
15 pin::Pin,
16 sync::Arc,
17 task::{Context, Poll},
18};
19
20pub struct H1Connection<Transport> {
25 context: Arc<HttpContext>,
26 transport: Transport,
27 initial_bytes: Option<Vec<u8>>,
28}
29
30impl<Transport> Debug for H1Connection<Transport> {
31 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
32 f.debug_struct("H1Connection")
33 .field("initial_bytes", &self.initial_bytes.as_ref().map(Vec::len))
34 .finish_non_exhaustive()
35 }
36}
37
38impl<Transport> H1Connection<Transport> {
39 pub fn new(context: Arc<HttpContext>, transport: Transport) -> Self {
41 Self {
42 context,
43 transport,
44 initial_bytes: None,
45 }
46 }
47
48 #[must_use]
52 pub fn with_initial_bytes(mut self, initial_bytes: Vec<u8>) -> Self {
53 self.initial_bytes = Some(initial_bytes);
54 self
55 }
56}
57
58impl<Transport> H1Connection<Transport>
59where
60 Transport: AsyncRead + AsyncWrite + Unpin + Send + Sync + 'static,
61{
62 pub async fn run<Handler, Fut>(self, mut handler: Handler) -> H1ConnectionResult<Transport>
65 where
66 Handler: FnMut(Conn<Transport>) -> Fut,
67 Fut: Future<Output = Conn<Transport>>,
68 {
69 let Self {
70 context,
71 transport,
72 initial_bytes,
73 } = self;
74 let initial_bytes = initial_bytes
75 .unwrap_or_else(|| Vec::with_capacity(context.config.request_buffer_initial_len));
76 let _guard = context.swansong.guard();
77
78 let mut status = match Conn::new_h1(context, transport, initial_bytes).await {
79 Ok(conn) => Ok(H1Status::Conn(conn)),
80 Err(HeadError::BadRequest(bad)) => bad.send().await,
81 Err(HeadError::Fatal(error)) => Err(error),
82 };
83
84 loop {
85 status = match status {
86 Ok(H1Status::Conn(conn)) => handler(conn).await.send().await,
87 Ok(H1Status::Upgrade(upgrade)) => return H1ConnectionResult::Upgrade(upgrade),
88 Ok(H1Status::Close(conn)) => return H1ConnectionResult::Close(H1Close::new(conn)),
89 Ok(H1Status::Ended(conn)) => {
90 return H1ConnectionResult::Close(H1Close::finished(conn));
91 }
92 Err(error) => return H1ConnectionResult::Error(error),
93 };
94 }
95 }
96}
97
98#[derive(Debug)]
100#[must_use]
101#[non_exhaustive]
102pub enum H1ConnectionResult<Transport> {
103 Upgrade(Upgrade<Transport>),
105
106 Close(H1Close<Transport>),
109
110 Error(Error),
113}
114
115impl<Transport> H1ConnectionResult<Transport> {
116 pub(crate) fn into_upgrade(self) -> crate::Result<Option<Upgrade<Transport>>> {
118 match self {
119 Self::Upgrade(upgrade) => Ok(Some(upgrade)),
120 Self::Close(_) => Ok(None),
121 Self::Error(error) => Err(error),
122 }
123 }
124}
125
126pub struct H1Close<Transport>(GracefulClose<Transport>);
136
137impl<Transport> Debug for H1Close<Transport> {
138 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
139 f.debug_tuple("H1Close").finish_non_exhaustive()
140 }
141}
142
143impl<Transport> H1Close<Transport> {
144 fn new(conn: Conn<Transport>) -> Self {
145 let Conn { inner, transport } = conn;
146 let ConnInner {
147 buffer, context, ..
148 } = *inner;
149 Self(GracefulClose::new(
150 transport,
151 buffer.into(),
152 context.config.copy_loops_per_yield,
153 ))
154 }
155
156 fn finished(conn: Conn<Transport>) -> Self {
157 Self(GracefulClose::finished(conn.transport))
158 }
159}
160
161impl<Transport> Future for H1Close<Transport>
162where
163 Transport: AsyncRead + AsyncWrite + Unpin,
164{
165 type Output = ();
166
167 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> {
168 Pin::new(&mut self.get_mut().0).poll(cx)
169 }
170}