Work around for http2 hang with Or (#199)

This is a nasty hack that works around
https://github.com/hyperium/hyper/issues/2621.

Fixes https://github.com/tokio-rs/axum/issues/191
This commit is contained in:
David Pedersen
2021-08-17 19:00:24 +02:00
committed by GitHub
parent 97c140cdf7
commit 93cdfe8c5f
4 changed files with 175 additions and 5 deletions
+38 -1
View File
@@ -547,7 +547,11 @@ where
fn call(&mut self, request: Request<B>) -> Self::Future {
let mut res = Response::new(crate::body::empty());
res.extensions_mut().insert(FromEmptyRouter { request });
if request.extensions().get::<OrDepth>().is_some() {
res.extensions_mut().insert(FromEmptyRouter { request });
}
*res.status_mut() = self.status;
EmptyRouterFuture {
future: futures_util::future::ok(res),
@@ -565,6 +569,39 @@ struct FromEmptyRouter<B> {
request: Request<B>,
}
/// We need to track whether we're inside an `Or` or not, and only if we then
/// should we save the request into the response extensions.
///
/// This is to work around https://github.com/hyperium/hyper/issues/2621.
///
/// Since ours can be nested we have to track the depth to know when we're
/// leaving the top most `Or`.
///
/// Hopefully when https://github.com/hyperium/hyper/issues/2621 is resolved we
/// can remove this nasty hack.
#[derive(Debug)]
struct OrDepth(usize);
impl OrDepth {
fn new() -> Self {
Self(1)
}
fn increment(&mut self) {
self.0 += 1;
}
fn decrement(&mut self) {
self.0 -= 1;
}
}
impl PartialEq<usize> for &mut OrDepth {
fn eq(&self, other: &usize) -> bool {
self.0 == *other
}
}
#[derive(Debug, Clone)]
pub(crate) struct PathPattern(Arc<Inner>);