1- //! todo
1+ //! Tower layers and services for HTTP/1 and HTTP/2 client connections.
2+ //!
3+ //! This module provides Tower-compatible layers that wrap Hyper's low-level
4+ //! HTTP client connection types, making them easier to compose with other
5+ //! middleware and connection pooling strategies.
26
37use std:: future:: Future ;
48use std:: marker:: PhantomData ;
@@ -12,14 +16,39 @@ use crate::common::future::poll_fn;
1216
1317type BoxError = Box < dyn std:: error:: Error + Send + Sync > ;
1418
15- /// todo
19+ /// A Tower [`Layer`](tower_layer::Layer) for creating HTTP/1 client connections.
20+ ///
21+ /// This layer wraps a connection service (typically a TCP or TLS connector) and
22+ /// performs the HTTP/1 handshake, producing an [`Http1ClientService`] that can
23+ /// send requests.
24+ ///
25+ /// Use [`http1()`] to create a layer with default settings, or construct from
26+ /// a [`hyper::client::conn::http1::Builder`] for custom configuration.
27+ ///
28+ /// # Example
29+ ///
30+ /// ```ignore
31+ /// use hyper_util::client::conn::http1;
32+ /// use hyper::{client::connect::HttpConnector, body::Bytes};
33+ /// use tower:: ServiceBuilder;
34+ /// use http_body_util::Empty;
35+ ///
36+ /// let connector = HttpConnector::new();
37+ /// let layer: Http1Layer<Empty<Bytes>> = http1();
38+ /// let client = ServiceBuilder::new()
39+ /// .layer(layer)
40+ /// .service(connector);
41+ /// ```
1642#[ cfg( feature = "http1" ) ]
1743pub struct Http1Layer < B > {
1844 builder : hyper:: client:: conn:: http1:: Builder ,
1945 _body : PhantomData < fn ( B ) > ,
2046}
2147
22- /// todo
48+ /// Creates an [`Http1Layer`] with default HTTP/1 settings.
49+ ///
50+ /// For custom settings, construct an [`Http1Layer`] from a
51+ /// [`hyper::client::conn::http1::Builder`] using `.into()`.
2352#[ cfg( feature = "http1" ) ]
2453pub fn http1 < B > ( ) -> Http1Layer < B > {
2554 Http1Layer {
@@ -60,7 +89,11 @@ impl<B> From<hyper::client::conn::http1::Builder> for Http1Layer<B> {
6089 }
6190}
6291
63- /// todo
92+ /// A Tower [`Service`] that establishes HTTP/1 connections.
93+ ///
94+ /// This service wraps an underlying connection service (e.g., TCP or TLS) and
95+ /// performs the HTTP/1 handshake when called. The resulting service can be used
96+ /// to send HTTP requests over the established connection.
6497#[ cfg( feature = "http1" ) ]
6598pub struct Http1Connect < M , B > {
6699 inner : M ,
@@ -118,21 +151,56 @@ impl<M: Clone, B> Clone for Http1Connect<M, B> {
118151 }
119152}
120153
121- /// todo
154+ /// A Tower [`Layer`](tower_layer::Layer) for creating HTTP/2 client connections.
155+ ///
156+ /// This layer wraps a connection service (typically a TCP or TLS connector) and
157+ /// performs the HTTP/2 handshake, producing an [`Http2ClientService`] that can
158+ /// send requests.
159+ ///
160+ /// Use [`http2()`] to create a layer with a specific executor, or construct from
161+ /// a [`hyper::client::conn::http2::Builder`] for custom configuration.
162+ ///
163+ /// # Example
164+ ///
165+ /// ```ignore
166+ /// use hyper_util::client::conn::http2;
167+ /// use hyper::{client::connect::HttpConnector, body::Bytes};
168+ /// use tower:: ServiceBuilder;
169+ /// use http_body_util::Empty;
170+ ///
171+ /// let connector = HttpConnector::new();
172+ /// let layer: Http2Layer<Empty<Bytes>> = http2();
173+ /// let client = ServiceBuilder::new()
174+ /// .layer(layer)
175+ /// .service(connector);
176+ /// ```
122177#[ cfg( feature = "http2" ) ]
123- pub struct Http2Layer < B > {
178+ pub struct Http2Layer < B , E > {
179+ builder : hyper:: client:: conn:: http2:: Builder < E > ,
124180 _body : PhantomData < fn ( B ) > ,
125181}
126182
127- /// todo
183+ /// Creates an [`Http2Layer`] with default HTTP/1 settings.
184+ ///
185+ /// For custom settings, construct an [`Http2Layer`] from a
186+ /// [`hyper::client::conn::http2::Builder`] using `.into()`.
128187#[ cfg( feature = "http2" ) ]
129- pub fn http2 < B > ( ) -> Http2Layer < B > {
130- Http2Layer { _body : PhantomData }
188+ pub fn http2 < B , E > ( executor : E ) -> Http2Layer < B , E >
189+ where
190+ E : Clone ,
191+ {
192+ Http2Layer {
193+ builder : hyper:: client:: conn:: http2:: Builder :: new ( executor) ,
194+ _body : PhantomData ,
195+ }
131196}
132197
133198#[ cfg( feature = "http2" ) ]
134- impl < M , B > tower_layer:: Layer < M > for Http2Layer < B > {
135- type Service = Http2Connect < M , B > ;
199+ impl < M , B , E > tower_layer:: Layer < M > for Http2Layer < B , E >
200+ where
201+ E : Clone ,
202+ {
203+ type Service = Http2Connect < M , B , E > ;
136204 fn layer ( & self , inner : M ) -> Self :: Service {
137205 Http2Connect {
138206 inner,
@@ -143,25 +211,40 @@ impl<M, B> tower_layer::Layer<M> for Http2Layer<B> {
143211}
144212
145213#[ cfg( feature = "http2" ) ]
146- impl < B > Clone for Http2Layer < B > {
214+ impl < B , E : Clone > Clone for Http2Layer < B , E > {
147215 fn clone ( & self ) -> Self {
148216 Self {
217+ builder : self . builder . clone ( ) ,
149218 _body : self . _body . clone ( ) ,
150219 }
151220 }
152221}
153222
154- /// todo
223+ #[ cfg( feature = "http2" ) ]
224+ impl < B , E > From < hyper:: client:: conn:: http2:: Builder < E > > for Http2Layer < B , E > {
225+ fn from ( builder : hyper:: client:: conn:: http2:: Builder < E > ) -> Self {
226+ Self {
227+ builder,
228+ _body : PhantomData ,
229+ }
230+ }
231+ }
232+
233+ /// A Tower [`Service`] that establishes HTTP/2 connections.
234+ ///
235+ /// This service wraps an underlying connection service (e.g., TCP or TLS) and
236+ /// performs the HTTP/2 handshake when called. The resulting service can be used
237+ /// to send HTTP requests over the established connection.
155238#[ cfg( feature = "http2" ) ]
156239#[ derive( Debug ) ]
157- pub struct Http2Connect < M , B > {
240+ pub struct Http2Connect < M , B , E > {
158241 inner : M ,
159- builder : hyper:: client:: conn:: http2:: Builder < crate :: rt :: TokioExecutor > ,
242+ builder : hyper:: client:: conn:: http2:: Builder < E > ,
160243 _body : PhantomData < fn ( B ) > ,
161244}
162245
163246#[ cfg( feature = "http2" ) ]
164- impl < M , Dst , B > Service < Dst > for Http2Connect < M , B >
247+ impl < M , Dst , B , E > Service < Dst > for Http2Connect < M , B , E >
165248where
166249 M : Service < Dst > ,
167250 M :: Future : Send + ' static ,
@@ -170,6 +253,7 @@ where
170253 B : hyper:: body:: Body + Unpin + Send + ' static ,
171254 B :: Data : Send + ' static ,
172255 B :: Error : Into < BoxError > ,
256+ E : hyper:: rt:: bounds:: Http2ClientConnExec < B , M :: Response > + Unpin + Clone + Send + ' static ,
173257{
174258 type Response = Http2ClientService < B > ;
175259 type Error = BoxError ;
@@ -199,7 +283,7 @@ where
199283}
200284
201285#[ cfg( feature = "http2" ) ]
202- impl < M : Clone , B > Clone for Http2Connect < M , B > {
286+ impl < M : Clone , B , E : Clone > Clone for Http2Connect < M , B , E > {
203287 fn clone ( & self ) -> Self {
204288 Self {
205289 inner : self . inner . clone ( ) ,
@@ -209,7 +293,14 @@ impl<M: Clone, B> Clone for Http2Connect<M, B> {
209293 }
210294}
211295
212- /// A thin adapter over hyper HTTP/1 client SendRequest.
296+ /// A Tower [`Service`] that sends HTTP/1 requests over an established connection.
297+ ///
298+ /// This is a thin wrapper around [`hyper::client::conn::http1::SendRequest`] that implements
299+ /// the Tower `Service` trait, making it composable with other Tower middleware.
300+ ///
301+ /// The service maintains a single HTTP/1 connection and can be used to send multiple
302+ /// sequential requests. For concurrent requests or connection pooling, wrap this service
303+ /// with appropriate middleware.
213304#[ cfg( feature = "http1" ) ]
214305#[ derive( Debug ) ]
215306pub struct Http1ClientService < B > {
@@ -218,7 +309,10 @@ pub struct Http1ClientService<B> {
218309
219310#[ cfg( feature = "http1" ) ]
220311impl < B > Http1ClientService < B > {
221- /// todo
312+ /// Constructs a new HTTP/1 client service from a Hyper `SendRequest`.
313+ ///
314+ /// Typically you won't call this directly; instead, use [`Http1Connect`] to
315+ /// establish connections and produce this service.
222316 pub fn new ( tx : hyper:: client:: conn:: http1:: SendRequest < B > ) -> Self {
223317 Self { tx }
224318 }
@@ -248,7 +342,14 @@ where
248342 }
249343}
250344
251- /// todo
345+ /// A Tower [`Service`] that sends HTTP/2 requests over an established connection.
346+ ///
347+ /// This is a thin wrapper around [`hyper::client::conn::http2::SendRequest`] that implements
348+ /// the Tower `Service` trait, making it composable with other Tower middleware.
349+ ///
350+ /// The service maintains a single HTTP/2 connection and supports multiplexing multiple
351+ /// concurrent requests over that connection. The service can be cloned to send requests
352+ /// concurrently, or used with the [`Singleton`](crate::client::pool::singleton::Singleton) pool service.
252353#[ cfg( feature = "http2" ) ]
253354#[ derive( Debug ) ]
254355pub struct Http2ClientService < B > {
@@ -257,7 +358,10 @@ pub struct Http2ClientService<B> {
257358
258359#[ cfg( feature = "http2" ) ]
259360impl < B > Http2ClientService < B > {
260- /// todo
361+ /// Constructs a new HTTP/2 client service from a Hyper `SendRequest`.
362+ ///
363+ /// Typically you won't call this directly; instead, use [`Http2Connect`] to
364+ /// establish connections and produce this service.
261365 pub fn new ( tx : hyper:: client:: conn:: http2:: SendRequest < B > ) -> Self {
262366 Self { tx }
263367 }
0 commit comments