mirror of https://github.com/fafhrd91/actix-web
expose multiple types related to InnerConnector
This commit is contained in:
parent
73c2c68aac
commit
22f251de1a
|
@ -187,7 +187,7 @@ impl<T: AsyncRead + AsyncWrite + Unpin> IoConnection<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub(crate) enum EitherIoConnection<A, B>
|
pub enum EitherIoConnection<A, B>
|
||||||
where
|
where
|
||||||
A: AsyncRead + AsyncWrite + Unpin + 'static,
|
A: AsyncRead + AsyncWrite + Unpin + 'static,
|
||||||
B: AsyncRead + AsyncWrite + Unpin + 'static,
|
B: AsyncRead + AsyncWrite + Unpin + 'static,
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
use std::future::Future;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
use std::pin::Pin;
|
||||||
|
use std::task::{Context, Poll};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use actix_codec::{AsyncRead, AsyncWrite};
|
use actix_codec::{AsyncRead, AsyncWrite};
|
||||||
|
@ -12,7 +15,7 @@ use actix_utils::timeout::{TimeoutError, TimeoutService};
|
||||||
use http::Uri;
|
use http::Uri;
|
||||||
|
|
||||||
use super::config::ConnectorConfig;
|
use super::config::ConnectorConfig;
|
||||||
use super::connection::Connection;
|
use super::connection::EitherIoConnection;
|
||||||
use super::error::ConnectError;
|
use super::error::ConnectError;
|
||||||
use super::pool::{ConnectionPool, Protocol};
|
use super::pool::{ConnectionPool, Protocol};
|
||||||
use super::Connect;
|
use super::Connect;
|
||||||
|
@ -55,7 +58,7 @@ pub struct Connector<T, U> {
|
||||||
_phantom: PhantomData<U>,
|
_phantom: PhantomData<U>,
|
||||||
}
|
}
|
||||||
|
|
||||||
trait Io: AsyncRead + AsyncWrite + Unpin {}
|
pub trait Io: AsyncRead + AsyncWrite + Unpin {}
|
||||||
impl<T: AsyncRead + AsyncWrite + Unpin> Io for T {}
|
impl<T: AsyncRead + AsyncWrite + Unpin> Io for T {}
|
||||||
|
|
||||||
impl Connector<(), ()> {
|
impl Connector<(), ()> {
|
||||||
|
@ -242,8 +245,12 @@ where
|
||||||
/// its combinator chain.
|
/// its combinator chain.
|
||||||
pub fn finish(
|
pub fn finish(
|
||||||
self,
|
self,
|
||||||
) -> impl Service<Connect, Response = impl Connection, Error = ConnectError> + Clone
|
) -> InnerConnector<
|
||||||
{
|
impl Service<Connect, Response = (U, Protocol), Error = ConnectError>,
|
||||||
|
impl Service<Connect, Response = (Box<dyn Io>, Protocol), Error = ConnectError>,
|
||||||
|
U,
|
||||||
|
Box<dyn Io>,
|
||||||
|
> {
|
||||||
let tcp_service = TimeoutService::new(
|
let tcp_service = TimeoutService::new(
|
||||||
self.config.timeout,
|
self.config.timeout,
|
||||||
apply_fn(self.connector.clone(), |msg: Connect, srv| {
|
apply_fn(self.connector.clone(), |msg: Connect, srv| {
|
||||||
|
@ -259,22 +266,7 @@ where
|
||||||
|
|
||||||
#[cfg(not(any(feature = "openssl", feature = "rustls")))]
|
#[cfg(not(any(feature = "openssl", feature = "rustls")))]
|
||||||
{
|
{
|
||||||
use futures_core::future::LocalBoxFuture;
|
InnerConnector {
|
||||||
|
|
||||||
// A dummy service for annotate tls pool's type signature.
|
|
||||||
type DummyService = Box<
|
|
||||||
dyn Service<
|
|
||||||
Connect,
|
|
||||||
Response = (Box<dyn Io>, Protocol),
|
|
||||||
Error = ConnectError,
|
|
||||||
Future = LocalBoxFuture<
|
|
||||||
'static,
|
|
||||||
Result<(Box<dyn Io>, Protocol), ConnectError>,
|
|
||||||
>,
|
|
||||||
>,
|
|
||||||
>;
|
|
||||||
|
|
||||||
connect_impl::InnerConnector::<_, DummyService, _, Box<dyn Io>> {
|
|
||||||
tcp_pool: ConnectionPool::new(
|
tcp_pool: ConnectionPool::new(
|
||||||
tcp_service,
|
tcp_service,
|
||||||
self.config.no_disconnect_timeout(),
|
self.config.no_disconnect_timeout(),
|
||||||
|
@ -282,6 +274,7 @@ where
|
||||||
tls_pool: None,
|
tls_pool: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(feature = "openssl", feature = "rustls"))]
|
#[cfg(any(feature = "openssl", feature = "rustls"))]
|
||||||
{
|
{
|
||||||
const H2: &[u8] = b"h2";
|
const H2: &[u8] = b"h2";
|
||||||
|
@ -344,7 +337,7 @@ where
|
||||||
TimeoutError::Timeout => ConnectError::Timeout,
|
TimeoutError::Timeout => ConnectError::Timeout,
|
||||||
});
|
});
|
||||||
|
|
||||||
connect_impl::InnerConnector {
|
InnerConnector {
|
||||||
tcp_pool: ConnectionPool::new(
|
tcp_pool: ConnectionPool::new(
|
||||||
tcp_service,
|
tcp_service,
|
||||||
self.config.no_disconnect_timeout(),
|
self.config.no_disconnect_timeout(),
|
||||||
|
@ -355,99 +348,86 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mod connect_impl {
|
pub struct InnerConnector<S1, S2, Io1, Io2>
|
||||||
use std::future::Future;
|
where
|
||||||
use std::pin::Pin;
|
S1: Service<Connect, Response = (Io1, Protocol), Error = ConnectError> + 'static,
|
||||||
use std::task::{Context, Poll};
|
S2: Service<Connect, Response = (Io2, Protocol), Error = ConnectError> + 'static,
|
||||||
|
Io1: AsyncRead + AsyncWrite + Unpin + 'static,
|
||||||
|
Io2: AsyncRead + AsyncWrite + Unpin + 'static,
|
||||||
|
{
|
||||||
|
tcp_pool: ConnectionPool<S1, Io1>,
|
||||||
|
tls_pool: Option<ConnectionPool<S2, Io2>>,
|
||||||
|
}
|
||||||
|
|
||||||
use super::*;
|
impl<S1, S2, Io1, Io2> Clone for InnerConnector<S1, S2, Io1, Io2>
|
||||||
use crate::client::connection::EitherIoConnection;
|
where
|
||||||
|
S1: Service<Connect, Response = (Io1, Protocol), Error = ConnectError> + 'static,
|
||||||
pub(crate) struct InnerConnector<S1, S2, Io1, Io2>
|
S2: Service<Connect, Response = (Io2, Protocol), Error = ConnectError> + 'static,
|
||||||
where
|
Io1: AsyncRead + AsyncWrite + Unpin + 'static,
|
||||||
S1: Service<Connect, Response = (Io1, Protocol), Error = ConnectError> + 'static,
|
Io2: AsyncRead + AsyncWrite + Unpin + 'static,
|
||||||
S2: Service<Connect, Response = (Io2, Protocol), Error = ConnectError> + 'static,
|
{
|
||||||
Io1: AsyncRead + AsyncWrite + Unpin + 'static,
|
fn clone(&self) -> Self {
|
||||||
Io2: AsyncRead + AsyncWrite + Unpin + 'static,
|
InnerConnector {
|
||||||
{
|
tcp_pool: self.tcp_pool.clone(),
|
||||||
pub(crate) tcp_pool: ConnectionPool<S1, Io1>,
|
tls_pool: self.tls_pool.as_ref().cloned(),
|
||||||
pub(crate) tls_pool: Option<ConnectionPool<S2, Io2>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<S1, S2, Io1, Io2> Clone for InnerConnector<S1, S2, Io1, Io2>
|
|
||||||
where
|
|
||||||
S1: Service<Connect, Response = (Io1, Protocol), Error = ConnectError> + 'static,
|
|
||||||
S2: Service<Connect, Response = (Io2, Protocol), Error = ConnectError> + 'static,
|
|
||||||
Io1: AsyncRead + AsyncWrite + Unpin + 'static,
|
|
||||||
Io2: AsyncRead + AsyncWrite + Unpin + 'static,
|
|
||||||
{
|
|
||||||
fn clone(&self) -> Self {
|
|
||||||
InnerConnector {
|
|
||||||
tcp_pool: self.tcp_pool.clone(),
|
|
||||||
tls_pool: self.tls_pool.as_ref().cloned(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<S1, S2, Io1, Io2> Service<Connect> for InnerConnector<S1, S2, Io1, Io2>
|
impl<S1, S2, Io1, Io2> Service<Connect> for InnerConnector<S1, S2, Io1, Io2>
|
||||||
where
|
where
|
||||||
S1: Service<Connect, Response = (Io1, Protocol), Error = ConnectError> + 'static,
|
S1: Service<Connect, Response = (Io1, Protocol), Error = ConnectError> + 'static,
|
||||||
S2: Service<Connect, Response = (Io2, Protocol), Error = ConnectError> + 'static,
|
S2: Service<Connect, Response = (Io2, Protocol), Error = ConnectError> + 'static,
|
||||||
Io1: AsyncRead + AsyncWrite + Unpin + 'static,
|
Io1: AsyncRead + AsyncWrite + Unpin + 'static,
|
||||||
Io2: AsyncRead + AsyncWrite + Unpin + 'static,
|
Io2: AsyncRead + AsyncWrite + Unpin + 'static,
|
||||||
{
|
{
|
||||||
type Response = EitherIoConnection<Io1, Io2>;
|
type Response = EitherIoConnection<Io1, Io2>;
|
||||||
type Error = ConnectError;
|
type Error = ConnectError;
|
||||||
type Future = InnerConnectorResponse<S1, S2, Io1, Io2>;
|
type Future = InnerConnectorResponse<S1, S2, Io1, Io2>;
|
||||||
|
|
||||||
fn poll_ready(&self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
fn poll_ready(&self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
||||||
self.tcp_pool.poll_ready(cx)
|
self.tcp_pool.poll_ready(cx)
|
||||||
}
|
|
||||||
|
|
||||||
fn call(&self, req: Connect) -> Self::Future {
|
|
||||||
match req.uri.scheme_str() {
|
|
||||||
Some("https") | Some("wss") => match self.tls_pool {
|
|
||||||
None => InnerConnectorResponse::SslIsNotSupported,
|
|
||||||
Some(ref pool) => InnerConnectorResponse::Io2(pool.call(req)),
|
|
||||||
},
|
|
||||||
_ => InnerConnectorResponse::Io1(self.tcp_pool.call(req)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pin_project::pin_project(project = InnerConnectorProj)]
|
fn call(&self, req: Connect) -> Self::Future {
|
||||||
pub(crate) enum InnerConnectorResponse<S1, S2, Io1, Io2>
|
match req.uri.scheme_str() {
|
||||||
where
|
Some("https") | Some("wss") => match self.tls_pool {
|
||||||
S1: Service<Connect, Response = (Io1, Protocol), Error = ConnectError> + 'static,
|
None => InnerConnectorResponse::SslIsNotSupported,
|
||||||
S2: Service<Connect, Response = (Io2, Protocol), Error = ConnectError> + 'static,
|
Some(ref pool) => InnerConnectorResponse::Io2(pool.call(req)),
|
||||||
Io1: AsyncRead + AsyncWrite + Unpin + 'static,
|
},
|
||||||
Io2: AsyncRead + AsyncWrite + Unpin + 'static,
|
_ => InnerConnectorResponse::Io1(self.tcp_pool.call(req)),
|
||||||
{
|
}
|
||||||
Io1(#[pin] <ConnectionPool<S1, Io1> as Service<Connect>>::Future),
|
|
||||||
Io2(#[pin] <ConnectionPool<S2, Io2> as Service<Connect>>::Future),
|
|
||||||
SslIsNotSupported,
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<S1, S2, Io1, Io2> Future for InnerConnectorResponse<S1, S2, Io1, Io2>
|
#[pin_project::pin_project(project = InnerConnectorProj)]
|
||||||
where
|
pub enum InnerConnectorResponse<S1, S2, Io1, Io2>
|
||||||
S1: Service<Connect, Response = (Io1, Protocol), Error = ConnectError> + 'static,
|
where
|
||||||
S2: Service<Connect, Response = (Io2, Protocol), Error = ConnectError> + 'static,
|
S1: Service<Connect, Response = (Io1, Protocol), Error = ConnectError> + 'static,
|
||||||
Io1: AsyncRead + AsyncWrite + Unpin + 'static,
|
S2: Service<Connect, Response = (Io2, Protocol), Error = ConnectError> + 'static,
|
||||||
Io2: AsyncRead + AsyncWrite + Unpin + 'static,
|
Io1: AsyncRead + AsyncWrite + Unpin + 'static,
|
||||||
{
|
Io2: AsyncRead + AsyncWrite + Unpin + 'static,
|
||||||
type Output = Result<EitherIoConnection<Io1, Io2>, ConnectError>;
|
{
|
||||||
|
Io1(#[pin] <ConnectionPool<S1, Io1> as Service<Connect>>::Future),
|
||||||
|
Io2(#[pin] <ConnectionPool<S2, Io2> as Service<Connect>>::Future),
|
||||||
|
SslIsNotSupported,
|
||||||
|
}
|
||||||
|
|
||||||
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
impl<S1, S2, Io1, Io2> Future for InnerConnectorResponse<S1, S2, Io1, Io2>
|
||||||
match self.project() {
|
where
|
||||||
InnerConnectorProj::Io1(fut) => {
|
S1: Service<Connect, Response = (Io1, Protocol), Error = ConnectError> + 'static,
|
||||||
fut.poll(cx).map_ok(EitherIoConnection::A)
|
S2: Service<Connect, Response = (Io2, Protocol), Error = ConnectError> + 'static,
|
||||||
}
|
Io1: AsyncRead + AsyncWrite + Unpin + 'static,
|
||||||
InnerConnectorProj::Io2(fut) => {
|
Io2: AsyncRead + AsyncWrite + Unpin + 'static,
|
||||||
fut.poll(cx).map_ok(EitherIoConnection::B)
|
{
|
||||||
}
|
type Output = Result<EitherIoConnection<Io1, Io2>, ConnectError>;
|
||||||
InnerConnectorProj::SslIsNotSupported => {
|
|
||||||
Poll::Ready(Err(ConnectError::SslIsNotSupported))
|
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||||
}
|
match self.project() {
|
||||||
|
InnerConnectorProj::Io1(fut) => fut.poll(cx).map_ok(EitherIoConnection::A),
|
||||||
|
InnerConnectorProj::Io2(fut) => fut.poll(cx).map_ok(EitherIoConnection::B),
|
||||||
|
InnerConnectorProj::SslIsNotSupported => {
|
||||||
|
Poll::Ready(Err(ConnectError::SslIsNotSupported))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,7 +45,7 @@ impl From<Authority> for Key {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Connections pool for reuse Io type for certain [`http::uri::Authority`] as key.
|
/// Connections pool for reuse Io type for certain [`http::uri::Authority`] as key.
|
||||||
pub(crate) struct ConnectionPool<S, Io>
|
pub struct ConnectionPool<S, Io>
|
||||||
where
|
where
|
||||||
Io: AsyncWrite + Unpin + 'static,
|
Io: AsyncWrite + Unpin + 'static,
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue