From 80526fbc683d5fe82c2d3985ea0ef32ea196ec26 Mon Sep 17 00:00:00 2001 From: Sebastian Imlay <sebastian.imlay@gmail.com> Date: Mon, 29 Jul 2024 14:45:20 -0400 Subject: [PATCH] Initial barebones for browser wasm support --- Cargo.toml | 8 ++++++-- src/connect_wasm.rs | 42 ++++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 18 +++++++++++++----- 3 files changed, 61 insertions(+), 7 deletions(-) create mode 100644 src/connect_wasm.rs diff --git a/Cargo.toml b/Cargo.toml index dec1fa2c..d3170d83 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,11 +27,15 @@ rustls-tls-webpki-roots = ["__rustls-tls", "webpki-roots"] __rustls-tls = ["rustls", "rustls-pki-types", "tokio-rustls", "stream", "tungstenite/__rustls-tls", "handshake"] stream = [] url = ["tungstenite/url"] +js-connect = ["stream", "handshake", "ws_stream_wasm", "async_io_stream", "getrandom/js" ] [dependencies] log = "0.4.17" futures-util = { version = "0.3.28", default-features = false, features = ["sink", "std"] } -tokio = { version = "1.0.0", default-features = false, features = ["io-util"] } +tokio = { version = "1.39.0", default-features = false } +ws_stream_wasm = { version = "0.7.4", optional = true } +async_io_stream = { version = "0.3.3", features = ["tokio_io"], optional = true } +getrandom = { version = "0.2", optional = true } [dependencies.tungstenite] version = "0.23.0" @@ -68,7 +72,7 @@ default-features = false optional = true version = "0.26.0" -[dev-dependencies] +[target.'cfg(not(target_family = "wasm"))'.dev-dependencies] futures-channel = "0.3.28" hyper = { version = "1.0", default-features = false, features = ["http1", "server"] } hyper-util = { version = "0.1", features = ["tokio"] } diff --git a/src/connect_wasm.rs b/src/connect_wasm.rs new file mode 100644 index 00000000..f3d130bd --- /dev/null +++ b/src/connect_wasm.rs @@ -0,0 +1,42 @@ +use crate::{stream::MaybeTlsStream, Connector, WebSocketStream}; + +use tungstenite::{ + error::{Error, UrlError}, + handshake::client::{Request, Response}, + protocol::WebSocketConfig, + //client::IntoClientRequest, +}; +//use web_sys::WebSocket; +use ws_stream_wasm::WsStreamIo; +use async_io_stream::IoStream; + + + +pub async fn connect( + request: Request, + config: Option<WebSocketConfig>, + disable_nagle: bool, + //connector: Option<Connector>, +) -> Result<(WebSocketStream<MaybeTlsStream<IoStream<WsStreamIo, Vec<u8>>>>, Response), Error> { + //let domain = domain(&request)?; + let domain = request.uri().host().unwrap(); + 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)?; + } + todo!(); + + //crate::tls::client_async_tls_with_config(request, socket, config, connector).await +} diff --git a/src/lib.rs b/src/lib.rs index 734fc648..ef6b5143 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -8,17 +8,22 @@ //! Each WebSocket stream implements the required `Stream` and `Sink` traits, //! so the socket is just a stream of messages coming in and going out. -#![deny(missing_docs, unused_must_use, unused_mut, unused_imports, unused_import_braces)] +//#![deny(missing_docs, unused_must_use, unused_mut, unused_imports, unused_import_braces)] pub use tungstenite; mod compat; -#[cfg(feature = "connect")] +#[cfg(all(feature = "connect", not(target_family = "wasm")))] mod connect; + +#[cfg(all(feature = "js-connect", target_family = "wasm"))] +mod connect_wasm; + +#[cfg(feature = "handshake")] mod handshake; #[cfg(feature = "stream")] mod stream; -#[cfg(any(feature = "native-tls", feature = "__rustls-tls", feature = "connect"))] +#[cfg(any(feature = "native-tls", feature = "__rustls-tls", feature = "connect", feature = "js-connect"))] mod tls; use std::io::{Read, Write}; @@ -49,14 +54,17 @@ use tungstenite::{ protocol::{Message, Role, WebSocket, WebSocketConfig}, }; -#[cfg(any(feature = "native-tls", feature = "__rustls-tls", feature = "connect"))] +#[cfg(any(feature = "native-tls", feature = "__rustls-tls", feature = "connect", feature = "js-connect"))] pub use tls::Connector; #[cfg(any(feature = "native-tls", feature = "__rustls-tls"))] pub use tls::{client_async_tls, client_async_tls_with_config}; -#[cfg(feature = "connect")] +#[cfg(all(feature = "connect", not(target_family = "wasm")))] pub use connect::{connect_async, connect_async_with_config}; +#[cfg(all(feature = "js-connect", target_family = "wasm"))] +pub use connect_wasm::connect; + #[cfg(all(any(feature = "native-tls", feature = "__rustls-tls"), feature = "connect"))] pub use connect::connect_async_tls_with_config;