Skip to main content

base_endpoint/tls/
tls_client_endpoint.rs

1// Released under the MIT License.
2// Copyright, 2026, by Samuel Williams.
3
4use super::TlsConnector;
5use crate::ConnectEndpoint;
6use base_scheduler::{Cancellation, OperationResult};
7
8/// Compose connection establishment with a TLS client handshake. The server identity is explicit and independent of the underlying endpoint's routing address.
9#[derive(Clone, Debug)]
10pub struct TlsClientEndpoint<E, T> {
11    endpoint: E,
12    connector: T,
13    server_name: String,
14}
15
16impl<E, T> TlsClientEndpoint<E, T> {
17    /// Describe a TLS connection using a configured provider and the identity to authenticate. No I/O is performed until `connect` is polled.
18    pub fn new(endpoint: E, connector: T, server_name: impl Into<String>) -> Self {
19        Self {
20            endpoint,
21            connector,
22            server_name: server_name.into(),
23        }
24    }
25
26    /// The underlying endpoint description.
27    pub fn endpoint(&self) -> &E {
28        &self.endpoint
29    }
30
31    /// The server identity supplied to the connector.
32    pub fn server_name(&self) -> &str {
33        &self.server_name
34    }
35}
36
37impl<S, E, T> ConnectEndpoint<S> for TlsClientEndpoint<E, T>
38where
39    S: Sync + ?Sized,
40    E: ConnectEndpoint<S>,
41    T: TlsConnector<S, E::Connection>,
42{
43    type Connection = T::Connection;
44
45    async fn connect(
46        &self,
47        scheduler: &S,
48        cancellation: &Cancellation,
49    ) -> OperationResult<Self::Connection> {
50        cancellation.check()?;
51        let connection = self.endpoint.connect(scheduler, cancellation).await?;
52        // Ownership transfers to the provider even if cancellation arrived during transport establishment. The provider must retire the connection on every failed handshake path.
53        self.connector
54            .connect(scheduler, connection, &self.server_name, cancellation)
55            .await
56    }
57}