Retry some pooled connections failing when server closes. Close #10

This is not a perfect solution. It works as long as we are not sending
any body bytes. We discover the error first when attempting to read
the response status line. That means we discover the error after
sending body bytes. To be able to re-send the body, we would need to
introduce a buffer to be able to replay the body on the next
request. We don't currently do that.
This commit is contained in:
Martin Algesten
2019-10-20 21:32:19 +02:00
parent 1264213ca6
commit 753d61b454
5 changed files with 64 additions and 8 deletions

View File

@@ -144,11 +144,23 @@ pub(crate) fn connect(
}
// send the body (which can be empty now depending on redirects)
body::send_body(body, unit.is_chunked, &mut stream)?;
let body_bytes_sent = body::send_body(body, unit.is_chunked, &mut stream)?;
// start reading the response to process cookies and redirects.
let mut resp = Response::from_read(&mut stream);
if let Some(err) = resp.synthetic_error() {
if err.is_bad_status_read() && body_bytes_sent == 0 && is_recycled {
// We try open a new connection, this happens if the remote server
// hangs a pooled connection and we only discover when trying to
// read from it. It's however only possible if we didn't send any
// body bytes. This is because we currently don't want to buffer
// any body to be able to replay it.
let empty = Payload::Empty.into_read();
return connect(req, unit, false, redirect_count, empty, redir);
}
}
// squirrel away cookies
if cfg!(feature = "cookies") {
save_cookies(&unit, &resp);