From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by lists.proxmox.com (Postfix) with ESMTPS id 2F7757520A for ; Wed, 21 Apr 2021 13:17:39 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 1A7ACDC8B for ; Wed, 21 Apr 2021 13:17:09 +0200 (CEST) Received: from elsa.proxmox.com (unknown [94.136.29.99]) by firstgate.proxmox.com (Proxmox) with ESMTP id 989B4DC68 for ; Wed, 21 Apr 2021 13:17:04 +0200 (CEST) Received: by elsa.proxmox.com (Postfix, from userid 0) id 7BC8FAEAF1D; Wed, 21 Apr 2021 13:17:04 +0200 (CEST) From: Dietmar Maurer To: pbs-devel@lists.proxmox.com Date: Wed, 21 Apr 2021 13:16:58 +0200 Message-Id: <20210421111702.19095-2-dietmar@proxmox.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20210421111702.19095-1-dietmar@proxmox.com> References: <20210421111702.19095-1-dietmar@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-SPAM-LEVEL: Spam detection results: 1 AWL -0.024 Adjusted score from AWL reputation of From: address KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment RDNS_NONE 1.274 Delivered to internal network by a host with no rDNS SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record URIBL_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to URIBL was blocked. See http://wiki.apache.org/spamassassin/DnsBlocklists#dnsbl-block for more information. [http.rs] Subject: [pbs-devel] [RFC proxmox-backup 1/5] http: rename EitherStream to MaybeTlsStream X-BeenThere: pbs-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox Backup Server development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 21 Apr 2021 11:17:39 -0000 And rename the enum values. Added an additional enum called Proxied. The enum in now more specialized, but we only use it for the http client anyways. --- src/tools/async_io.rs | 64 +++++++++++++++++++++++++++---------------- src/tools/http.rs | 20 ++++++-------- 2 files changed, 48 insertions(+), 36 deletions(-) diff --git a/src/tools/async_io.rs b/src/tools/async_io.rs index 844afaa9..963f6fdd 100644 --- a/src/tools/async_io.rs +++ b/src/tools/async_io.rs @@ -1,4 +1,4 @@ -//! Generic AsyncRead/AsyncWrite utilities. +//! AsyncRead/AsyncWrite utilities. use std::io; use std::os::unix::io::{AsRawFd, RawFd}; @@ -9,41 +9,52 @@ use futures::stream::{Stream, TryStream}; use futures::ready; use tokio::io::{AsyncRead, AsyncWrite, ReadBuf}; use tokio::net::TcpListener; -use hyper::client::connect::Connection; - -pub enum EitherStream { - Left(L), - Right(R), +use tokio_openssl::SslStream; +use hyper::client::connect::{Connection, Connected}; + +/// Asynchronous stream, possibly encrypted and proxied +/// +/// Usefule for HTTP client implementations using hyper. +pub enum MaybeTlsStream { + Normal(S), + Proxied(S), + Secured(SslStream), } -impl AsyncRead for EitherStream { +impl AsyncRead for MaybeTlsStream { fn poll_read( self: Pin<&mut Self>, cx: &mut Context, buf: &mut ReadBuf, ) -> Poll> { match self.get_mut() { - EitherStream::Left(ref mut s) => { + MaybeTlsStream::Normal(ref mut s) => { + Pin::new(s).poll_read(cx, buf) + } + MaybeTlsStream::Proxied(ref mut s) => { Pin::new(s).poll_read(cx, buf) } - EitherStream::Right(ref mut s) => { + MaybeTlsStream::Secured(ref mut s) => { Pin::new(s).poll_read(cx, buf) } } } } -impl AsyncWrite for EitherStream { +impl AsyncWrite for MaybeTlsStream { fn poll_write( self: Pin<&mut Self>, cx: &mut Context, buf: &[u8], ) -> Poll> { match self.get_mut() { - EitherStream::Left(ref mut s) => { + MaybeTlsStream::Normal(ref mut s) => { + Pin::new(s).poll_write(cx, buf) + } + MaybeTlsStream::Proxied(ref mut s) => { Pin::new(s).poll_write(cx, buf) } - EitherStream::Right(ref mut s) => { + MaybeTlsStream::Secured(ref mut s) => { Pin::new(s).poll_write(cx, buf) } } @@ -51,10 +62,13 @@ impl AsyncWrite for EitherStream, cx: &mut Context) -> Poll> { match self.get_mut() { - EitherStream::Left(ref mut s) => { + MaybeTlsStream::Normal(ref mut s) => { Pin::new(s).poll_flush(cx) } - EitherStream::Right(ref mut s) => { + MaybeTlsStream::Proxied(ref mut s) => { + Pin::new(s).poll_flush(cx) + } + MaybeTlsStream::Secured(ref mut s) => { Pin::new(s).poll_flush(cx) } } @@ -62,25 +76,27 @@ impl AsyncWrite for EitherStream, cx: &mut Context) -> Poll> { match self.get_mut() { - EitherStream::Left(ref mut s) => { + MaybeTlsStream::Normal(ref mut s) => { Pin::new(s).poll_shutdown(cx) } - EitherStream::Right(ref mut s) => { + MaybeTlsStream::Proxied(ref mut s) => { + Pin::new(s).poll_shutdown(cx) + } + MaybeTlsStream::Secured(ref mut s) => { Pin::new(s).poll_shutdown(cx) } } } } -// we need this for crate::client::http_client: -impl Connection for EitherStream< - tokio::net::TcpStream, - Pin>>, -> { - fn connected(&self) -> hyper::client::connect::Connected { +// we need this for the hyper http client +impl Connection for MaybeTlsStream +{ + fn connected(&self) -> Connected { match self { - EitherStream::Left(s) => s.connected(), - EitherStream::Right(s) => s.get_ref().connected(), + MaybeTlsStream::Normal(s) => s.connected(), + MaybeTlsStream::Proxied(s) => s.connected().proxy(true), + MaybeTlsStream::Secured(s) => s.get_ref().connected(), } } } diff --git a/src/tools/http.rs b/src/tools/http.rs index d08ce451..3cd3af4e 100644 --- a/src/tools/http.rs +++ b/src/tools/http.rs @@ -10,9 +10,11 @@ use hyper::client::{Client, HttpConnector}; use http::{Request, Response}; use openssl::ssl::{SslConnector, SslMethod}; use futures::*; +use tokio::net::TcpStream; +use tokio_openssl::SslStream; use crate::tools::{ - async_io::EitherStream, + async_io::MaybeTlsStream, socket::{ set_tcp_keepalive, PROXMOX_BACKUP_TCP_KEEPALIVE_TIME, @@ -100,13 +102,8 @@ impl HttpsConnector { } } -type MaybeTlsStream = EitherStream< - tokio::net::TcpStream, - Pin>>, ->; - impl hyper::service::Service for HttpsConnector { - type Response = MaybeTlsStream; + type Response = MaybeTlsStream; type Error = Error; #[allow(clippy::type_complexity)] type Future = Pin> + Send + 'static>>; @@ -140,12 +137,11 @@ impl hyper::service::Service for HttpsConnector { let _ = set_tcp_keepalive(conn.as_raw_fd(), PROXMOX_BACKUP_TCP_KEEPALIVE_TIME); if is_https { - let conn: tokio_openssl::SslStream = tokio_openssl::SslStream::new(config?.into_ssl(&host)?, conn)?; - let mut conn = Box::pin(conn); - conn.as_mut().connect().await?; - Ok(MaybeTlsStream::Right(conn)) + let mut conn: SslStream = SslStream::new(config?.into_ssl(&host)?, conn)?; + Pin::new(&mut conn).connect().await?; + Ok(MaybeTlsStream::Secured(conn)) } else { - Ok(MaybeTlsStream::Left(conn)) + Ok(MaybeTlsStream::Normal(conn)) } }.boxed() } -- 2.20.1