use tokio::net::TcpStream;
use tungstenite::{
error::{Error, UrlError},
handshake::client::{Request, Response},
protocol::WebSocketConfig,
};
use crate::{domain, stream::MaybeTlsStream, Connector, IntoClientRequest, WebSocketStream};
pub async fn connect_async<R>(
request: R,
) -> Result<(WebSocketStream<MaybeTlsStream<TcpStream>>, Response), Error>
where
R: IntoClientRequest + Unpin,
{
connect_async_with_config(request, None, false).await
}
pub async fn connect_async_with_config<R>(
request: R,
config: Option<WebSocketConfig>,
disable_nagle: bool,
) -> Result<(WebSocketStream<MaybeTlsStream<TcpStream>>, Response), Error>
where
R: IntoClientRequest + Unpin,
{
connect(request.into_client_request()?, config, disable_nagle, None).await
}
#[cfg(any(feature = "native-tls", feature = "__rustls-tls"))]
pub async fn connect_async_tls_with_config<R>(
request: R,
config: Option<WebSocketConfig>,
disable_nagle: bool,
connector: Option<Connector>,
) -> Result<(WebSocketStream<MaybeTlsStream<TcpStream>>, Response), Error>
where
R: IntoClientRequest + Unpin,
{
connect(request.into_client_request()?, config, disable_nagle, connector).await
}
async fn connect(
request: Request,
config: Option<WebSocketConfig>,
disable_nagle: bool,
connector: Option<Connector>,
) -> Result<(WebSocketStream<MaybeTlsStream<TcpStream>>, Response), Error> {
let domain = domain(&request)?;
let port = request
.uri()
.port_u16()
.or_else(|| match request.uri().scheme_str() {
Some("wss") => Some(443),
Some("ws") => Some(80),
_ => None,
})
.ok_or(Error::Url(UrlError::UnsupportedUrlScheme))?;
let addr = format!("{domain}:{port}");
let socket = TcpStream::connect(addr).await.map_err(Error::Io)?;
if disable_nagle {
socket.set_nodelay(true)?;
}
crate::tls::client_async_tls_with_config(request, socket, config, connector).await
}