Don't reuse conns with bytes pending from server (#372)
This makes us less likely to try and reuse a closed connection, which produces problems in particular for requests that can't be retried. Fixes #361 Fixes #124
This commit is contained in:
committed by
GitHub
parent
5e4b37a393
commit
50d9ccff8c
@@ -148,7 +148,15 @@ impl Stream {
|
||||
|
||||
// Check if the server has closed a stream by performing a one-byte
|
||||
// non-blocking read. If this returns EOF, the server has closed the
|
||||
// connection: return true. If this returns WouldBlock (aka EAGAIN),
|
||||
// connection: return true. If this returns a successful read, there are
|
||||
// some bytes on the connection even though there was no inflight request.
|
||||
// For plain HTTP streams, that might mean an HTTP 408 was pushed; it
|
||||
// could also mean a buggy server that sent more bytes than a response's
|
||||
// Content-Length. For HTTPS streams, that might mean a close_notify alert,
|
||||
// which is the proper way to shut down an idle stream.
|
||||
// Either way, bytes available on the stream before we've made a request
|
||||
// means the stream is not usable, so we should discard it.
|
||||
// If this returns WouldBlock (aka EAGAIN),
|
||||
// that means the connection is still open: return false. Otherwise
|
||||
// return an error.
|
||||
fn serverclosed_stream(stream: &std::net::TcpStream) -> io::Result<bool> {
|
||||
@@ -156,8 +164,13 @@ impl Stream {
|
||||
stream.set_nonblocking(true)?;
|
||||
|
||||
let result = match stream.peek(&mut buf) {
|
||||
Ok(0) => Ok(true),
|
||||
Ok(_) => Ok(false), // TODO: Maybe this should produce an "unexpected response" error
|
||||
Ok(n) => {
|
||||
debug!(
|
||||
"peek on reused connection returned {}, not WouldBlock; discarding",
|
||||
n
|
||||
);
|
||||
Ok(true)
|
||||
}
|
||||
Err(e) if e.kind() == io::ErrorKind::WouldBlock => Ok(false),
|
||||
Err(e) => Err(e),
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user