monolake_core/http/mod.rs
1//! HTTP handling traits and types for asynchronous services.
2//!
3//! This module provides traits and types for implementing HTTP handlers
4//! that can be used with asynchronous services. It defines a common interface
5//! for processing HTTP requests and generating responses, with support for
6//! connection management and context-aware handling.
7//!
8//! # Key Components
9//!
10//! - [`HttpHandler`]: A trait for implementing HTTP request handlers.
11//! - [`ResponseWithContinue`]: A type alias for responses that indicate whether to continue
12//! processing the connection.
13//! - [`HttpAccept`]: A type alias for connection acceptance information.
14//!
15//! # Usage
16//!
17//! The `HttpHandler` trait is automatically implemented for types
18//! that implement the [`Service`] trait with
19//! request type `(Request<B>, CX)` and return type
20//! [`ResponseWithContinue`].
21use std::future::Future;
22
23use http::{Request, Response};
24use service_async::Service;
25
26use crate::sealed::SealedT;
27
28/// A tuple representing an HTTP response along with a connection continuation flag.
29///
30/// # Type Parameters
31///
32/// - `B`: The body type of the response.
33///
34/// # Fields
35///
36/// - `Response<B>`: The HTTP response.
37/// - `bool`: A flag indicating whether to continue processing the connection.
38/// - `true`: Continue processing the connection.
39/// - `false`: Close the connection after sending the response.
40///
41/// Note: The service does not need to add the `Connection: close` header itself;
42/// this is handled by the HTTP core service based on this flag.
43pub type ResponseWithContinue<B> = (Response<B>, bool);
44
45/// A tuple representing an accepted HTTP connection with its context.
46///
47/// # Type Parameters
48///
49/// - `Stream`: The type of the I/O stream for the connection.
50/// - `CX`: The type of the connection context, typically a `certain_map`.
51///
52/// # Fields
53///
54/// - `bool`: Indicates whether the connection is using HTTP/2.
55/// - `true`: The connection is using HTTP/2.
56/// - `false`: The connection is using HTTP/1.x.
57/// - `Stream`: The I/O stream for the connection.
58/// - `CX`: The context of the connection, providing additional information or state.
59pub type HttpAccept<Stream, CX> = (bool, Stream, CX);
60
61struct HttpSeal;
62
63/// A trait for HTTP request handlers.
64///
65/// This trait defines the interface for processing HTTP requests and generating responses.
66/// It is designed to work with asynchronous services and supports context-aware handling.
67///
68/// Implementors of this trait can process HTTP requests and return responses along with
69/// a boolean flag indicating whether to continue processing the connection.
70///
71/// # Type Parameters
72///
73/// - `CX`: The context type for additional request processing information.
74/// - `B`: The body type of the incoming request.
75///
76/// # Associated Types
77///
78/// - `Body`: The body type of the outgoing response.
79/// - `Error`: The error type that may occur during request handling.
80///
81/// # Examples
82///
83/// ```ignore
84/// use your_crate::{HttpHandler, ResponseWithContinue};
85/// use http::{Request, Response};
86///
87/// struct MyHandler;
88///
89/// impl HttpHandler<(), Vec<u8>> for MyHandler {
90/// type Body = Vec<u8>;
91/// type Error = std::io::Error;
92///
93/// async fn handle(&self, request: Request<Vec<u8>>, ctx: ())
94/// -> Result<ResponseWithContinue<Self::Body>, Self::Error> {
95/// // Process the request and generate a response
96/// let response = Response::new(Vec::new());
97/// Ok((response, true))
98/// }
99/// }
100/// ```
101///
102/// The [`HttpHandler`] trait is automatically implemented for types
103/// that implement the [`Service`] trait with
104/// request type `(Request<B>, CX)` and return type
105/// [`ResponseWithContinue`].
106#[allow(private_bounds)]
107pub trait HttpHandler<CX, B>: SealedT<HttpSeal, (CX, B)> {
108 type Body;
109 type Error;
110
111 fn handle(
112 &self,
113 request: Request<B>,
114 ctx: CX,
115 ) -> impl Future<Output = Result<ResponseWithContinue<Self::Body>, Self::Error>>;
116}
117
118impl<T, CX, IB, OB> SealedT<HttpSeal, (CX, IB)> for T where
119 T: Service<(Request<IB>, CX), Response = ResponseWithContinue<OB>>
120{
121}
122
123impl<T, CX, IB, OB> HttpHandler<CX, IB> for T
124where
125 T: Service<(Request<IB>, CX), Response = ResponseWithContinue<OB>>,
126{
127 type Body = OB;
128 type Error = T::Error;
129
130 async fn handle(
131 &self,
132 req: Request<IB>,
133 ctx: CX,
134 ) -> Result<ResponseWithContinue<OB>, Self::Error> {
135 self.call((req, ctx)).await
136 }
137}