1 mod support;
2 use support::*;
3
4 use std::time::Duration;
5
6 #[tokio::test]
client_timeout()7 async fn client_timeout() {
8 let _ = env_logger::try_init();
9
10 let server = server::http(move |_req| {
11 async {
12 // delay returning the response
13 tokio::time::delay_for(Duration::from_secs(2)).await;
14 http::Response::default()
15 }
16 });
17
18 let client = reqwest::Client::builder()
19 .timeout(Duration::from_millis(500))
20 .build()
21 .unwrap();
22
23 let url = format!("http://{}/slow", server.addr());
24
25 let res = client.get(&url).send().await;
26
27 let err = res.unwrap_err();
28
29 assert!(err.is_timeout());
30 assert_eq!(err.url().map(|u| u.as_str()), Some(url.as_str()));
31 }
32
33 #[tokio::test]
request_timeout()34 async fn request_timeout() {
35 let _ = env_logger::try_init();
36
37 let server = server::http(move |_req| {
38 async {
39 // delay returning the response
40 tokio::time::delay_for(Duration::from_secs(2)).await;
41 http::Response::default()
42 }
43 });
44
45 let client = reqwest::Client::builder().build().unwrap();
46
47 let url = format!("http://{}/slow", server.addr());
48
49 let res = client
50 .get(&url)
51 .timeout(Duration::from_millis(500))
52 .send()
53 .await;
54
55 let err = res.unwrap_err();
56
57 assert!(err.is_timeout());
58 assert_eq!(err.url().map(|u| u.as_str()), Some(url.as_str()));
59 }
60
61 #[tokio::test]
response_timeout()62 async fn response_timeout() {
63 let _ = env_logger::try_init();
64
65 let server = server::http(move |_req| {
66 async {
67 // immediate response, but delayed body
68 let body = hyper::Body::wrap_stream(futures_util::stream::once(async {
69 tokio::time::delay_for(Duration::from_secs(2)).await;
70 Ok::<_, std::convert::Infallible>("Hello")
71 }));
72
73 http::Response::new(body)
74 }
75 });
76
77 let client = reqwest::Client::builder()
78 .timeout(Duration::from_millis(500))
79 .build()
80 .unwrap();
81
82 let url = format!("http://{}/slow", server.addr());
83 let res = client.get(&url).send().await.expect("Failed to get");
84 let body = res.text().await;
85
86 let err = body.unwrap_err();
87
88 assert!(err.is_timeout());
89 }
90
91 /// Tests that internal client future cancels when the oneshot channel
92 /// is canceled.
93 #[cfg(feature = "blocking")]
94 #[test]
timeout_closes_connection()95 fn timeout_closes_connection() {
96 let _ = env_logger::try_init();
97
98 // Make Client drop *after* the Server, so the background doesn't
99 // close too early.
100 let client = reqwest::blocking::Client::builder()
101 .timeout(Duration::from_millis(500))
102 .build()
103 .unwrap();
104
105 let server = server::http(move |_req| {
106 async {
107 // delay returning the response
108 tokio::time::delay_for(Duration::from_secs(2)).await;
109 http::Response::default()
110 }
111 });
112
113 let url = format!("http://{}/closes", server.addr());
114 let err = client.get(&url).send().unwrap_err();
115
116 assert!(err.is_timeout());
117 assert_eq!(err.url().map(|u| u.as_str()), Some(url.as_str()));
118 }
119
120 #[cfg(feature = "blocking")]
121 #[test]
timeout_blocking_request()122 fn timeout_blocking_request() {
123 let _ = env_logger::try_init();
124
125 // Make Client drop *after* the Server, so the background doesn't
126 // close too early.
127 let client = reqwest::blocking::Client::builder().build().unwrap();
128
129 let server = server::http(move |_req| {
130 async {
131 // delay returning the response
132 tokio::time::delay_for(Duration::from_secs(2)).await;
133 http::Response::default()
134 }
135 });
136
137 let url = format!("http://{}/closes", server.addr());
138 let err = client
139 .get(&url)
140 .timeout(Duration::from_millis(500))
141 .send()
142 .unwrap_err();
143
144 assert!(err.is_timeout());
145 assert_eq!(err.url().map(|u| u.as_str()), Some(url.as_str()));
146 }
147
148 #[cfg(feature = "blocking")]
149 #[test]
write_timeout_large_body()150 fn write_timeout_large_body() {
151 let _ = env_logger::try_init();
152 let body = vec![b'x'; 20_000];
153 let len = 8192;
154
155 // Make Client drop *after* the Server, so the background doesn't
156 // close too early.
157 let client = reqwest::blocking::Client::builder()
158 .timeout(Duration::from_millis(500))
159 .build()
160 .unwrap();
161
162 let server = server::http(move |_req| {
163 async {
164 // delay returning the response
165 tokio::time::delay_for(Duration::from_secs(2)).await;
166 http::Response::default()
167 }
168 });
169
170 let cursor = std::io::Cursor::new(body);
171 let url = format!("http://{}/write-timeout", server.addr());
172 let err = client
173 .post(&url)
174 .body(reqwest::blocking::Body::sized(cursor, len as u64))
175 .send()
176 .unwrap_err();
177
178 assert!(err.is_timeout());
179 assert_eq!(err.url().map(|u| u.as_str()), Some(url.as_str()));
180 }
181