Handle ConnectionReset+ConnectionAbort at any time (#168)
Previously we had a special case for BadStatusRead that would happen only when we got a ConnectionAborted error reading the status line. However, sometimes we get ConnectionReset instead. Also the HTTP spec says that idempotent requests may be retried anytime a connection is closed prematurely. The change treats as retryable any ConnectionAborted OR ConnectionReset error while reading the status line and headers. It removes the special case BadStatusRead error. Fixes #165 (I think).
This commit is contained in:
committed by
GitHub
parent
065b560dfb
commit
17d7e147eb
16
src/error.rs
16
src/error.rs
@@ -1,5 +1,5 @@
|
||||
use std::fmt;
|
||||
use std::io;
|
||||
use std::io::{self, ErrorKind};
|
||||
|
||||
/// Errors that are translated to ["synthetic" responses](struct.Response.html#method.synthetic).
|
||||
#[derive(Debug)]
|
||||
@@ -14,9 +14,6 @@ pub enum Error {
|
||||
ConnectionFailed(String),
|
||||
/// Too many redirects. Synthetic error `500`.
|
||||
TooManyRedirects,
|
||||
/// We fail to read the status line. This happens for pooled connections when
|
||||
/// TLS fails and we don't notice until trying to read.
|
||||
BadStatusRead,
|
||||
/// A status line we don't understand `HTTP/1.1 200 OK`. Synthetic error `500`.
|
||||
BadStatus,
|
||||
/// A header line that couldn't be parsed. Synthetic error `500`.
|
||||
@@ -37,11 +34,11 @@ pub enum Error {
|
||||
}
|
||||
|
||||
impl Error {
|
||||
// If the error is bad status read, which might happen if a TLS connections is
|
||||
// closed and we only discover it when trying to read the status line from it.
|
||||
pub(crate) fn is_bad_status_read(&self) -> bool {
|
||||
// Return true iff the error was due to a connection closing.
|
||||
pub(crate) fn connection_closed(&self) -> bool {
|
||||
match self {
|
||||
Error::BadStatusRead => true,
|
||||
Error::Io(e) if e.kind() == ErrorKind::ConnectionAborted => true,
|
||||
Error::Io(e) if e.kind() == ErrorKind::ConnectionReset => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
@@ -54,7 +51,6 @@ impl Error {
|
||||
Error::DnsFailed(_) => 400,
|
||||
Error::ConnectionFailed(_) => 500,
|
||||
Error::TooManyRedirects => 500,
|
||||
Error::BadStatusRead => 500,
|
||||
Error::BadStatus => 500,
|
||||
Error::BadHeader => 500,
|
||||
Error::Io(_) => 500,
|
||||
@@ -75,7 +71,6 @@ impl Error {
|
||||
Error::DnsFailed(_) => "Dns Failed",
|
||||
Error::ConnectionFailed(_) => "Connection Failed",
|
||||
Error::TooManyRedirects => "Too Many Redirects",
|
||||
Error::BadStatusRead => "Failed to read status line",
|
||||
Error::BadStatus => "Bad Status",
|
||||
Error::BadHeader => "Bad Header",
|
||||
Error::Io(_) => "Network Error",
|
||||
@@ -96,7 +91,6 @@ impl Error {
|
||||
Error::DnsFailed(err) => format!("Dns Failed: {}", err),
|
||||
Error::ConnectionFailed(err) => format!("Connection Failed: {}", err),
|
||||
Error::TooManyRedirects => "Too Many Redirects".to_string(),
|
||||
Error::BadStatusRead => "Failed to read status line".to_string(),
|
||||
Error::BadStatus => "Bad Status".to_string(),
|
||||
Error::BadHeader => "Bad Header".to_string(),
|
||||
Error::Io(ioe) => format!("Network Error: {}", ioe),
|
||||
|
||||
Reference in New Issue
Block a user