mobile wss use rustls_platform_verifier

Signed-off-by: 21pages <sunboeasy@gmail.com>
This commit is contained in:
21pages
2025-10-21 20:56:55 +08:00
parent 5ed0afde08
commit bf9a79fda5
5 changed files with 77 additions and 7 deletions
+68 -2
View File
@@ -8,7 +8,11 @@ use crate::{
ResultType,
};
use bytes::{Bytes, BytesMut};
#[cfg(any(target_os = "android", target_os = "ios"))]
use futures::future::{select_ok, FutureExt};
use futures::{SinkExt, StreamExt};
#[cfg(any(target_os = "android", target_os = "ios"))]
use std::future::Future;
use std::{
io::{Error, ErrorKind},
net::SocketAddr,
@@ -28,6 +32,19 @@ pub struct WsFramedStream {
send_timeout: u64,
}
#[cfg(any(target_os = "android", target_os = "ios"))]
async fn await_timeout_result<F, T, E>(future: F) -> ResultType<T>
where
F: Future<Output = Result<Result<T, E>, tokio::time::error::Elapsed>>,
E: std::error::Error + Send + Sync + 'static,
{
match future.await {
Ok(Ok(result)) => Ok(result),
Ok(Err(e)) => Err(e.into()),
Err(elapsed) => Err(Error::new(ErrorKind::TimedOut, elapsed).into()),
}
}
impl WsFramedStream {
pub async fn new<T: AsRef<str>>(
url: T,
@@ -43,8 +60,57 @@ impl WsFramedStream {
.into_client_request()
.map_err(|e| Error::new(ErrorKind::Other, e))?;
let (stream, _) =
timeout(Duration::from_millis(ms_timeout), connect_async(request)).await??;
let stream;
#[cfg(any(target_os = "android", target_os = "ios"))]
{
let mut futures = vec![];
let is_wss = url_str.starts_with("wss://");
let rustls_platform_verifier_initialized = !cfg!(target_os = "android")
|| crate::config::RUSTLS_PLATFORM_VERIFIER_INITIALIZED
.load(std::sync::atomic::Ordering::Relaxed);
if is_wss && rustls_platform_verifier_initialized {
use rustls_platform_verifier::ConfigVerifierExt;
use std::sync::Arc;
use tokio_rustls::rustls::ClientConfig;
use tokio_tungstenite::{connect_async_tls_with_config, Connector};
match ClientConfig::with_platform_verifier() {
Ok(config) => {
let connector = Connector::Rustls(Arc::new(config));
futures.push(
await_timeout_result(timeout(
Duration::from_millis(ms_timeout),
connect_async_tls_with_config(
request.clone(),
None,
false,
Some(connector),
),
))
.boxed(),
);
}
Err(e) => {
log::error!("with_platform_verifier failed: {:?}", e);
}
}
}
futures.push(
await_timeout_result(timeout(
Duration::from_millis(ms_timeout),
connect_async(request),
))
.boxed(),
);
let ((s, _), _) = select_ok(futures).await?;
stream = s;
}
#[cfg(not(any(target_os = "android", target_os = "ios")))]
{
let (s, _) =
timeout(Duration::from_millis(ms_timeout), connect_async(request)).await??;
stream = s;
}
let addr = match stream.get_ref() {
MaybeTlsStream::Plain(tcp) => tcp.peer_addr()?,