use compio_tls::TlsConnector;
use compio_ws::connect_async_tls_with_config;
use tungstenite::Message;
#[cfg(feature = "native-tls")]
async fn create_insecure_tls_connector() -> Result<TlsConnector, Box<dyn std::error::Error>> {
let mut builder = compio_tls::native_tls::TlsConnector::builder();
builder
.danger_accept_invalid_certs(true)
.danger_accept_invalid_hostnames(true);
let connector = builder.build()?;
Ok(TlsConnector::from(connector))
}
#[cfg(all(feature = "rustls", not(feature = "native-tls")))]
async fn create_insecure_tls_connector() -> Result<TlsConnector, Box<dyn std::error::Error>> {
use std::sync::Arc;
use compio_tls::rustls;
use rustls::ClientConfig;
#[derive(Debug)]
struct AcceptAllVerifier;
impl rustls::client::danger::ServerCertVerifier for AcceptAllVerifier {
fn verify_server_cert(
&self,
_end_entity: &rustls::pki_types::CertificateDer<'_>,
_intermediates: &[rustls::pki_types::CertificateDer<'_>],
_server_name: &rustls::pki_types::ServerName<'_>,
_ocsp_response: &[u8],
_now: rustls::pki_types::UnixTime,
) -> Result<rustls::client::danger::ServerCertVerified, rustls::Error> {
Ok(rustls::client::danger::ServerCertVerified::assertion())
}
fn verify_tls12_signature(
&self,
_message: &[u8],
_cert: &rustls::pki_types::CertificateDer<'_>,
_dss: &rustls::DigitallySignedStruct,
) -> Result<rustls::client::danger::HandshakeSignatureValid, rustls::Error> {
Ok(rustls::client::danger::HandshakeSignatureValid::assertion())
}
fn verify_tls13_signature(
&self,
_message: &[u8],
_cert: &rustls::pki_types::CertificateDer<'_>,
_dss: &rustls::DigitallySignedStruct,
) -> Result<rustls::client::danger::HandshakeSignatureValid, rustls::Error> {
Ok(rustls::client::danger::HandshakeSignatureValid::assertion())
}
fn supported_verify_schemes(&self) -> Vec<rustls::SignatureScheme> {
vec![
rustls::SignatureScheme::RSA_PKCS1_SHA1,
rustls::SignatureScheme::ECDSA_SHA1_Legacy,
rustls::SignatureScheme::RSA_PKCS1_SHA256,
rustls::SignatureScheme::ECDSA_NISTP256_SHA256,
rustls::SignatureScheme::RSA_PKCS1_SHA384,
rustls::SignatureScheme::ECDSA_NISTP384_SHA384,
rustls::SignatureScheme::RSA_PKCS1_SHA512,
rustls::SignatureScheme::ECDSA_NISTP521_SHA512,
rustls::SignatureScheme::RSA_PSS_SHA256,
rustls::SignatureScheme::RSA_PSS_SHA384,
rustls::SignatureScheme::RSA_PSS_SHA512,
rustls::SignatureScheme::ED25519,
rustls::SignatureScheme::ED448,
]
}
}
let config = ClientConfig::builder()
.dangerous()
.with_custom_certificate_verifier(Arc::new(AcceptAllVerifier))
.with_no_client_auth();
Ok(TlsConnector::from(Arc::new(config)))
}
#[compio_macros::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
#[cfg(any(feature = "native-tls", feature = "rustls"))]
let connector = Some(create_insecure_tls_connector().await?);
#[cfg(not(any(feature = "native-tls", feature = "rustls")))]
let connector = None;
let (mut websocket, _response) =
connect_async_tls_with_config("wss://127.0.0.1:9002", None, connector).await?;
println!("Successfully connected to WebSocket TLS server!");
println!();
println!("Test 1: Sending text message");
websocket
.send(Message::Text("Hello, secure server!".into()))
.await?;
println!("Test 2: Sending binary message");
websocket
.send(Message::Binary(vec![1, 2, 3, 4, 5].into()))
.await?;
println!("Test 3: Sending ping");
websocket.send(Message::Ping(vec![42].into())).await?;
println!("Reading responses from server:");
for i in 0..3 {
match websocket.read().await? {
Message::Text(text) => {
println!(" Response {}: Text: {}", i + 1, text);
}
Message::Binary(data) => {
let data_str = String::from_utf8_lossy(&data);
println!(" Response {}: Binary: {}", i + 1, data_str);
}
Message::Pong(data) => {
println!(" Response {}: Pong: {:?}", i + 1, data);
}
other => {
println!(" Response {}: {:?}", i + 1, other);
}
}
}
println!("Closing TLS connection...");
websocket.close(None).await?;
println!("TLS connection closed successfully!");
Ok(())
}