diff options
author | Alex Auvolat <alex@adnab.me> | 2021-12-08 23:45:24 +0100 |
---|---|---|
committer | Alex Auvolat <alex@adnab.me> | 2021-12-08 23:45:24 +0100 |
commit | 207f467b879194c993c70a092c232daca8ad1057 (patch) | |
tree | 118c8940e2d9d37400219335263f1ec9c1c94d2d /src/tls_util.rs | |
parent | ca8c5aad2378dd9f8ec525b3b0779f5c53cfe9eb (diff) | |
download | tricot-207f467b879194c993c70a092c232daca8ad1057.tar.gz tricot-207f467b879194c993c70a092c232daca8ad1057.zip |
Support totally ignoring backend HTTPS certificate stuff
Diffstat (limited to 'src/tls_util.rs')
-rw-r--r-- | src/tls_util.rs | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/src/tls_util.rs b/src/tls_util.rs new file mode 100644 index 0000000..054c35a --- /dev/null +++ b/src/tls_util.rs @@ -0,0 +1,79 @@ +use core::future::Future; +use core::task::{Context, Poll}; +use std::convert::TryFrom; +use std::pin::Pin; +use std::sync::Arc; +use std::io; + +use futures_util::future::*; +use rustls::ServerName; +use hyper::client::connect::Connection; +use hyper::client::HttpConnector; +use hyper::service::Service; +use hyper::Uri; +use hyper_rustls::MaybeHttpsStream; +use tokio::io::{AsyncRead, AsyncWrite}; +use tokio_rustls::TlsConnector; + + +#[derive(Clone)] +pub struct HttpsConnectorFixedDnsname<T> { + http: T, + tls_config: Arc<rustls::ClientConfig>, + fixed_dnsname: &'static str, +} +type BoxError = Box<dyn std::error::Error + Send + Sync>; +impl HttpsConnectorFixedDnsname<HttpConnector> { + pub fn new(mut tls_config: rustls::ClientConfig, fixed_dnsname: &'static str) -> Self { + let mut http = HttpConnector::new(); + http.enforce_http(false); + tls_config.alpn_protocols = vec![b"h2".to_vec(), b"http/1.1".to_vec()]; + Self { + http, + tls_config: Arc::new(tls_config), + fixed_dnsname, + } + } +} +impl<T> Service<Uri> for HttpsConnectorFixedDnsname<T> +where + T: Service<Uri>, + T::Response: Connection + AsyncRead + AsyncWrite + Send + Unpin + 'static, + T::Future: Send + 'static, + T::Error: Into<BoxError>, +{ + type Response = MaybeHttpsStream<T::Response>; + type Error = BoxError; + #[allow(clippy::type_complexity)] + type Future = + Pin<Box<dyn Future<Output = Result<MaybeHttpsStream<T::Response>, BoxError>> + Send>>; + + fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> { + match self.http.poll_ready(cx) { + Poll::Ready(Ok(())) => Poll::Ready(Ok(())), + Poll::Ready(Err(e)) => Poll::Ready(Err(e.into())), + Poll::Pending => Poll::Pending, + } + } + + fn call(&mut self, dst: Uri) -> Self::Future { + let is_https = dst.scheme_str() == Some("https"); + assert!(is_https); + + let cfg = self.tls_config.clone(); + let connecting_future = self.http.call(dst); + let dnsname = + ServerName::try_from(self.fixed_dnsname).expect("Invalid fixed dnsname"); + let f = async move { + let tcp = connecting_future.await.map_err(Into::into)?; + let connector = TlsConnector::from(cfg); + let tls = connector + .connect(dnsname, tcp) + .await + .map_err(|e| io::Error::new(io::ErrorKind::Other, e))?; + Ok(MaybeHttpsStream::Https(tls)) + }; + f.boxed() + } +} + |