mirror of
https://github.com/actix/actix-web.git
synced 2024-11-18 15:41:17 +00:00
fix broken pipe for h2 when client is instantly dropped (#2113)
This commit is contained in:
parent
8c2ce2dedb
commit
2f7f1fa97a
1 changed files with 49 additions and 7 deletions
|
@ -174,8 +174,14 @@ impl H2ConnectionInner {
|
||||||
/// Cancel spawned connection task on drop.
|
/// Cancel spawned connection task on drop.
|
||||||
impl Drop for H2ConnectionInner {
|
impl Drop for H2ConnectionInner {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
|
if self
|
||||||
|
.sender
|
||||||
|
.send_request(http::Request::new(()), true)
|
||||||
|
.is_err()
|
||||||
|
{
|
||||||
self.handle.abort();
|
self.handle.abort();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
|
@ -398,9 +404,18 @@ where
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use std::net;
|
use std::{
|
||||||
|
future::Future,
|
||||||
|
net,
|
||||||
|
pin::Pin,
|
||||||
|
task::{Context, Poll},
|
||||||
|
time::{Duration, Instant},
|
||||||
|
};
|
||||||
|
|
||||||
use actix_rt::net::TcpStream;
|
use actix_rt::{
|
||||||
|
net::TcpStream,
|
||||||
|
time::{interval, Interval},
|
||||||
|
};
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
@ -424,9 +439,36 @@ mod test {
|
||||||
|
|
||||||
drop(conn);
|
drop(conn);
|
||||||
|
|
||||||
match sender.ready().await {
|
struct DropCheck {
|
||||||
Ok(_) => panic!("connection should be gone and can not be ready"),
|
sender: h2::client::SendRequest<Bytes>,
|
||||||
Err(e) => assert!(e.is_io()),
|
interval: Interval,
|
||||||
};
|
start_from: Instant,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Future for DropCheck {
|
||||||
|
type Output = ();
|
||||||
|
|
||||||
|
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||||
|
let this = self.get_mut();
|
||||||
|
match futures_core::ready!(this.sender.poll_ready(cx)) {
|
||||||
|
Ok(()) => {
|
||||||
|
if this.start_from.elapsed() > Duration::from_secs(10) {
|
||||||
|
panic!("connection should be gone and can not be ready");
|
||||||
|
} else {
|
||||||
|
let _ = this.interval.poll_tick(cx);
|
||||||
|
Poll::Pending
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(_) => Poll::Ready(()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DropCheck {
|
||||||
|
sender,
|
||||||
|
interval: interval(Duration::from_millis(100)),
|
||||||
|
start_from: Instant::now(),
|
||||||
|
}
|
||||||
|
.await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue