tokio_tungstenite/
connect.rs

1//! Connection helper.
2use tokio::net::TcpStream;
3
4use tungstenite::{
5    error::{Error, UrlError},
6    handshake::client::{Request, Response},
7    protocol::WebSocketConfig,
8};
9
10use crate::{domain, stream::MaybeTlsStream, Connector, IntoClientRequest, WebSocketStream};
11
12/// Connect to a given URL.
13pub async fn connect_async<R>(
14    request: R,
15) -> Result<(WebSocketStream<MaybeTlsStream<TcpStream>>, Response), Error>
16where
17    R: IntoClientRequest + Unpin,
18{
19    connect_async_with_config(request, None, false).await
20}
21
22/// The same as `connect_async()` but the one can specify a websocket configuration.
23/// Please refer to `connect_async()` for more details. `disable_nagle` specifies if
24/// the Nagle's algorithm must be disabled, i.e. `set_nodelay(true)`. If you don't know
25/// what the Nagle's algorithm is, better leave it set to `false`.
26pub async fn connect_async_with_config<R>(
27    request: R,
28    config: Option<WebSocketConfig>,
29    disable_nagle: bool,
30) -> Result<(WebSocketStream<MaybeTlsStream<TcpStream>>, Response), Error>
31where
32    R: IntoClientRequest + Unpin,
33{
34    connect(request.into_client_request()?, config, disable_nagle, None).await
35}
36
37/// The same as `connect_async()` but the one can specify a websocket configuration,
38/// and a TLS connector to use. Please refer to `connect_async()` for more details.
39/// `disable_nagle` specifies if the Nagle's algorithm must be disabled, i.e.
40/// `set_nodelay(true)`. If you don't know what the Nagle's algorithm is, better
41/// leave it to `false`.
42#[cfg(any(feature = "native-tls", feature = "__rustls-tls"))]
43pub async fn connect_async_tls_with_config<R>(
44    request: R,
45    config: Option<WebSocketConfig>,
46    disable_nagle: bool,
47    connector: Option<Connector>,
48) -> Result<(WebSocketStream<MaybeTlsStream<TcpStream>>, Response), Error>
49where
50    R: IntoClientRequest + Unpin,
51{
52    connect(request.into_client_request()?, config, disable_nagle, connector).await
53}
54
55async fn connect(
56    request: Request,
57    config: Option<WebSocketConfig>,
58    disable_nagle: bool,
59    connector: Option<Connector>,
60) -> Result<(WebSocketStream<MaybeTlsStream<TcpStream>>, Response), Error> {
61    let domain = domain(&request)?;
62    let port = request
63        .uri()
64        .port_u16()
65        .or_else(|| match request.uri().scheme_str() {
66            Some("wss") => Some(443),
67            Some("ws") => Some(80),
68            _ => None,
69        })
70        .ok_or(Error::Url(UrlError::UnsupportedUrlScheme))?;
71
72    let addr = format!("{domain}:{port}");
73    let socket = TcpStream::connect(addr).await.map_err(Error::Io)?;
74
75    if disable_nagle {
76        socket.set_nodelay(true)?;
77    }
78
79    crate::tls::client_async_tls_with_config(request, socket, config, connector).await
80}