Skip to content

Commit ab1daa9

Browse files
rustypbzweihander
rusty
authored andcommitted
Add stopper option to server
1 parent 882fa23 commit ab1daa9

File tree

2 files changed

+25
-7
lines changed

2 files changed

+25
-7
lines changed

Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ log = "0.4.11"
2626
pin-project = "1.0.2"
2727
async-channel = "1.5.1"
2828
async-dup = "1.2.2"
29+
stopper = "0.2.0"
2930

3031
[dev-dependencies]
3132
pretty_assertions = "0.6.1"

src/server/mod.rs

+24-7
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use http_types::headers::{CONNECTION, UPGRADE};
66
use http_types::upgrade::Connection;
77
use http_types::{Request, Response, StatusCode};
88
use std::{marker::PhantomData, time::Duration};
9+
use stopper::Stopper;
910
mod body_reader;
1011
mod decode;
1112
mod encode;
@@ -17,13 +18,16 @@ pub use encode::Encoder;
1718
#[derive(Debug, Clone)]
1819
pub struct ServerOptions {
1920
/// Timeout to handle headers. Defaults to 60s.
20-
headers_timeout: Option<Duration>,
21+
pub headers_timeout: Option<Duration>,
22+
/// Stopper to shutdown the server. Defaults to None.
23+
pub stopper: Option<Stopper>,
2124
}
2225

2326
impl Default for ServerOptions {
2427
fn default() -> Self {
2528
Self {
2629
headers_timeout: Some(Duration::from_secs(60)),
30+
stopper: None,
2731
}
2832
}
2933
}
@@ -113,17 +117,30 @@ where
113117
// Decode a new request, timing out if this takes longer than the timeout duration.
114118
let fut = decode(self.io.clone());
115119

116-
let (req, mut body) = if let Some(timeout_duration) = self.opts.headers_timeout {
117-
match timeout(timeout_duration, fut).await {
120+
let (req, mut body) = match (self.opts.headers_timeout, &self.opts.stopper) {
121+
(Some(timeout_duration), Some(stopper)) => {
122+
match timeout(timeout_duration, stopper.stop_future(fut)).await {
123+
Ok(Some(Ok(Some(r)))) => r,
124+
Ok(Some(Ok(None))) | Err(TimeoutError { .. }) | Ok(None) => {
125+
return Ok(ConnectionStatus::Close);
126+
} /* EOF, timeout, or stopped by stopper */
127+
Ok(Some(Err(e))) => return Err(e),
128+
}
129+
}
130+
(Some(timeout_duration), None) => match timeout(timeout_duration, fut).await {
118131
Ok(Ok(Some(r))) => r,
119132
Ok(Ok(None)) | Err(TimeoutError { .. }) => return Ok(ConnectionStatus::Close), /* EOF or timeout */
120133
Ok(Err(e)) => return Err(e),
121-
}
122-
} else {
123-
match fut.await? {
134+
},
135+
(None, Some(stopper)) => match stopper.stop_future(fut).await {
136+
Some(Ok(Some(r))) => r,
137+
Some(Ok(None)) | None => return Ok(ConnectionStatus::Close), /* EOF or stopped by stopper */
138+
Some(Err(e)) => return Err(e),
139+
},
140+
(None, None) => match fut.await? {
124141
Some(r) => r,
125142
None => return Ok(ConnectionStatus::Close), /* EOF */
126-
}
143+
},
127144
};
128145

129146
let has_upgrade_header = req.header(UPGRADE).is_some();

0 commit comments

Comments
 (0)