1
1
use futures:: { ready, Stream } ;
2
2
use hyper:: {
3
3
body:: { Bytes , HttpBody } ,
4
- client:: { connect:: Connect , ResponseFuture } ,
4
+ client:: {
5
+ connect:: { Connect , Connection } ,
6
+ ResponseFuture ,
7
+ } ,
5
8
header:: { HeaderMap , HeaderName , HeaderValue } ,
9
+ service:: Service ,
6
10
Body , Request , StatusCode , Uri ,
7
11
} ;
8
12
#[ cfg( feature = "rustls" ) ]
@@ -19,18 +23,25 @@ use std::{
19
23
task:: { Context , Poll } ,
20
24
time:: Duration ,
21
25
} ;
22
- use tokio:: time:: Sleep ;
26
+
27
+ use tokio:: {
28
+ io:: { AsyncRead , AsyncWrite } ,
29
+ time:: Sleep ,
30
+ } ;
23
31
24
32
use super :: config:: ReconnectOptions ;
25
33
use super :: decode:: Decoded ;
26
34
use super :: error:: { Error , Result } ;
27
35
28
36
use crate :: Event ;
29
37
pub use hyper:: client:: HttpConnector ;
38
+ use hyper_timeout:: TimeoutConnector ;
30
39
31
40
#[ cfg( feature = "rustls" ) ]
32
41
pub type HttpsConnector = RustlsConnector < HttpConnector > ;
33
42
43
+ type BoxError = Box < dyn std:: error:: Error + Send + Sync > ;
44
+
34
45
/// Represents a [`Pin`]'d [`Send`] + [`Sync`] stream, returned by [`Client`]'s stream method.
35
46
pub type BoxStream < T > = Pin < boxed:: Box < dyn Stream < Item = T > + Send + Sync > > ;
36
47
@@ -51,6 +62,7 @@ pub struct ClientBuilder {
51
62
url : Uri ,
52
63
headers : HeaderMap ,
53
64
reconnect_opts : ReconnectOptions ,
65
+ read_timeout : Option < Duration > ,
54
66
}
55
67
56
68
impl ClientBuilder {
@@ -63,6 +75,7 @@ impl ClientBuilder {
63
75
url,
64
76
headers : HeaderMap :: new ( ) ,
65
77
reconnect_opts : ReconnectOptions :: default ( ) ,
78
+ read_timeout : None ,
66
79
} )
67
80
}
68
81
@@ -78,6 +91,12 @@ impl ClientBuilder {
78
91
Ok ( self )
79
92
}
80
93
94
+ /// Set a read timeout for the underlying connection. There is no read timeout by default.
95
+ pub fn read_timeout ( mut self , read_timeout : Duration ) -> ClientBuilder {
96
+ self . read_timeout = Some ( read_timeout) ;
97
+ self
98
+ }
99
+
81
100
/// Configure the client's reconnect behaviour according to the supplied
82
101
/// [`ReconnectOptions`].
83
102
///
@@ -90,10 +109,18 @@ impl ClientBuilder {
90
109
/// Build with a specific client connector.
91
110
pub fn build_with_conn < C > ( self , conn : C ) -> impl Client
92
111
where
93
- C : Connect + Clone + Send + Sync + ' static ,
112
+ C : Service < Uri > + Clone + Send + Sync + ' static ,
113
+ C :: Response : Connection + AsyncRead + AsyncWrite + Send + Unpin ,
114
+ C :: Future : Send + ' static ,
115
+ C :: Error : Into < BoxError > ,
94
116
{
117
+ let mut connector = TimeoutConnector :: new ( conn) ;
118
+ connector. set_read_timeout ( self . read_timeout ) ;
119
+
120
+ let client = hyper:: Client :: builder ( ) . build :: < _ , hyper:: Body > ( connector) ;
121
+
95
122
ClientImpl {
96
- http : hyper :: Client :: builder ( ) . build ( conn ) ,
123
+ http : client ,
97
124
request_props : RequestProps {
98
125
url : self . url ,
99
126
headers : self . headers ,
0 commit comments