Skip to content

Commit d2aa5d8

Browse files
committed
fix(client): don't leak connections with no keep-alive
Closes #1383
1 parent e4864a2 commit d2aa5d8

File tree

2 files changed

+44
-1
lines changed

2 files changed

+44
-1
lines changed

src/client/pool.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -200,10 +200,13 @@ impl<T: Clone> KeepAlive for Pooled<T> {
200200
};
201201
if pool.is_enabled() {
202202
pool.put(self.key.clone(), self.entry.clone());
203+
} else {
204+
trace!("keepalive disabled, dropping pooled ({:?})", self.key);
205+
self.disable();
203206
}
204207
} else {
205208
trace!("pool dropped, dropping pooled ({:?})", self.key);
206-
self.entry.status.set(TimedKA::Disabled);
209+
self.disable();
207210
}
208211
}
209212

tests/client.rs

+40
Original file line numberDiff line numberDiff line change
@@ -654,6 +654,46 @@ mod dispatch_impl {
654654
}
655655

656656

657+
#[test]
658+
fn no_keep_alive_closes_connection() {
659+
// https://github.com/hyperium/hyper/issues/1383
660+
let _ = pretty_env_logger::init();
661+
662+
let server = TcpListener::bind("127.0.0.1:0").unwrap();
663+
let addr = server.local_addr().unwrap();
664+
let mut core = Core::new().unwrap();
665+
let handle = core.handle();
666+
let closes = Arc::new(AtomicUsize::new(0));
667+
668+
let (tx1, rx1) = oneshot::channel();
669+
670+
thread::spawn(move || {
671+
let mut sock = server.accept().unwrap().0;
672+
sock.set_read_timeout(Some(Duration::from_secs(5))).unwrap();
673+
sock.set_write_timeout(Some(Duration::from_secs(5))).unwrap();
674+
let mut buf = [0; 4096];
675+
sock.read(&mut buf).expect("read 1");
676+
sock.write_all(b"HTTP/1.1 200 OK\r\nContent-Length: 0\r\n\r\n").unwrap();
677+
let _ = tx1.send(());
678+
});
679+
680+
let uri = format!("http://{}/a", addr).parse().unwrap();
681+
682+
let client = Client::configure()
683+
.connector(DebugConnector(HttpConnector::new(1, &handle), closes.clone()))
684+
.no_proto()
685+
.keep_alive(false)
686+
.build(&handle);
687+
let res = client.get(uri).and_then(move |res| {
688+
assert_eq!(res.status(), hyper::StatusCode::Ok);
689+
res.body().concat2()
690+
});
691+
let rx = rx1.map_err(|_| hyper::Error::Io(io::Error::new(io::ErrorKind::Other, "thread panicked")));
692+
core.run(res.join(rx).map(|r| r.0)).unwrap();
693+
694+
assert_eq!(closes.load(Ordering::Relaxed), 1);
695+
}
696+
657697

658698
struct DebugConnector(HttpConnector, Arc<AtomicUsize>);
659699

0 commit comments

Comments
 (0)