mirror of
https://github.com/fafhrd91/actix-web
synced 2025-08-29 00:07:48 +02:00
Use cilent time out for h2 handshake timeout. (#2483)
This commit is contained in:
@@ -1,20 +1,30 @@
|
||||
//! HTTP/2 protocol.
|
||||
|
||||
use std::{
|
||||
future::Future,
|
||||
pin::Pin,
|
||||
task::{Context, Poll},
|
||||
};
|
||||
|
||||
use actix_codec::{AsyncRead, AsyncWrite};
|
||||
use actix_rt::time::Sleep;
|
||||
use bytes::Bytes;
|
||||
use futures_core::{ready, Stream};
|
||||
use h2::RecvStream;
|
||||
use h2::{
|
||||
server::{handshake, Connection, Handshake},
|
||||
RecvStream,
|
||||
};
|
||||
|
||||
mod dispatcher;
|
||||
mod service;
|
||||
|
||||
pub use self::dispatcher::Dispatcher;
|
||||
pub use self::service::H2Service;
|
||||
use crate::error::PayloadError;
|
||||
|
||||
use crate::{
|
||||
config::ServiceConfig,
|
||||
error::{DispatchError, PayloadError},
|
||||
};
|
||||
|
||||
/// HTTP/2 peer stream.
|
||||
pub struct Payload {
|
||||
@@ -50,3 +60,44 @@ impl Stream for Payload {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn handshake_with_timeout<T>(
|
||||
io: T,
|
||||
config: &ServiceConfig,
|
||||
) -> HandshakeWithTimeout<T>
|
||||
where
|
||||
T: AsyncRead + AsyncWrite + Unpin,
|
||||
{
|
||||
HandshakeWithTimeout {
|
||||
handshake: handshake(io),
|
||||
timer: config.client_timer().map(Box::pin),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) struct HandshakeWithTimeout<T: AsyncRead + AsyncWrite + Unpin> {
|
||||
handshake: Handshake<T>,
|
||||
timer: Option<Pin<Box<Sleep>>>,
|
||||
}
|
||||
|
||||
impl<T> Future for HandshakeWithTimeout<T>
|
||||
where
|
||||
T: AsyncRead + AsyncWrite + Unpin,
|
||||
{
|
||||
type Output = Result<(Connection<T, Bytes>, Option<Pin<Box<Sleep>>>), DispatchError>;
|
||||
|
||||
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||
let this = self.get_mut();
|
||||
|
||||
match Pin::new(&mut this.handshake).poll(cx)? {
|
||||
// return the timer on success handshake. It can be re-used for h2 ping-pong.
|
||||
Poll::Ready(conn) => Poll::Ready(Ok((conn, this.timer.take()))),
|
||||
Poll::Pending => match this.timer.as_mut() {
|
||||
Some(timer) => {
|
||||
ready!(timer.as_mut().poll(cx));
|
||||
Poll::Ready(Err(DispatchError::SlowRequestTimeout))
|
||||
}
|
||||
None => Poll::Pending,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user