volo-http 0.5.5

HTTP framework implementation of volo.
Documentation
use http::uri::Scheme;
use motore::service::UnaryService;
use volo::net::{
    conn::{Conn, ConnInfo, ConnStream},
    tls::TlsConnector,
};

use super::{connector::PeerInfo, plain::PlainMakeConnection};
use crate::error::{ClientError, client::request_error};

#[derive(Clone, Debug)]
pub struct TlsMakeConnection<S = PlainMakeConnection> {
    inner: S,
    tls_connector: TlsConnector,
}

impl<S> TlsMakeConnection<S> {
    pub fn new(inner: S, tls_connector: TlsConnector) -> Self {
        Self {
            inner,
            tls_connector,
        }
    }
}

impl<S> UnaryService<PeerInfo> for TlsMakeConnection<S>
where
    S: UnaryService<PeerInfo, Response = Conn, Error = ClientError> + Sync,
{
    type Response = S::Response;
    type Error = S::Error;

    async fn call(&self, req: PeerInfo) -> Result<Self::Response, Self::Error> {
        let conn = self.inner.call(req.clone()).await?;

        if req.scheme == Scheme::HTTP {
            // It's an HTTP request
            return Ok(conn);
        }

        let target_name = req.name;
        tracing::debug!("[Volo-HTTP] try to make tls handshake, name: {target_name:?}");

        let tcp_stream = match conn.stream {
            ConnStream::Tcp(tcp_stream) => tcp_stream,
            _ => unreachable!(),
        };
        match self.tls_connector.connect(&target_name, tcp_stream).await {
            Ok(stream) => Ok(Conn {
                stream,
                info: ConnInfo {
                    peer_addr: Some(req.address),
                },
            }),
            Err(err) => {
                tracing::warn!("[Volo-HTTP] failed to make tls connection, error: {err}");
                Err(request_error(err))
            }
        }
    }
}