Skip to main content

xitca_http/h1/
service.rs

1use core::{net::SocketAddr, pin::pin};
2
3use crate::body::Body;
4use xitca_io::io::{AsyncBufRead, AsyncBufWrite};
5use xitca_service::Service;
6
7use crate::{
8    body::RequestBody,
9    builder::marker,
10    bytes::Bytes,
11    error::{HttpServiceError, TimeoutError},
12    http::{Request, RequestExt, Response},
13    service::HttpService,
14    util::timer::Timeout,
15};
16
17pub type H1Service<St, Io, S, A, const HEADER_LIMIT: usize, const READ_BUF_LIMIT: usize, const WRITE_BUF_LIMIT: usize> =
18    HttpService<marker::Http1, Io, St, S, A, HEADER_LIMIT, READ_BUF_LIMIT, WRITE_BUF_LIMIT>;
19
20impl<St, Io, S, B, A, const HEADER_LIMIT: usize, const READ_BUF_LIMIT: usize, const WRITE_BUF_LIMIT: usize>
21    Service<(St, SocketAddr)> for H1Service<St, Io, S, A, HEADER_LIMIT, READ_BUF_LIMIT, WRITE_BUF_LIMIT>
22where
23    S: Service<Request<RequestExt<RequestBody>>, Response = Response<B>>,
24    A: Service<St>,
25    A::Response: AsyncBufRead + AsyncBufWrite + 'static,
26    B: Body<Data = Bytes>,
27    HttpServiceError<S::Error, B::Error>: From<A::Error>,
28{
29    type Response = ();
30    type Error = HttpServiceError<S::Error, B::Error>;
31
32    async fn call(&self, (io, addr): (St, SocketAddr)) -> Result<Self::Response, Self::Error> {
33        // at this stage keep-alive timer is used to tracks tls accept timeout.
34        let mut timer = pin!(self.keep_alive());
35
36        let io = self
37            .tls_acceptor
38            .call(io)
39            .timeout(timer.as_mut())
40            .await
41            .map_err(|_| HttpServiceError::Timeout(TimeoutError::TlsAccept))??;
42
43        super::Dispatcher::run(
44            io,
45            addr,
46            crate::bytes::BytesMut::new(),
47            timer,
48            self.config,
49            &self.service,
50            self.date.get(),
51        )
52        .await
53        .map_err(Into::into)
54    }
55}