Refactor ntex-io (#164)

* Refactor Io and Filter types
This commit is contained in:
Nikolay Kim 2023-01-23 14:42:00 +06:00 committed by GitHub
parent 8cbd8758a5
commit 83d05d81ef
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
55 changed files with 1615 additions and 1495 deletions

View file

@ -1,5 +1,9 @@
# Changes
## [0.2.1] - 2023-01-23
* Update filter implementation
## [0.2.0] - 2023-01-04
* Release

View file

@ -1,6 +1,6 @@
[package]
name = "ntex-tls"
version = "0.2.0"
version = "0.2.1"
authors = ["ntex contributors <team@ntex.rs>"]
description = "An implementation of SSL streams for ntex backed by OpenSSL"
keywords = ["network", "framework", "async", "futures"]
@ -25,15 +25,15 @@ openssl = ["tls_openssl"]
rustls = ["tls_rust"]
[dependencies]
ntex-bytes = "0.1.18"
ntex-io = "0.2.0"
ntex-bytes = "0.1.19"
ntex-io = "0.2.1"
ntex-util = "0.2.0"
ntex-service = "1.0.0"
log = "0.4"
pin-project-lite = "0.2"
# openssl
tls_openssl = { version="0.10.42", package = "openssl", optional = true }
tls_openssl = { version="0.10", package = "openssl", optional = true }
# rustls
tls_rust = { version = "0.20", package = "rustls", optional = true }

View file

@ -1,31 +1,31 @@
-----BEGIN CERTIFICATE-----
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
Ing=
MIICCgKCAgEA2WzIA2IpVR9Tb9EFhITlxuhE5rY2a3S6qzYNzQVgSFggxXEPn8k1
sQEcer5BfAP986Sck3H0FvB4Bt/I8PwOtUCmhwcc8KtB5TcGPR4fjXnrpC+MIK5U
NLkwuyBDKziYzTdBj8kUFX1WxmvEHEgqToPOZfBgsS71cJAR/zOWraDLSRM54jXy
voLZN4Ti9rQagQrvTQ44Vz5ycDQy7UxtbUGh1CVv69vNVr7/SOOh/Nw5FNOZWLWr
odGyoec5wh9iqRZgRqiTUc6Lt7V2RWc2X2gjwST2UfI+U46Ip3oaQ7ZD4eAkoqND
xdniBZAykVG3c/99ux4BAESTF8fsNch6UticBxYMuTu+ouvP0psfI9wwwNliJDmA
CRUTB9AgRynbL1AzhqQoDfsb98IZfjfNOpwnwuLwpMAPhbgd5KNdZaIJ4Hb6/stI
yFElOExxd3TAxF2Gshd/lq1JcNHAZ1DSXV5MvOWT/NWgXwbIzUgQ8eIi+HuDYX2U
UuaB6R8tbd52H7rbUv6HrfinuSlKWqjSYLkiKHkwUpoMw8y9UycRSzs1E9nPwPTO
vRXb0mNCQeBCV9FvStNVXdCUTT8LGPv87xSD2pmt7LijlE6mHLG8McfcWkzA69un
CEHIFAFDimTuN7EBljc119xWFTcHMyoZAfFF+oTqwSbBGImruCxnaJECAwEAATAN
BgkqhkiG9w0BAQsFAAOCAgEApavsgsn7SpPHfhDSN5iZs1ILZQRewJg0Bty0xPfk
3tynSW6bNH3nSaKbpsdmxxomthNSQgD2heOq1By9YzeOoNR+7Pk3s4FkASnf3ToI
JNTUasBFFfaCG96s4Yvs8KiWS/k84yaWuU8c3Wb1jXs5Rv1qE1Uvuwat1DSGXSoD
JNluuIkCsC4kWkyq5pWCGQrabWPRTWsHwC3PTcwSRBaFgYLJaR72SloHB1ot02zL
d2age9dmFRFLLCBzP+D7RojBvL37qS/HR+rQ4SoQwiVc/JzaeqSe7ZbvEH9sZYEu
ALowJzgbwro7oZflwTWunSeSGDSltkqKjvWvZI61pwfHKDahUTmZ5h2y67FuGEaC
CIOUI8dSVSPKITxaq3JL4ze2e9/0Lt7hj19YK2uUmtMAW5Tirz4Yx5lyGH9U8Wur
y/X8VPxTc4A9TMlJgkyz0hqvhbPOT/zSWB10zXh0glKAsSBryAOEDxV1UygmSir7
YV8Qaq+oyKUTMc1MFq5vZ07M51EPaietn85t8V2Y+k/8XYltRp32NxsypxAJuyxh
g/ko6RVTrWa1sMvz/F9LFqAdKiK5eM96lh9IU4xiLg4ob8aS/GRAA8oIFkZFhLrt
tOwjIUPmEPyHWFi8dLpNuQKYalLYhuwZftG/9xV+wqhKGZO9iPrpHSYBRTap8w2y
1QU=
-----END CERTIFICATE-----

View file

@ -1,51 +1,51 @@
-----BEGIN RSA PRIVATE KEY-----
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
-----END RSA PRIVATE KEY-----

View file

@ -27,7 +27,8 @@ async fn main() -> io::Result<()> {
// rustls connector
let connector = connect::rustls::Connector::new(config.clone());
let io = connector.connect("www.rust-lang.org:443").await.unwrap();
//let io = connector.connect("www.rust-lang.org:443").await.unwrap();
let io = connector.connect("127.0.0.1:8443").await.unwrap();
println!("Connected to tls server {:?}", io.query::<PeerAddr>().get());
let result = io
.send(Bytes::from_static(b"GET /\r\n\r\n"), &codec::BytesCodec)

View file

@ -1,7 +1,7 @@
use std::task::{Context, Poll};
use std::{error::Error, future::Future, marker::PhantomData, pin::Pin};
use ntex_io::{Filter, FilterFactory, Io};
use ntex_io::{Filter, FilterFactory, Io, Layer};
use ntex_service::{Service, ServiceFactory};
use ntex_util::{future::Ready, time::Millis};
use tls_openssl::ssl::SslAcceptor;
@ -53,7 +53,7 @@ impl<F> Clone for Acceptor<F> {
}
impl<F: Filter, C: 'static> ServiceFactory<Io<F>, C> for Acceptor<F> {
type Response = Io<SslFilter<F>>;
type Response = Io<Layer<SslFilter, F>>;
type Error = Box<dyn Error>;
type Service = AcceptorService<F>;
type InitError = ();
@ -81,7 +81,7 @@ pub struct AcceptorService<F> {
}
impl<F: Filter> Service<Io<F>> for AcceptorService<F> {
type Response = Io<SslFilter<F>>;
type Response = Io<Layer<SslFilter, F>>;
type Error = Box<dyn Error>;
type Future<'f> = AcceptorServiceResponse<F>;
@ -115,7 +115,7 @@ pin_project_lite::pin_project! {
}
impl<F: Filter> Future for AcceptorServiceResponse<F> {
type Output = Result<Io<SslFilter<F>>, Box<dyn Error>>;
type Output = Result<Io<Layer<SslFilter, F>>, Box<dyn Error>>;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
self.project().fut.poll(cx)

View file

@ -1,10 +1,9 @@
#![allow(clippy::type_complexity)]
//! An implementation of SSL streams for ntex backed by OpenSSL
use std::cell::{Cell, RefCell};
use std::{any, cmp, error::Error, io, task::Context, task::Poll};
use ntex_bytes::{BufMut, BytesVec, PoolRef};
use ntex_io::{types, Base, Filter, FilterFactory, Io, IoRef, ReadStatus, WriteStatus};
use ntex_io::{types, Filter, FilterFactory, FilterLayer, Io, Layer, ReadBuf, WriteBuf};
use ntex_util::{future::poll_fn, future::BoxFuture, ready, time, time::Millis};
use tls_openssl::ssl::{self, NameType, SslStream};
use tls_openssl::x509::X509;
@ -23,28 +22,27 @@ pub struct PeerCert(pub X509);
pub struct PeerCertChain(pub Vec<X509>);
/// An implementation of SSL streams
pub struct SslFilter<F = Base> {
inner: RefCell<SslStream<IoInner<F>>>,
pub struct SslFilter {
inner: RefCell<SslStream<IoInner>>,
pool: PoolRef,
handshake: Cell<bool>,
read_buf: Cell<Option<BytesVec>>,
}
struct IoInner<F> {
inner: F,
struct IoInner {
inner_read_buf: Option<BytesVec>,
inner_write_buf: Option<BytesVec>,
pool: PoolRef,
write_buf: Option<BytesVec>,
}
impl<F: Filter> io::Read for IoInner<F> {
impl io::Read for IoInner {
fn read(&mut self, dst: &mut [u8]) -> io::Result<usize> {
if let Some(mut buf) = self.inner.get_read_buf() {
if let Some(mut buf) = self.inner_read_buf.take() {
if buf.is_empty() {
Err(io::Error::from(io::ErrorKind::WouldBlock))
} else {
let len = cmp::min(buf.len(), dst.len());
dst[..len].copy_from_slice(&buf.split_to(len));
self.inner.release_read_buf(buf);
self.inner_read_buf = Some(buf);
Ok(len)
}
} else {
@ -53,16 +51,16 @@ impl<F: Filter> io::Read for IoInner<F> {
}
}
impl<F: Filter> io::Write for IoInner<F> {
impl io::Write for IoInner {
fn write(&mut self, src: &[u8]) -> io::Result<usize> {
let mut buf = if let Some(mut buf) = self.inner.get_write_buf() {
let mut buf = if let Some(mut buf) = self.inner_write_buf.take() {
buf.reserve(src.len());
buf
} else {
BytesVec::with_capacity_in(src.len(), self.pool)
};
buf.extend_from_slice(src);
self.inner.release_write_buf(buf)?;
self.inner_write_buf = Some(buf);
Ok(src.len())
}
@ -71,7 +69,37 @@ impl<F: Filter> io::Write for IoInner<F> {
}
}
impl<F: Filter> Filter for SslFilter<F> {
impl SslFilter {
fn with_buffers<F, R>(&self, buf: &mut WriteBuf<'_>, f: F) -> R
where
F: FnOnce() -> R,
{
self.inner.borrow_mut().get_mut().inner_write_buf = Some(buf.take_dst());
self.inner.borrow_mut().get_mut().inner_read_buf =
buf.with_read_buf(|b| b.take_src());
let result = f();
buf.set_dst(self.inner.borrow_mut().get_mut().inner_write_buf.take());
buf.with_read_buf(|b| {
b.set_src(self.inner.borrow_mut().get_mut().inner_read_buf.take())
});
result
}
fn set_buffers(&self, buf: &mut WriteBuf<'_>) {
self.inner.borrow_mut().get_mut().inner_write_buf = Some(buf.take_dst());
self.inner.borrow_mut().get_mut().inner_read_buf =
buf.with_read_buf(|b| b.take_src());
}
fn unset_buffers(&self, buf: &mut WriteBuf<'_>) {
buf.set_dst(self.inner.borrow_mut().get_mut().inner_write_buf.take());
buf.with_read_buf(|b| {
b.set_src(self.inner.borrow_mut().get_mut().inner_read_buf.take())
});
}
}
impl FilterLayer for SslFilter {
fn query(&self, id: any::TypeId) -> Option<Box<dyn any::Any>> {
const H2: &[u8] = b"h2";
@ -116,86 +144,37 @@ impl<F: Filter> Filter for SslFilter<F> {
None
}
} else {
self.inner.borrow().get_ref().inner.query(id)
None
}
}
fn poll_shutdown(&self) -> Poll<io::Result<()>> {
let ssl_result = self.inner.borrow_mut().shutdown();
fn shutdown(&self, buf: &mut WriteBuf<'_>) -> io::Result<Poll<()>> {
let ssl_result = self.with_buffers(buf, || self.inner.borrow_mut().shutdown());
match ssl_result {
Ok(ssl::ShutdownResult::Sent) => Poll::Pending,
Ok(ssl::ShutdownResult::Received) => {
self.inner.borrow().get_ref().inner.poll_shutdown()
}
Err(ref e) if e.code() == ssl::ErrorCode::ZERO_RETURN => {
self.inner.borrow().get_ref().inner.poll_shutdown()
}
Ok(ssl::ShutdownResult::Sent) => Ok(Poll::Pending),
Ok(ssl::ShutdownResult::Received) => Ok(Poll::Ready(())),
Err(ref e) if e.code() == ssl::ErrorCode::ZERO_RETURN => Ok(Poll::Ready(())),
Err(ref e)
if e.code() == ssl::ErrorCode::WANT_READ
|| e.code() == ssl::ErrorCode::WANT_WRITE =>
{
Poll::Pending
Ok(Poll::Pending)
}
Err(e) => Poll::Ready(Err(e
Err(e) => Err(e
.into_io_error()
.unwrap_or_else(|e| io::Error::new(io::ErrorKind::Other, e)))),
.unwrap_or_else(|e| io::Error::new(io::ErrorKind::Other, e))),
}
}
#[inline]
fn poll_read_ready(&self, cx: &mut Context<'_>) -> Poll<ReadStatus> {
self.inner.borrow().get_ref().inner.poll_read_ready(cx)
}
#[inline]
fn poll_write_ready(&self, cx: &mut Context<'_>) -> Poll<WriteStatus> {
self.inner.borrow().get_ref().inner.poll_write_ready(cx)
}
#[inline]
fn get_read_buf(&self) -> Option<BytesVec> {
self.read_buf.take()
}
#[inline]
fn get_write_buf(&self) -> Option<BytesVec> {
self.inner.borrow_mut().get_mut().write_buf.take()
}
#[inline]
fn release_read_buf(&self, buf: BytesVec) {
self.read_buf.set(Some(buf));
}
fn process_read_buf(&self, io: &IoRef, nbytes: usize) -> io::Result<(usize, usize)> {
// ask inner filter to process read buf
match self
.inner
.borrow_mut()
.get_ref()
.inner
.process_read_buf(io, nbytes)
{
Err(err) => io.want_shutdown(Some(err)),
Ok((n, 0)) => return Ok((n, 0)),
Ok((_, _)) => (),
}
// get processed buffer
let mut dst = if let Some(dst) = self.get_read_buf() {
dst
} else {
self.pool.get_read_buf()
};
let (hw, lw) = self.pool.read_params().unpack();
fn process_read_buf(&self, buf: &mut ReadBuf<'_>) -> io::Result<usize> {
buf.with_write_buf(|b| self.set_buffers(b));
let dst = buf.get_dst();
let mut new_bytes = usize::from(self.handshake.get());
loop {
// make sure we've got room
let remaining = dst.remaining_mut();
if remaining < lw {
dst.reserve(hw - remaining);
}
self.pool.resize_read_buf(dst);
let chunk: &mut [u8] = unsafe { std::mem::transmute(&mut *dst.chunk_mut()) };
let ssl_result = self.inner.borrow_mut().ssl_read(chunk);
@ -209,43 +188,61 @@ impl<F: Filter> Filter for SslFilter<F> {
if e.code() == ssl::ErrorCode::WANT_READ
|| e.code() == ssl::ErrorCode::WANT_WRITE =>
{
Ok((dst.len(), new_bytes))
Ok(new_bytes)
}
Err(ref e) if e.code() == ssl::ErrorCode::ZERO_RETURN => {
io.want_shutdown(None);
Ok((dst.len(), new_bytes))
buf.want_shutdown();
Ok(new_bytes)
}
Err(e) => {
log::trace!("SSL Error: {:?}", e);
Err(map_to_ioerr(e))
}
};
self.release_read_buf(dst);
buf.with_write_buf(|b| self.unset_buffers(b));
return result;
}
}
fn release_write_buf(&self, mut buf: BytesVec) -> Result<(), io::Error> {
loop {
if buf.is_empty() {
return Ok(());
}
let ssl_result = self.inner.borrow_mut().ssl_write(&buf);
match ssl_result {
Ok(v) => {
buf.split_to(v);
continue;
fn process_write_buf(&self, buf: &mut WriteBuf<'_>) -> io::Result<()> {
if let Some(mut src) = buf.take_src() {
self.set_buffers(buf);
loop {
if src.is_empty() {
self.unset_buffers(buf);
return Ok(());
}
Err(e) => {
if !buf.is_empty() {
self.inner.borrow_mut().get_mut().write_buf = Some(buf);
let ssl_result = self.inner.borrow_mut().ssl_write(&src);
match ssl_result {
Ok(v) => {
src.split_to(v);
continue;
}
Err(e) => {
if !src.is_empty() {
buf.set_src(Some(src));
}
self.unset_buffers(buf);
return match e.code() {
ssl::ErrorCode::WANT_READ | ssl::ErrorCode::WANT_WRITE => {
buf.set_dst(
self.inner
.borrow_mut()
.get_mut()
.inner_write_buf
.take(),
);
Ok(())
}
_ => Err(map_to_ioerr(e)),
};
}
return match e.code() {
ssl::ErrorCode::WANT_READ | ssl::ErrorCode::WANT_WRITE => Ok(()),
_ => Err(map_to_ioerr(e)),
};
}
}
} else {
Ok(())
}
}
}
@ -283,42 +280,47 @@ impl Clone for SslAcceptor {
}
impl<F: Filter> FilterFactory<F> for SslAcceptor {
type Filter = SslFilter<F>;
type Filter = SslFilter;
type Error = Box<dyn Error>;
type Future = BoxFuture<'static, Result<Io<Self::Filter>, Self::Error>>;
type Future = BoxFuture<'static, Result<Io<Layer<Self::Filter, F>>, Self::Error>>;
fn create(self, st: Io<F>) -> Self::Future {
fn create(self, io: Io<F>) -> Self::Future {
let timeout = self.timeout;
let ctx_result = ssl::Ssl::new(self.acceptor.context());
Box::pin(async move {
time::timeout(timeout, async {
let ssl = ctx_result.map_err(map_to_ioerr)?;
let pool = st.memory_pool();
let st = st.map_filter(|inner: F| {
let inner = IoInner {
pool,
inner,
write_buf: None,
};
let ssl_stream = ssl::SslStream::new(ssl, inner)?;
Ok::<_, Box<dyn Error>>(SslFilter {
pool,
read_buf: Cell::new(None),
handshake: Cell::new(true),
inner: RefCell::new(ssl_stream),
})
})?;
let inner = IoInner {
pool: io.memory_pool(),
inner_read_buf: None,
inner_write_buf: None,
};
let filter = SslFilter {
pool: io.memory_pool(),
handshake: Cell::new(true),
inner: RefCell::new(ssl::SslStream::new(ssl, inner)?),
};
let io = io.add_filter(filter);
poll_fn(|cx| {
handle_result(st.filter().inner.borrow_mut().accept(), &st, cx)
let result = io
.with_buf(|buf| {
let filter = io.filter();
filter.with_buffers(buf, || filter.inner.borrow_mut().accept())
})
.map_err(|err| {
let err: Box<dyn Error> =
io::Error::new(io::ErrorKind::Other, err).into();
err
})?;
handle_result(result, &io, cx)
})
.await?;
st.filter().handshake.set(false);
Ok(st)
io.filter().handshake.set(false);
Ok(io)
})
.await
.map_err(|_| {
@ -341,35 +343,42 @@ impl SslConnector {
}
impl<F: Filter> FilterFactory<F> for SslConnector {
type Filter = SslFilter<F>;
type Filter = SslFilter;
type Error = Box<dyn Error>;
type Future = BoxFuture<'static, Result<Io<Self::Filter>, Self::Error>>;
type Future = BoxFuture<'static, Result<Io<Layer<Self::Filter, F>>, Self::Error>>;
fn create(self, st: Io<F>) -> Self::Future {
fn create(self, io: Io<F>) -> Self::Future {
Box::pin(async move {
let ssl = self.ssl;
let pool = st.memory_pool();
let st = st.map_filter(|inner: F| {
let inner = IoInner {
pool,
inner,
write_buf: None,
};
let ssl_stream = ssl::SslStream::new(ssl, inner)?;
let inner = IoInner {
pool: io.memory_pool(),
inner_read_buf: None,
inner_write_buf: None,
};
let filter = SslFilter {
pool: io.memory_pool(),
handshake: Cell::new(true),
inner: RefCell::new(ssl::SslStream::new(self.ssl, inner)?),
};
let io = io.add_filter(filter);
Ok::<_, Box<dyn Error>>(SslFilter {
pool,
read_buf: Cell::new(None),
handshake: Cell::new(true),
inner: RefCell::new(ssl_stream),
})
})?;
poll_fn(|cx| {
let result = io
.with_buf(|buf| {
let filter = io.filter();
filter.with_buffers(buf, || filter.inner.borrow_mut().connect())
})
.map_err(|err| {
let err: Box<dyn Error> =
io::Error::new(io::ErrorKind::Other, err).into();
err
})?;
handle_result(result, &io, cx)
})
.await?;
poll_fn(|cx| handle_result(st.filter().inner.borrow_mut().connect(), &st, cx))
.await?;
Ok(st)
io.filter().handshake.set(false);
Ok(io)
})
}
}

View file

@ -3,7 +3,7 @@ use std::{future::Future, io, marker::PhantomData, pin::Pin, sync::Arc};
use tls_rust::ServerConfig;
use ntex_io::{Filter, FilterFactory, Io};
use ntex_io::{Filter, FilterFactory, Io, Layer};
use ntex_service::{Service, ServiceFactory};
use ntex_util::{future::Ready, time::Millis};
@ -52,7 +52,7 @@ impl<F> Clone for Acceptor<F> {
}
impl<F: Filter, C: 'static> ServiceFactory<Io<F>, C> for Acceptor<F> {
type Response = Io<TlsFilter<F>>;
type Response = Io<Layer<TlsFilter, F>>;
type Error = io::Error;
type Service = AcceptorService<F>;
@ -79,7 +79,7 @@ pub struct AcceptorService<F> {
}
impl<F: Filter> Service<Io<F>> for AcceptorService<F> {
type Response = Io<TlsFilter<F>>;
type Response = Io<Layer<TlsFilter, F>>;
type Error = io::Error;
type Future<'f> = AcceptorServiceFut<F>;
@ -113,7 +113,7 @@ pin_project_lite::pin_project! {
}
impl<F: Filter> Future for AcceptorServiceFut<F> {
type Output = Result<Io<TlsFilter<F>>, io::Error>;
type Output = Result<Io<Layer<TlsFilter, F>>, io::Error>;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
self.project().fut.poll(cx)

View file

@ -1,9 +1,9 @@
//! An implementation of SSL streams for ntex backed by OpenSSL
use std::io::{self, Read as IoRead, Write as IoWrite};
use std::{any, cell::Cell, cell::RefCell, sync::Arc, task::Context, task::Poll};
use std::{any, cell::Cell, cell::RefCell, sync::Arc, task::Poll};
use ntex_bytes::{BufMut, BytesVec};
use ntex_io::{types, Filter, Io, IoRef, ReadStatus, WriteStatus};
use ntex_bytes::BufMut;
use ntex_io::{types, Filter, FilterLayer, Io, Layer, ReadBuf, WriteBuf};
use ntex_util::{future::poll_fn, ready};
use tls_rust::{ClientConfig, ClientConnection, ServerName};
@ -12,12 +12,12 @@ use crate::rustls::{IoInner, TlsFilter, Wrapper};
use super::{PeerCert, PeerCertChain};
/// An implementation of SSL streams
pub struct TlsClientFilter<F> {
inner: IoInner<F>,
pub struct TlsClientFilter {
inner: IoInner,
session: RefCell<ClientConnection>,
}
impl<F: Filter> Filter for TlsClientFilter<F> {
impl FilterLayer for TlsClientFilter {
fn query(&self, id: any::TypeId) -> Option<Box<dyn any::Any>> {
const H2: &[u8] = b"h2";
@ -52,71 +52,19 @@ impl<F: Filter> Filter for TlsClientFilter<F> {
None
}
} else {
self.inner.filter.query(id)
None
}
}
#[inline]
fn poll_shutdown(&self) -> Poll<io::Result<()>> {
self.inner.filter.poll_shutdown()
}
#[inline]
fn poll_read_ready(&self, cx: &mut Context<'_>) -> Poll<ReadStatus> {
self.inner.filter.poll_read_ready(cx)
}
#[inline]
fn poll_write_ready(&self, cx: &mut Context<'_>) -> Poll<WriteStatus> {
self.inner.filter.poll_write_ready(cx)
}
#[inline]
fn get_read_buf(&self) -> Option<BytesVec> {
self.inner.read_buf.take()
}
#[inline]
fn get_write_buf(&self) -> Option<BytesVec> {
self.inner.write_buf.take()
}
#[inline]
fn release_read_buf(&self, buf: BytesVec) {
self.inner.read_buf.set(Some(buf));
}
fn process_read_buf(&self, io: &IoRef, nbytes: usize) -> io::Result<(usize, usize)> {
fn process_read_buf(&self, buf: &mut ReadBuf<'_>) -> io::Result<usize> {
let mut session = self.session.borrow_mut();
// ask inner filter to process read buf
match self.inner.filter.process_read_buf(io, nbytes) {
Err(err) => io.want_shutdown(Some(err)),
Ok((_, 0)) => return Ok((0, 0)),
Ok(_) => (),
}
// get processed buffer
let mut dst = if let Some(dst) = self.inner.read_buf.take() {
dst
} else {
self.inner.pool.get_read_buf()
};
let (hw, lw) = self.inner.pool.read_params().unpack();
let mut src = if let Some(src) = self.inner.filter.get_read_buf() {
src
} else {
return Ok((0, 0));
};
let (src, dst) = buf.get_pair();
let mut new_bytes = usize::from(self.inner.handshake.get());
loop {
// make sure we've got room
let remaining = dst.remaining_mut();
if remaining < lw {
dst.reserve(hw - remaining);
}
self.inner.pool.resize_read_buf(dst);
let mut cursor = io::Cursor::new(&src);
let n = session.read_tls(&mut cursor)?;
@ -138,73 +86,74 @@ impl<F: Filter> Filter for TlsClientFilter<F> {
}
}
let dst_len = dst.len();
self.inner.read_buf.set(Some(dst));
self.inner.filter.release_read_buf(src);
Ok((dst_len, new_bytes))
Ok(new_bytes)
}
fn release_write_buf(&self, mut src: BytesVec) -> Result<(), io::Error> {
let mut session = self.session.borrow_mut();
let mut io = Wrapper(&self.inner);
fn process_write_buf(&self, buf: &mut WriteBuf<'_>) -> io::Result<()> {
if let Some(mut src) = buf.take_src() {
let mut session = self.session.borrow_mut();
let mut io = Wrapper(&self.inner, buf);
loop {
if !src.is_empty() {
let n = session.writer().write(&src)?;
src.split_to(n);
}
if session.wants_write() {
session.complete_io(&mut io)?;
} else {
break;
}
}
loop {
if !src.is_empty() {
let n = session.writer().write(&src)?;
src.split_to(n);
}
let n = session.write_tls(&mut io)?;
if n == 0 {
break;
buf.set_src(Some(src));
}
Ok(())
} else {
Ok(())
}
if !src.is_empty() {
self.inner.write_buf.set(Some(src));
}
Ok(())
}
}
impl<F: Filter> TlsClientFilter<F> {
pub(crate) async fn create(
impl TlsClientFilter {
pub(crate) async fn create<F: Filter>(
io: Io<F>,
cfg: Arc<ClientConfig>,
domain: ServerName,
) -> Result<Io<TlsFilter<F>>, io::Error> {
let pool = io.memory_pool();
let session = match ClientConnection::new(cfg, domain) {
Ok(session) => session,
Err(error) => return Err(io::Error::new(io::ErrorKind::Other, error)),
};
let io = io.map_filter(|filter: F| {
let inner = IoInner {
pool,
filter,
read_buf: Cell::new(None),
write_buf: Cell::new(None),
) -> Result<Io<Layer<TlsFilter, F>>, io::Error> {
let session = ClientConnection::new(cfg, domain)
.map_err(|err| io::Error::new(io::ErrorKind::Other, err))?;
let filter = TlsFilter::new_client(TlsClientFilter {
inner: IoInner {
pool: io.memory_pool(),
handshake: Cell::new(true),
};
Ok::<_, io::Error>(TlsFilter::new_client(TlsClientFilter {
inner,
session: RefCell::new(session),
}))
})?;
},
session: RefCell::new(session),
});
let io = io.add_filter(filter);
let filter = io.filter();
loop {
let (result, wants_read, handshaking) = {
let (result, wants_read, handshaking) = io.with_buf(|buf| {
let mut session = filter.client().session.borrow_mut();
let mut wrp = Wrapper(&filter.client().inner);
(
let mut wrp = Wrapper(&filter.client().inner, buf);
let mut result = (
session.complete_io(&mut wrp),
session.wants_read(),
session.is_handshaking(),
)
};
);
while session.wants_write() {
result.0 = session.complete_io(&mut wrp);
if result.0.is_err() {
break;
}
}
result
})?;
match result {
Ok(_) => {
filter.client().inner.handshake.set(false);

View file

@ -1,11 +1,13 @@
#![allow(clippy::type_complexity)]
//! An implementation of SSL streams for ntex backed by OpenSSL
use std::{any, cmp, future::Future, io, pin::Pin, task::Context, task::Poll};
use std::{cell::Cell, sync::Arc};
use std::{any, cell::Cell, cmp, io, sync::Arc, task::Context, task::Poll};
use ntex_bytes::{BytesVec, PoolRef};
use ntex_io::{Base, Filter, FilterFactory, Io, IoRef, ReadStatus, WriteStatus};
use ntex_util::time::Millis;
use ntex_bytes::PoolRef;
use ntex_io::{
Filter, FilterFactory, FilterLayer, Io, Layer, ReadBuf, ReadStatus, WriteBuf,
WriteStatus,
};
use ntex_util::{future::BoxFuture, time::Millis};
use tls_rust::{Certificate, ClientConfig, ServerConfig, ServerName};
mod accept;
@ -25,33 +27,33 @@ pub struct PeerCert(pub Certificate);
pub struct PeerCertChain(pub Vec<Certificate>);
/// An implementation of SSL streams
pub struct TlsFilter<F = Base> {
inner: InnerTlsFilter<F>,
pub struct TlsFilter {
inner: InnerTlsFilter,
}
enum InnerTlsFilter<F> {
Server(TlsServerFilter<F>),
Client(TlsClientFilter<F>),
enum InnerTlsFilter {
Server(TlsServerFilter),
Client(TlsClientFilter),
}
impl<F> TlsFilter<F> {
fn new_server(server: TlsServerFilter<F>) -> Self {
impl TlsFilter {
fn new_server(server: TlsServerFilter) -> Self {
TlsFilter {
inner: InnerTlsFilter::Server(server),
}
}
fn new_client(client: TlsClientFilter<F>) -> Self {
fn new_client(client: TlsClientFilter) -> Self {
TlsFilter {
inner: InnerTlsFilter::Client(client),
}
}
fn server(&self) -> &TlsServerFilter<F> {
fn server(&self) -> &TlsServerFilter {
match self.inner {
InnerTlsFilter::Server(ref server) => server,
_ => unreachable!(),
}
}
fn client(&self) -> &TlsClientFilter<F> {
fn client(&self) -> &TlsClientFilter {
match self.inner {
InnerTlsFilter::Client(ref server) => server,
_ => unreachable!(),
@ -59,7 +61,7 @@ impl<F> TlsFilter<F> {
}
}
impl<F: Filter> Filter for TlsFilter<F> {
impl FilterLayer for TlsFilter {
#[inline]
fn query(&self, id: any::TypeId) -> Option<Box<dyn any::Any>> {
match self.inner {
@ -69,10 +71,10 @@ impl<F: Filter> Filter for TlsFilter<F> {
}
#[inline]
fn poll_shutdown(&self) -> Poll<io::Result<()>> {
fn shutdown(&self, buf: &mut WriteBuf<'_>) -> io::Result<Poll<()>> {
match self.inner {
InnerTlsFilter::Server(ref f) => f.poll_shutdown(),
InnerTlsFilter::Client(ref f) => f.poll_shutdown(),
InnerTlsFilter::Server(ref f) => f.shutdown(buf),
InnerTlsFilter::Client(ref f) => f.shutdown(buf),
}
}
@ -93,42 +95,18 @@ impl<F: Filter> Filter for TlsFilter<F> {
}
#[inline]
fn get_read_buf(&self) -> Option<BytesVec> {
fn process_read_buf(&self, buf: &mut ReadBuf<'_>) -> io::Result<usize> {
match self.inner {
InnerTlsFilter::Server(ref f) => f.get_read_buf(),
InnerTlsFilter::Client(ref f) => f.get_read_buf(),
InnerTlsFilter::Server(ref f) => f.process_read_buf(buf),
InnerTlsFilter::Client(ref f) => f.process_read_buf(buf),
}
}
#[inline]
fn get_write_buf(&self) -> Option<BytesVec> {
fn process_write_buf(&self, buf: &mut WriteBuf<'_>) -> io::Result<()> {
match self.inner {
InnerTlsFilter::Server(ref f) => f.get_write_buf(),
InnerTlsFilter::Client(ref f) => f.get_write_buf(),
}
}
#[inline]
fn release_read_buf(&self, buf: BytesVec) {
match self.inner {
InnerTlsFilter::Server(ref f) => f.release_read_buf(buf),
InnerTlsFilter::Client(ref f) => f.release_read_buf(buf),
}
}
#[inline]
fn process_read_buf(&self, io: &IoRef, nb: usize) -> io::Result<(usize, usize)> {
match self.inner {
InnerTlsFilter::Server(ref f) => f.process_read_buf(io, nb),
InnerTlsFilter::Client(ref f) => f.process_read_buf(io, nb),
}
}
#[inline]
fn release_write_buf(&self, src: BytesVec) -> Result<(), io::Error> {
match self.inner {
InnerTlsFilter::Server(ref f) => f.release_write_buf(src),
InnerTlsFilter::Client(ref f) => f.release_write_buf(src),
InnerTlsFilter::Server(ref f) => f.process_write_buf(buf),
InnerTlsFilter::Client(ref f) => f.process_write_buf(buf),
}
}
}
@ -172,10 +150,10 @@ impl Clone for TlsAcceptor {
}
impl<F: Filter> FilterFactory<F> for TlsAcceptor {
type Filter = TlsFilter<F>;
type Filter = TlsFilter;
type Error = io::Error;
type Future = Pin<Box<dyn Future<Output = Result<Io<Self::Filter>, io::Error>>>>;
type Future = BoxFuture<'static, Result<Io<Layer<Self::Filter, F>>, io::Error>>;
fn create(self, st: Io<F>) -> Self::Future {
let cfg = self.cfg.clone();
@ -227,10 +205,10 @@ impl Clone for TlsConnectorConfigured {
}
impl<F: Filter> FilterFactory<F> for TlsConnectorConfigured {
type Filter = TlsFilter<F>;
type Filter = TlsFilter;
type Error = io::Error;
type Future = Pin<Box<dyn Future<Output = Result<Io<Self::Filter>, io::Error>>>>;
type Future = BoxFuture<'static, Result<Io<Layer<Self::Filter, F>>, io::Error>>;
fn create(self, st: Io<F>) -> Self::Future {
let cfg = self.cfg;
@ -240,44 +218,31 @@ impl<F: Filter> FilterFactory<F> for TlsConnectorConfigured {
}
}
pub(crate) struct IoInner<F> {
filter: F,
pub(crate) struct IoInner {
pool: PoolRef,
read_buf: Cell<Option<BytesVec>>,
write_buf: Cell<Option<BytesVec>>,
handshake: Cell<bool>,
}
pub(crate) struct Wrapper<'a, F>(&'a IoInner<F>);
pub(crate) struct Wrapper<'a, 'b>(&'a IoInner, &'a mut WriteBuf<'b>);
impl<'a, F: Filter> io::Read for Wrapper<'a, F> {
impl<'a, 'b> io::Read for Wrapper<'a, 'b> {
fn read(&mut self, dst: &mut [u8]) -> io::Result<usize> {
if let Some(mut read_buf) = self.0.filter.get_read_buf() {
self.1.with_read_buf(|buf| {
let read_buf = buf.get_src();
let len = cmp::min(read_buf.len(), dst.len());
let result = if len > 0 {
if len > 0 {
dst[..len].copy_from_slice(&read_buf.split_to(len));
Ok(len)
} else {
Err(io::Error::new(io::ErrorKind::WouldBlock, ""))
};
self.0.filter.release_read_buf(read_buf);
result
} else {
Err(io::Error::new(io::ErrorKind::WouldBlock, ""))
}
}
})
}
}
impl<'a, F: Filter> io::Write for Wrapper<'a, F> {
impl<'a, 'b> io::Write for Wrapper<'a, 'b> {
fn write(&mut self, src: &[u8]) -> io::Result<usize> {
let mut buf = if let Some(mut buf) = self.0.filter.get_write_buf() {
buf.reserve(src.len());
buf
} else {
BytesVec::with_capacity_in(src.len(), self.0.pool)
};
buf.extend_from_slice(src);
self.0.filter.release_write_buf(buf)?;
self.1.get_dst().extend_from_slice(src);
Ok(src.len())
}

View file

@ -1,9 +1,9 @@
//! An implementation of SSL streams for ntex backed by OpenSSL
use std::io::{self, Read as IoRead, Write as IoWrite};
use std::{any, cell::Cell, cell::RefCell, sync::Arc, task::Context, task::Poll};
use std::{any, cell::Cell, cell::RefCell, sync::Arc, task::Poll};
use ntex_bytes::{BufMut, BytesVec};
use ntex_io::{types, Filter, Io, IoRef, ReadStatus, WriteStatus};
use ntex_bytes::BufMut;
use ntex_io::{types, Filter, FilterLayer, Io, Layer, ReadBuf, WriteBuf};
use ntex_util::{future::poll_fn, ready, time, time::Millis};
use tls_rust::{ServerConfig, ServerConnection};
@ -13,12 +13,12 @@ use crate::Servername;
use super::{PeerCert, PeerCertChain};
/// An implementation of SSL streams
pub struct TlsServerFilter<F> {
inner: IoInner<F>,
pub struct TlsServerFilter {
inner: IoInner,
session: RefCell<ServerConnection>,
}
impl<F: Filter> Filter for TlsServerFilter<F> {
impl FilterLayer for TlsServerFilter {
fn query(&self, id: any::TypeId) -> Option<Box<dyn any::Any>> {
const H2: &[u8] = b"h2";
@ -59,71 +59,19 @@ impl<F: Filter> Filter for TlsServerFilter<F> {
None
}
} else {
self.inner.filter.query(id)
None
}
}
#[inline]
fn poll_shutdown(&self) -> Poll<io::Result<()>> {
self.inner.filter.poll_shutdown()
}
#[inline]
fn poll_read_ready(&self, cx: &mut Context<'_>) -> Poll<ReadStatus> {
self.inner.filter.poll_read_ready(cx)
}
#[inline]
fn poll_write_ready(&self, cx: &mut Context<'_>) -> Poll<WriteStatus> {
self.inner.filter.poll_write_ready(cx)
}
#[inline]
fn get_read_buf(&self) -> Option<BytesVec> {
self.inner.read_buf.take()
}
#[inline]
fn get_write_buf(&self) -> Option<BytesVec> {
self.inner.write_buf.take()
}
#[inline]
fn release_read_buf(&self, buf: BytesVec) {
self.inner.read_buf.set(Some(buf));
}
fn process_read_buf(&self, io: &IoRef, nbytes: usize) -> io::Result<(usize, usize)> {
fn process_read_buf(&self, buf: &mut ReadBuf<'_>) -> io::Result<usize> {
let mut session = self.session.borrow_mut();
// ask inner filter to process read buf
match self.inner.filter.process_read_buf(io, nbytes) {
Err(err) => io.want_shutdown(Some(err)),
Ok((_, 0)) => return Ok((0, 0)),
Ok(_) => (),
}
// get processed buffer
let mut dst = if let Some(dst) = self.inner.read_buf.take() {
dst
} else {
self.inner.pool.get_read_buf()
};
let (hw, lw) = self.inner.pool.read_params().unpack();
let mut src = if let Some(src) = self.inner.filter.get_read_buf() {
src
} else {
return Ok((0, 0));
};
let (src, dst) = buf.get_pair();
let mut new_bytes = usize::from(self.inner.handshake.get());
loop {
// make sure we've got room
let remaining = dst.remaining_mut();
if remaining < lw {
dst.reserve(hw - remaining);
}
self.inner.pool.resize_read_buf(dst);
let mut cursor = io::Cursor::new(&src);
let n = session.read_tls(&mut cursor)?;
@ -145,73 +93,73 @@ impl<F: Filter> Filter for TlsServerFilter<F> {
}
}
let dst_len = dst.len();
self.inner.read_buf.set(Some(dst));
self.inner.filter.release_read_buf(src);
Ok((dst_len, new_bytes))
Ok(new_bytes)
}
fn release_write_buf(&self, mut src: BytesVec) -> Result<(), io::Error> {
let mut session = self.session.borrow_mut();
let mut io = Wrapper(&self.inner);
fn process_write_buf(&self, buf: &mut WriteBuf<'_>) -> io::Result<()> {
if let Some(mut src) = buf.take_src() {
let mut session = self.session.borrow_mut();
let mut io = Wrapper(&self.inner, buf);
loop {
if !src.is_empty() {
let n = session.writer().write(&src)?;
src.split_to(n);
}
if session.wants_write() {
session.complete_io(&mut io)?;
} else {
break;
}
}
loop {
if !src.is_empty() {
let n = session.writer().write(&src)?;
src.split_to(n);
buf.set_src(Some(src));
}
let n = session.write_tls(&mut io)?;
if n == 0 {
break;
}
}
if !src.is_empty() {
self.inner.write_buf.set(Some(src));
}
Ok(())
}
}
impl<F: Filter> TlsServerFilter<F> {
pub(crate) async fn create(
impl TlsServerFilter {
pub(crate) async fn create<F: Filter>(
io: Io<F>,
cfg: Arc<ServerConfig>,
timeout: Millis,
) -> Result<Io<TlsFilter<F>>, io::Error> {
) -> Result<Io<Layer<TlsFilter, F>>, io::Error> {
time::timeout(timeout, async {
let pool = io.memory_pool();
let session = match ServerConnection::new(cfg) {
Ok(session) => session,
Err(error) => return Err(io::Error::new(io::ErrorKind::Other, error)),
};
let io = io.map_filter(|filter: F| {
let inner = IoInner {
pool,
filter,
read_buf: Cell::new(None),
write_buf: Cell::new(None),
let session = ServerConnection::new(cfg)
.map_err(|err| io::Error::new(io::ErrorKind::Other, err))?;
let filter = TlsFilter::new_server(TlsServerFilter {
session: RefCell::new(session),
inner: IoInner {
pool: io.memory_pool(),
handshake: Cell::new(true),
};
Ok::<_, io::Error>(TlsFilter::new_server(TlsServerFilter {
inner,
session: RefCell::new(session),
}))
})?;
},
});
let io = io.add_filter(filter);
let filter = io.filter();
loop {
let (result, wants_read, handshaking) = {
let (result, wants_read, handshaking) = io.with_buf(|buf| {
let mut session = filter.server().session.borrow_mut();
let mut wrp = Wrapper(&filter.server().inner);
(
let mut wrp = Wrapper(&filter.server().inner, buf);
let mut result = (
session.complete_io(&mut wrp),
session.wants_read(),
session.is_handshaking(),
)
};
);
while session.wants_write() {
result.0 = session.complete_io(&mut wrp);
if result.0.is_err() {
break;
}
}
result
})?;
match result {
Ok(_) => {
filter.server().inner.handshake.set(false);