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
+21 -3
View File
@@ -1,6 +1,6 @@
//! [`Or`] used to combine two services into one.
use super::{FromEmptyRouter, RoutingDsl};
use super::{FromEmptyRouter, OrDepth, RoutingDsl};
use crate::body::BoxBody;
use futures_util::ready;
use http::{Request, Response};
@@ -46,7 +46,13 @@ where
Poll::Ready(Ok(()))
}
fn call(&mut self, req: Request<ReqBody>) -> Self::Future {
fn call(&mut self, mut req: Request<ReqBody>) -> Self::Future {
if let Some(count) = req.extensions_mut().get_mut::<OrDepth>() {
count.increment();
} else {
req.extensions_mut().insert(OrDepth::new());
}
ResponseFuture {
state: State::FirstFuture {
f: self.first.clone().oneshot(req),
@@ -100,7 +106,7 @@ where
StateProj::FirstFuture { f } => {
let mut response = ready!(f.poll(cx)?);
let req = if let Some(ext) = response
let mut req = if let Some(ext) = response
.extensions_mut()
.remove::<FromEmptyRouter<ReqBody>>()
{
@@ -109,6 +115,18 @@ where
return Poll::Ready(Ok(response));
};
let mut leaving_outermost_or = false;
if let Some(depth) = req.extensions_mut().get_mut::<OrDepth>() {
if depth == 1 {
leaving_outermost_or = true;
} else {
depth.decrement();
}
}
if leaving_outermost_or {
req.extensions_mut().remove::<OrDepth>();
}
let second = this.second.take().expect("future polled after completion");
State::SecondFuture {