mirror of
https://github.com/fafhrd91/actix-net
synced 2025-06-28 23:30:36 +02:00
add io parameters
This commit is contained in:
@ -1,7 +1,6 @@
|
||||
use std::io;
|
||||
use std::marker::PhantomData;
|
||||
|
||||
use actix_server_config::ServerConfig;
|
||||
use actix_service::{NewService, Service};
|
||||
use futures::{future::ok, future::FutureResult, Async, Future, Poll};
|
||||
use native_tls::{self, Error, HandshakeError, TlsAcceptor};
|
||||
@ -9,16 +8,17 @@ use tokio_io::{AsyncRead, AsyncWrite};
|
||||
|
||||
use crate::counter::{Counter, CounterGuard};
|
||||
use crate::ssl::MAX_CONN_COUNTER;
|
||||
use crate::{Io, Protocol, ServerConfig};
|
||||
|
||||
/// Support `SSL` connections via native-tls package
|
||||
///
|
||||
/// `tls` feature enables `NativeTlsAcceptor` type
|
||||
pub struct NativeTlsAcceptor<T> {
|
||||
pub struct NativeTlsAcceptor<T, P> {
|
||||
acceptor: TlsAcceptor,
|
||||
io: PhantomData<T>,
|
||||
io: PhantomData<(T, P)>,
|
||||
}
|
||||
|
||||
impl<T: AsyncRead + AsyncWrite> NativeTlsAcceptor<T> {
|
||||
impl<T: AsyncRead + AsyncWrite, P> NativeTlsAcceptor<T, P> {
|
||||
/// Create `NativeTlsAcceptor` instance
|
||||
pub fn new(acceptor: TlsAcceptor) -> Self {
|
||||
NativeTlsAcceptor {
|
||||
@ -28,7 +28,7 @@ impl<T: AsyncRead + AsyncWrite> NativeTlsAcceptor<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: AsyncRead + AsyncWrite> Clone for NativeTlsAcceptor<T> {
|
||||
impl<T: AsyncRead + AsyncWrite, P> Clone for NativeTlsAcceptor<T, P> {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
acceptor: self.acceptor.clone(),
|
||||
@ -37,11 +37,11 @@ impl<T: AsyncRead + AsyncWrite> Clone for NativeTlsAcceptor<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: AsyncRead + AsyncWrite> NewService<ServerConfig> for NativeTlsAcceptor<T> {
|
||||
type Request = T;
|
||||
type Response = TlsStream<T>;
|
||||
impl<T: AsyncRead + AsyncWrite, P> NewService<ServerConfig> for NativeTlsAcceptor<T, P> {
|
||||
type Request = Io<T, P>;
|
||||
type Response = Io<TlsStream<T>, P>;
|
||||
type Error = Error;
|
||||
type Service = NativeTlsAcceptorService<T>;
|
||||
type Service = NativeTlsAcceptorService<T, P>;
|
||||
type InitError = ();
|
||||
type Future = FutureResult<Self::Service, Self::InitError>;
|
||||
|
||||
@ -58,17 +58,17 @@ impl<T: AsyncRead + AsyncWrite> NewService<ServerConfig> for NativeTlsAcceptor<T
|
||||
}
|
||||
}
|
||||
|
||||
pub struct NativeTlsAcceptorService<T> {
|
||||
pub struct NativeTlsAcceptorService<T, P> {
|
||||
acceptor: TlsAcceptor,
|
||||
io: PhantomData<T>,
|
||||
io: PhantomData<(T, P)>,
|
||||
conns: Counter,
|
||||
}
|
||||
|
||||
impl<T: AsyncRead + AsyncWrite> Service for NativeTlsAcceptorService<T> {
|
||||
type Request = T;
|
||||
type Response = TlsStream<T>;
|
||||
impl<T: AsyncRead + AsyncWrite, P> Service for NativeTlsAcceptorService<T, P> {
|
||||
type Request = Io<T, P>;
|
||||
type Response = Io<TlsStream<T>, P>;
|
||||
type Error = Error;
|
||||
type Future = Accept<T>;
|
||||
type Future = Accept<T, P>;
|
||||
|
||||
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
|
||||
if self.conns.available() {
|
||||
@ -78,10 +78,12 @@ impl<T: AsyncRead + AsyncWrite> Service for NativeTlsAcceptorService<T> {
|
||||
}
|
||||
}
|
||||
|
||||
fn call(&mut self, req: T) -> Self::Future {
|
||||
fn call(&mut self, req: Self::Request) -> Self::Future {
|
||||
let (io, params, _) = req.into_parts();
|
||||
Accept {
|
||||
_guard: self.conns.get(),
|
||||
inner: Some(self.acceptor.accept(req)),
|
||||
inner: Some(self.acceptor.accept(io)),
|
||||
params: Some(params),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -100,21 +102,30 @@ pub struct TlsStream<S> {
|
||||
|
||||
/// Future returned from `NativeTlsAcceptor::accept` which will resolve
|
||||
/// once the accept handshake has finished.
|
||||
pub struct Accept<S> {
|
||||
pub struct Accept<S, P> {
|
||||
inner: Option<Result<native_tls::TlsStream<S>, HandshakeError<S>>>,
|
||||
params: Option<P>,
|
||||
_guard: CounterGuard,
|
||||
}
|
||||
|
||||
impl<Io: AsyncRead + AsyncWrite> Future for Accept<Io> {
|
||||
type Item = TlsStream<Io>;
|
||||
impl<T: AsyncRead + AsyncWrite, P> Future for Accept<T, P> {
|
||||
type Item = Io<TlsStream<T>, P>;
|
||||
type Error = Error;
|
||||
|
||||
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
|
||||
match self.inner.take().expect("cannot poll MidHandshake twice") {
|
||||
Ok(stream) => Ok(TlsStream { inner: stream }.into()),
|
||||
Ok(stream) => Ok(Async::Ready(Io::from_parts(
|
||||
TlsStream { inner: stream },
|
||||
self.params.take().unwrap(),
|
||||
Protocol::Unknown,
|
||||
))),
|
||||
Err(HandshakeError::Failure(e)) => Err(e),
|
||||
Err(HandshakeError::WouldBlock(s)) => match s.handshake() {
|
||||
Ok(stream) => Ok(TlsStream { inner: stream }.into()),
|
||||
Ok(stream) => Ok(Async::Ready(Io::from_parts(
|
||||
TlsStream { inner: stream },
|
||||
self.params.take().unwrap(),
|
||||
Protocol::Unknown,
|
||||
))),
|
||||
Err(HandshakeError::Failure(e)) => Err(e),
|
||||
Err(HandshakeError::WouldBlock(s)) => {
|
||||
self.inner = Some(Err(HandshakeError::WouldBlock(s)));
|
||||
|
@ -8,17 +8,17 @@ use tokio_openssl::{AcceptAsync, SslAcceptorExt, SslStream};
|
||||
|
||||
use crate::counter::{Counter, CounterGuard};
|
||||
use crate::ssl::MAX_CONN_COUNTER;
|
||||
use crate::ServerConfig;
|
||||
use crate::{Io, Protocol, ServerConfig};
|
||||
|
||||
/// Support `SSL` connections via openssl package
|
||||
///
|
||||
/// `ssl` feature enables `OpensslAcceptor` type
|
||||
pub struct OpensslAcceptor<T> {
|
||||
pub struct OpensslAcceptor<T, P> {
|
||||
acceptor: SslAcceptor,
|
||||
io: PhantomData<T>,
|
||||
io: PhantomData<(T, P)>,
|
||||
}
|
||||
|
||||
impl<T> OpensslAcceptor<T> {
|
||||
impl<T, P> OpensslAcceptor<T, P> {
|
||||
/// Create default `OpensslAcceptor`
|
||||
pub fn new(acceptor: SslAcceptor) -> Self {
|
||||
OpensslAcceptor {
|
||||
@ -28,7 +28,7 @@ impl<T> OpensslAcceptor<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: AsyncRead + AsyncWrite> Clone for OpensslAcceptor<T> {
|
||||
impl<T: AsyncRead + AsyncWrite, P> Clone for OpensslAcceptor<T, P> {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
acceptor: self.acceptor.clone(),
|
||||
@ -37,11 +37,11 @@ impl<T: AsyncRead + AsyncWrite> Clone for OpensslAcceptor<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: AsyncRead + AsyncWrite> NewService<ServerConfig> for OpensslAcceptor<T> {
|
||||
type Request = T;
|
||||
type Response = SslStream<T>;
|
||||
impl<T: AsyncRead + AsyncWrite, P> NewService<ServerConfig> for OpensslAcceptor<T, P> {
|
||||
type Request = Io<T, P>;
|
||||
type Response = Io<SslStream<T>, P>;
|
||||
type Error = HandshakeError<T>;
|
||||
type Service = OpensslAcceptorService<T>;
|
||||
type Service = OpensslAcceptorService<T, P>;
|
||||
type InitError = ();
|
||||
type Future = FutureResult<Self::Service, Self::InitError>;
|
||||
|
||||
@ -58,17 +58,17 @@ impl<T: AsyncRead + AsyncWrite> NewService<ServerConfig> for OpensslAcceptor<T>
|
||||
}
|
||||
}
|
||||
|
||||
pub struct OpensslAcceptorService<T> {
|
||||
pub struct OpensslAcceptorService<T, P> {
|
||||
acceptor: SslAcceptor,
|
||||
io: PhantomData<T>,
|
||||
conns: Counter,
|
||||
io: PhantomData<(T, P)>,
|
||||
}
|
||||
|
||||
impl<T: AsyncRead + AsyncWrite> Service for OpensslAcceptorService<T> {
|
||||
type Request = T;
|
||||
type Response = SslStream<T>;
|
||||
impl<T: AsyncRead + AsyncWrite, P> Service for OpensslAcceptorService<T, P> {
|
||||
type Request = Io<T, P>;
|
||||
type Response = Io<SslStream<T>, P>;
|
||||
type Error = HandshakeError<T>;
|
||||
type Future = OpensslAcceptorServiceFut<T>;
|
||||
type Future = OpensslAcceptorServiceFut<T, P>;
|
||||
|
||||
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
|
||||
if self.conns.available() {
|
||||
@ -78,27 +78,52 @@ impl<T: AsyncRead + AsyncWrite> Service for OpensslAcceptorService<T> {
|
||||
}
|
||||
}
|
||||
|
||||
fn call(&mut self, req: T) -> Self::Future {
|
||||
fn call(&mut self, req: Self::Request) -> Self::Future {
|
||||
let (io, params, _) = req.into_parts();
|
||||
OpensslAcceptorServiceFut {
|
||||
_guard: self.conns.get(),
|
||||
fut: SslAcceptorExt::accept_async(&self.acceptor, req),
|
||||
fut: SslAcceptorExt::accept_async(&self.acceptor, io),
|
||||
params: Some(params),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct OpensslAcceptorServiceFut<T>
|
||||
pub struct OpensslAcceptorServiceFut<T, P>
|
||||
where
|
||||
T: AsyncRead + AsyncWrite,
|
||||
{
|
||||
fut: AcceptAsync<T>,
|
||||
params: Option<P>,
|
||||
_guard: CounterGuard,
|
||||
}
|
||||
|
||||
impl<T: AsyncRead + AsyncWrite> Future for OpensslAcceptorServiceFut<T> {
|
||||
type Item = SslStream<T>;
|
||||
impl<T: AsyncRead + AsyncWrite, P> Future for OpensslAcceptorServiceFut<T, P> {
|
||||
type Item = Io<SslStream<T>, P>;
|
||||
type Error = HandshakeError<T>;
|
||||
|
||||
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
|
||||
self.fut.poll()
|
||||
let io = futures::try_ready!(self.fut.poll());
|
||||
let proto = if let Some(protos) = io.get_ref().ssl().selected_alpn_protocol() {
|
||||
const H2: &[u8] = b"\x02h2";
|
||||
const HTTP10: &[u8] = b"\x08http/1.0";
|
||||
const HTTP11: &[u8] = b"\x08http/1.1";
|
||||
|
||||
if protos.windows(3).any(|window| window == H2) {
|
||||
Protocol::Http2
|
||||
} else if protos.windows(9).any(|window| window == HTTP11) {
|
||||
Protocol::Http11
|
||||
} else if protos.windows(9).any(|window| window == HTTP10) {
|
||||
Protocol::Http10
|
||||
} else {
|
||||
Protocol::Unknown
|
||||
}
|
||||
} else {
|
||||
Protocol::Unknown
|
||||
};
|
||||
Ok(Async::Ready(Io::from_parts(
|
||||
io,
|
||||
self.params.take().unwrap(),
|
||||
proto,
|
||||
)))
|
||||
}
|
||||
}
|
||||
|
@ -10,17 +10,17 @@ use tokio_rustls::{Accept, TlsAcceptor, TlsStream};
|
||||
|
||||
use crate::counter::{Counter, CounterGuard};
|
||||
use crate::ssl::MAX_CONN_COUNTER;
|
||||
use crate::ServerConfig as SrvConfig;
|
||||
use crate::{Io, Protocol, ServerConfig as SrvConfig};
|
||||
|
||||
/// Support `SSL` connections via rustls package
|
||||
///
|
||||
/// `rust-tls` feature enables `RustlsAcceptor` type
|
||||
pub struct RustlsAcceptor<T> {
|
||||
pub struct RustlsAcceptor<T, P> {
|
||||
config: Arc<ServerConfig>,
|
||||
io: PhantomData<T>,
|
||||
io: PhantomData<(T, P)>,
|
||||
}
|
||||
|
||||
impl<T: AsyncRead + AsyncWrite> RustlsAcceptor<T> {
|
||||
impl<T: AsyncRead + AsyncWrite, P> RustlsAcceptor<T, P> {
|
||||
/// Create `RustlsAcceptor` new service
|
||||
pub fn new(config: ServerConfig) -> Self {
|
||||
RustlsAcceptor {
|
||||
@ -30,7 +30,7 @@ impl<T: AsyncRead + AsyncWrite> RustlsAcceptor<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Clone for RustlsAcceptor<T> {
|
||||
impl<T, P> Clone for RustlsAcceptor<T, P> {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
config: self.config.clone(),
|
||||
@ -39,11 +39,11 @@ impl<T> Clone for RustlsAcceptor<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: AsyncRead + AsyncWrite> NewService<SrvConfig> for RustlsAcceptor<T> {
|
||||
type Request = T;
|
||||
type Response = TlsStream<T, ServerSession>;
|
||||
impl<T: AsyncRead + AsyncWrite, P> NewService<SrvConfig> for RustlsAcceptor<T, P> {
|
||||
type Request = Io<T, P>;
|
||||
type Response = Io<TlsStream<T, ServerSession>, P>;
|
||||
type Error = io::Error;
|
||||
type Service = RustlsAcceptorService<T>;
|
||||
type Service = RustlsAcceptorService<T, P>;
|
||||
type InitError = ();
|
||||
type Future = FutureResult<Self::Service, Self::InitError>;
|
||||
|
||||
@ -60,17 +60,17 @@ impl<T: AsyncRead + AsyncWrite> NewService<SrvConfig> for RustlsAcceptor<T> {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct RustlsAcceptorService<T> {
|
||||
pub struct RustlsAcceptorService<T, P> {
|
||||
acceptor: TlsAcceptor,
|
||||
io: PhantomData<T>,
|
||||
io: PhantomData<(T, P)>,
|
||||
conns: Counter,
|
||||
}
|
||||
|
||||
impl<T: AsyncRead + AsyncWrite> Service for RustlsAcceptorService<T> {
|
||||
type Request = T;
|
||||
type Response = TlsStream<T, ServerSession>;
|
||||
impl<T: AsyncRead + AsyncWrite, P> Service for RustlsAcceptorService<T, P> {
|
||||
type Request = Io<T, P>;
|
||||
type Response = Io<TlsStream<T, ServerSession>, P>;
|
||||
type Error = io::Error;
|
||||
type Future = RustlsAcceptorServiceFut<T>;
|
||||
type Future = RustlsAcceptorServiceFut<T, P>;
|
||||
|
||||
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
|
||||
if self.conns.available() {
|
||||
@ -80,27 +80,35 @@ impl<T: AsyncRead + AsyncWrite> Service for RustlsAcceptorService<T> {
|
||||
}
|
||||
}
|
||||
|
||||
fn call(&mut self, req: T) -> Self::Future {
|
||||
fn call(&mut self, req: Self::Request) -> Self::Future {
|
||||
let (io, params, _) = req.into_parts();
|
||||
RustlsAcceptorServiceFut {
|
||||
_guard: self.conns.get(),
|
||||
fut: self.acceptor.accept(req),
|
||||
fut: self.acceptor.accept(io),
|
||||
params: Some(params),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct RustlsAcceptorServiceFut<T>
|
||||
pub struct RustlsAcceptorServiceFut<T, P>
|
||||
where
|
||||
T: AsyncRead + AsyncWrite,
|
||||
{
|
||||
fut: Accept<T>,
|
||||
params: Option<P>,
|
||||
_guard: CounterGuard,
|
||||
}
|
||||
|
||||
impl<T: AsyncRead + AsyncWrite> Future for RustlsAcceptorServiceFut<T> {
|
||||
type Item = TlsStream<T, ServerSession>;
|
||||
impl<T: AsyncRead + AsyncWrite, P> Future for RustlsAcceptorServiceFut<T, P> {
|
||||
type Item = Io<TlsStream<T, ServerSession>, P>;
|
||||
type Error = io::Error;
|
||||
|
||||
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
|
||||
self.fut.poll()
|
||||
let io = futures::try_ready!(self.fut.poll());
|
||||
Ok(Async::Ready(Io::from_parts(
|
||||
io,
|
||||
self.params.take().unwrap(),
|
||||
Protocol::Unknown,
|
||||
)))
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user