Reinstate read timeouts on body.
This feature was broken in #67, which reset timeouts on the stream before passing it to set_stream. As part of this change, refactor the internal storage of timeouts on the Request object to use Option<Duration>. Remove the deadline field on Response. It wasn't used. The deadline field on unit was used instead. Add a unittest.
This commit is contained in:
committed by
Martin Algesten
parent
32f9ebc04a
commit
2bf9362eff
@@ -1,7 +1,6 @@
|
||||
use std::fmt;
|
||||
use std::io::{self, Cursor, ErrorKind, Read};
|
||||
use std::str::FromStr;
|
||||
use std::time::Instant;
|
||||
|
||||
use chunked_transfer::Decoder as ChunkDecoder;
|
||||
|
||||
@@ -56,7 +55,6 @@ pub struct Response {
|
||||
headers: Vec<Header>,
|
||||
unit: Option<Unit>,
|
||||
stream: Option<Stream>,
|
||||
deadline: Option<Instant>,
|
||||
}
|
||||
|
||||
/// index into status_line where we split: HTTP/1.1 200 OK
|
||||
@@ -327,12 +325,17 @@ impl Response {
|
||||
|
||||
let stream = self.stream.expect("No reader in response?!");
|
||||
let unit = self.unit;
|
||||
if let Some(unit) = &unit {
|
||||
let result = stream.set_read_timeout(unit.req.timeout_read);
|
||||
if let Err(e) = result {
|
||||
return Box::new(ErrorReader(e)) as Box<dyn Read + Send>;
|
||||
}
|
||||
}
|
||||
let deadline = unit.as_ref().and_then(|u| u.deadline);
|
||||
let stream = DeadlineStream::new(stream, deadline);
|
||||
|
||||
match (use_chunked, limit_bytes) {
|
||||
(true, _) => Box::new(PoolReturnRead::new(unit, ChunkDecoder::new(stream)))
|
||||
as Box<dyn Read + Send>,
|
||||
(true, _) => Box::new(PoolReturnRead::new(unit, ChunkDecoder::new(stream))),
|
||||
(false, Some(len)) => {
|
||||
Box::new(PoolReturnRead::new(unit, LimitedRead::new(stream, len)))
|
||||
}
|
||||
@@ -505,7 +508,6 @@ impl Response {
|
||||
headers,
|
||||
unit: None,
|
||||
stream: None,
|
||||
deadline: None,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -585,9 +587,6 @@ impl Into<Response> for Error {
|
||||
/// *Internal API*
|
||||
pub(crate) fn set_stream(resp: &mut Response, url: String, unit: Option<Unit>, stream: Stream) {
|
||||
resp.url = Some(url);
|
||||
if let Some(unit) = &unit {
|
||||
resp.deadline = unit.deadline;
|
||||
}
|
||||
resp.unit = unit;
|
||||
resp.stream = Some(stream);
|
||||
}
|
||||
@@ -813,3 +812,14 @@ mod tests {
|
||||
assert_eq!(v, "Bad Status\n");
|
||||
}
|
||||
}
|
||||
|
||||
// ErrorReader returns an error for every read.
|
||||
// The error is as close to a clone of the underlying
|
||||
// io::Error as we can get.
|
||||
struct ErrorReader(io::Error);
|
||||
|
||||
impl Read for ErrorReader {
|
||||
fn read(&mut self, _buf: &mut [u8]) -> io::Result<usize> {
|
||||
Err(io::Error::new(self.0.kind(), self.0.to_string()))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user