Upgrade async-tungstenite to tokio (#26193)

We're seeing panics caused by a buggy implementation of AsyncWrite
that is being passed to rustls: 

https://github.com/rustls/rustls/issues/2316#issuecomment-2662838186

One hypothesis was that we're using (comparatively) non-standard async
tools for connecting over websockets; so this attempts to make us be
(comparitvely) more standard.

Release Notes:

- N/A
This commit is contained in:
Conrad Irwin 2025-04-08 09:17:08 -06:00 committed by GitHub
parent ea33d78ae4
commit ca4cc4764b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 84 additions and 140 deletions

80
Cargo.lock generated
View File

@ -913,18 +913,6 @@ dependencies = [
"pin-project-lite", "pin-project-lite",
] ]
[[package]]
name = "async-native-tls"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9343dc5acf07e79ff82d0c37899f079db3534d99f189a1837c8e549c99405bec"
dependencies = [
"futures-util",
"native-tls",
"thiserror 1.0.69",
"url",
]
[[package]] [[package]]
name = "async-net" name = "async-net"
version = "2.0.0" version = "2.0.0"
@ -1094,18 +1082,6 @@ version = "4.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de"
[[package]]
name = "async-tls"
version = "0.13.0"
source = "git+https://github.com/zed-industries/async-tls?rev=1e759a4b5e370f87dc15e40756ac4f8815b61d9d#1e759a4b5e370f87dc15e40756ac4f8815b61d9d"
dependencies = [
"futures-core",
"futures-io",
"rustls 0.23.25",
"rustls-pemfile 2.2.0",
"webpki-roots",
]
[[package]] [[package]]
name = "async-trait" name = "async-trait"
version = "0.1.88" version = "0.1.88"
@ -1119,12 +1095,10 @@ dependencies = [
[[package]] [[package]]
name = "async-tungstenite" name = "async-tungstenite"
version = "0.28.2" version = "0.29.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1c348fb0b6d132c596eca3dcd941df48fb597aafcb07a738ec41c004b087dc99" checksum = "ef0f7efedeac57d9b26170f72965ecfd31473ca52ca7a64e925b0b6f5f079886"
dependencies = [ dependencies = [
"async-std",
"async-tls",
"atomic-waker", "atomic-waker",
"futures-core", "futures-core",
"futures-io", "futures-io",
@ -1132,7 +1106,10 @@ dependencies = [
"futures-util", "futures-util",
"log", "log",
"pin-project-lite", "pin-project-lite",
"tungstenite 0.24.0", "rustls-pki-types",
"tokio",
"tokio-rustls 0.26.2",
"tungstenite 0.26.2",
] ]
[[package]] [[package]]
@ -2838,7 +2815,6 @@ name = "client"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"async-native-tls",
"async-recursion 0.3.2", "async-recursion 0.3.2",
"async-tungstenite", "async-tungstenite",
"chrono", "chrono",
@ -2849,6 +2825,7 @@ dependencies = [
"feature_flags", "feature_flags",
"futures 0.3.31", "futures 0.3.31",
"gpui", "gpui",
"gpui_tokio",
"http_client", "http_client",
"http_client_tls", "http_client_tls",
"log", "log",
@ -2870,6 +2847,7 @@ dependencies = [
"thiserror 2.0.12", "thiserror 2.0.12",
"time", "time",
"tiny_http", "tiny_http",
"tokio",
"tokio-socks", "tokio-socks",
"url", "url",
"util", "util",
@ -7452,8 +7430,7 @@ dependencies = [
[[package]] [[package]]
name = "jupyter-protocol" name = "jupyter-protocol"
version = "0.6.0" version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "git+https://github.com/ConradIrwin/runtimed?rev=7130c804216b6914355d15d0b91ea91f6babd734#7130c804216b6914355d15d0b91ea91f6babd734"
checksum = "c9ae6296f9476658b3550293c113996daf75fa542cd8d078abb4c60207bded14"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"async-trait", "async-trait",
@ -7468,8 +7445,7 @@ dependencies = [
[[package]] [[package]]
name = "jupyter-websocket-client" name = "jupyter-websocket-client"
version = "0.9.0" version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "git+https://github.com/ConradIrwin/runtimed?rev=7130c804216b6914355d15d0b91ea91f6babd734#7130c804216b6914355d15d0b91ea91f6babd734"
checksum = "49c1ba895c5271ff8dcae51c347fd3588905ba0025a57e20955fd231fe1228cc"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"async-trait", "async-trait",
@ -8776,8 +8752,7 @@ dependencies = [
[[package]] [[package]]
name = "nbformat" name = "nbformat"
version = "0.10.0" version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "git+https://github.com/ConradIrwin/runtimed?rev=7130c804216b6914355d15d0b91ea91f6babd734#7130c804216b6914355d15d0b91ea91f6babd734"
checksum = "244c1673f02b4d5f3c51b6f8ed28d57182cb166a50a6dbf651a3d53e23dc81c0"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"chrono", "chrono",
@ -9556,15 +9531,6 @@ version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e"
[[package]]
name = "openssl-src"
version = "300.4.2+3.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "168ce4e058f975fe43e89d9ccf78ca668601887ae736090aacc23ae353c298e2"
dependencies = [
"cc",
]
[[package]] [[package]]
name = "openssl-sys" name = "openssl-sys"
version = "0.9.107" version = "0.9.107"
@ -9573,7 +9539,6 @@ checksum = "8288979acd84749c744a9014b4382d42b8f7b2592847b5afb2ed29e5d16ede07"
dependencies = [ dependencies = [
"cc", "cc",
"libc", "libc",
"openssl-src",
"pkg-config", "pkg-config",
"vcpkg", "vcpkg",
] ]
@ -12102,8 +12067,7 @@ dependencies = [
[[package]] [[package]]
name = "runtimelib" name = "runtimelib"
version = "0.25.0" version = "0.25.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "git+https://github.com/ConradIrwin/runtimed?rev=7130c804216b6914355d15d0b91ea91f6babd734#7130c804216b6914355d15d0b91ea91f6babd734"
checksum = "9af6ed9fd10d7ee940676945510c197c2a472806bb652096a713985c44ffd643"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"async-dispatcher", "async-dispatcher",
@ -15330,24 +15294,6 @@ dependencies = [
"utf-8", "utf-8",
] ]
[[package]]
name = "tungstenite"
version = "0.24.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "18e5b8366ee7a95b16d32197d0b2604b43a0be89dc5fac9f8e96ccafbaedda8a"
dependencies = [
"byteorder",
"bytes 1.10.1",
"data-encoding",
"http 1.3.1",
"httparse",
"log",
"rand 0.8.5",
"sha1",
"thiserror 1.0.69",
"utf-8",
]
[[package]] [[package]]
name = "tungstenite" name = "tungstenite"
version = "0.26.2" version = "0.26.2"
@ -17711,7 +17657,6 @@ dependencies = [
"scopeguard", "scopeguard",
"sea-orm", "sea-orm",
"sea-query-binder", "sea-query-binder",
"security-framework 2.11.1",
"security-framework 3.2.0", "security-framework 3.2.0",
"security-framework-sys", "security-framework-sys",
"semver", "semver",
@ -17742,6 +17687,7 @@ dependencies = [
"toml_edit", "toml_edit",
"tracing", "tracing",
"tracing-core", "tracing-core",
"tungstenite 0.26.2",
"unicode-properties", "unicode-properties",
"url", "url",
"uuid", "uuid",

View File

@ -396,7 +396,7 @@ async-pipe = { git = "https://github.com/zed-industries/async-pipe-rs", rev = "8
async-recursion = "1.0.0" async-recursion = "1.0.0"
async-tar = "0.5.0" async-tar = "0.5.0"
async-trait = "0.1" async-trait = "0.1"
async-tungstenite = "0.28" async-tungstenite = "0.29.1"
async-watch = "0.3.1" async-watch = "0.3.1"
async_zip = { version = "0.0.17", features = ["deflate", "deflate64"] } async_zip = { version = "0.0.17", features = ["deflate", "deflate64"] }
aws-config = { version = "1.6.1", features = ["behavior-version-latest"] } aws-config = { version = "1.6.1", features = ["behavior-version-latest"] }
@ -453,8 +453,8 @@ indoc = "2"
inventory = "0.3.19" inventory = "0.3.19"
itertools = "0.14.0" itertools = "0.14.0"
jsonwebtoken = "9.3" jsonwebtoken = "9.3"
jupyter-protocol = { version = "0.6.0" } jupyter-protocol = { git = "https://github.com/ConradIrwin/runtimed", rev = "7130c804216b6914355d15d0b91ea91f6babd734" }
jupyter-websocket-client = { version = "0.9.0" } jupyter-websocket-client = { git = "https://github.com/ConradIrwin/runtimed" ,rev = "7130c804216b6914355d15d0b91ea91f6babd734" }
libc = "0.2" libc = "0.2"
libsqlite3-sys = { version = "0.30.1", features = ["bundled"] } libsqlite3-sys = { version = "0.30.1", features = ["bundled"] }
linkify = "0.10.0" linkify = "0.10.0"
@ -463,7 +463,7 @@ log = { version = "0.4.16", features = ["kv_unstable_serde", "serde"] }
markup5ever_rcdom = "0.3.0" markup5ever_rcdom = "0.3.0"
mlua = { version = "0.10", features = ["lua54", "vendored", "async", "send"] } mlua = { version = "0.10", features = ["lua54", "vendored", "async", "send"] }
nanoid = "0.4" nanoid = "0.4"
nbformat = { version = "0.10.0" } nbformat = { git = "https://github.com/ConradIrwin/runtimed", rev = "7130c804216b6914355d15d0b91ea91f6babd734" }
nix = "0.29" nix = "0.29"
objc = "0.2" objc = "0.2"
open = "5.0.0" open = "5.0.0"
@ -501,7 +501,7 @@ reqwest = { git = "https://github.com/zed-industries/reqwest.git", rev = "fd110f
"stream", "stream",
] } ] }
rsa = "0.9.6" rsa = "0.9.6"
runtimelib = { version = "0.25.0", default-features = false, features = [ runtimelib = { git = "https://github.com/ConradIrwin/runtimed", rev = "7130c804216b6914355d15d0b91ea91f6babd734", default-features = false, features = [
"async-dispatcher-runtime", "async-dispatcher-runtime",
] } ] }
rustc-demangle = "0.1.23" rustc-demangle = "0.1.23"
@ -661,7 +661,6 @@ features = [
# TODO livekit https://github.com/RustAudio/cpal/pull/891 # TODO livekit https://github.com/RustAudio/cpal/pull/891
[patch.crates-io] [patch.crates-io]
cpal = { git = "https://github.com/zed-industries/cpal", rev = "fd8bc2fd39f1f5fdee5a0690656caff9a26d9d50" } cpal = { git = "https://github.com/zed-industries/cpal", rev = "fd8bc2fd39f1f5fdee5a0690656caff9a26d9d50" }
real-async-tls = { git = "https://github.com/zed-industries/async-tls", rev = "1e759a4b5e370f87dc15e40756ac4f8815b61d9d", package = "async-tls" }
notify = { git = "https://github.com/zed-industries/notify.git", rev = "bbb9ea5ae52b253e095737847e367c30653a2e96" } notify = { git = "https://github.com/zed-industries/notify.git", rev = "bbb9ea5ae52b253e095737847e367c30653a2e96" }
notify-types = { git = "https://github.com/zed-industries/notify.git", rev = "bbb9ea5ae52b253e095737847e367c30653a2e96" } notify-types = { git = "https://github.com/zed-industries/notify.git", rev = "bbb9ea5ae52b253e095737847e367c30653a2e96" }

View File

@ -18,7 +18,7 @@ test-support = ["clock/test-support", "collections/test-support", "gpui/test-sup
[dependencies] [dependencies]
anyhow.workspace = true anyhow.workspace = true
async-recursion = "0.3" async-recursion = "0.3"
async-tungstenite = { workspace = true, features = ["async-std", "async-tls"] } async-tungstenite = { workspace = true, features = ["tokio", "tokio-rustls-manual-roots"] }
chrono = { workspace = true, features = ["serde"] } chrono = { workspace = true, features = ["serde"] }
clock.workspace = true clock.workspace = true
collections.workspace = true collections.workspace = true
@ -26,6 +26,7 @@ credentials_provider.workspace = true
feature_flags.workspace = true feature_flags.workspace = true
futures.workspace = true futures.workspace = true
gpui.workspace = true gpui.workspace = true
gpui_tokio.workspace = true
http_client.workspace = true http_client.workspace = true
http_client_tls.workspace = true http_client_tls.workspace = true
log.workspace = true log.workspace = true
@ -51,6 +52,7 @@ url.workspace = true
util.workspace = true util.workspace = true
worktree.workspace = true worktree.workspace = true
telemetry.workspace = true telemetry.workspace = true
tokio.workspace = true
workspace-hack.workspace = true workspace-hack.workspace = true
[dev-dependencies] [dev-dependencies]
@ -67,4 +69,3 @@ windows.workspace = true
[target.'cfg(target_os = "macos")'.dependencies] [target.'cfg(target_os = "macos")'.dependencies]
cocoa.workspace = true cocoa.workspace = true
async-native-tls = { version = "0.5.0", features = ["vendored"] }

View File

@ -20,7 +20,7 @@ use futures::{
AsyncReadExt, FutureExt, SinkExt, Stream, StreamExt, TryFutureExt as _, TryStreamExt, AsyncReadExt, FutureExt, SinkExt, Stream, StreamExt, TryFutureExt as _, TryStreamExt,
channel::oneshot, future::BoxFuture, channel::oneshot, future::BoxFuture,
}; };
use gpui::{App, AppContext as _, AsyncApp, Entity, Global, Task, WeakEntity, actions}; use gpui::{App, AsyncApp, Entity, Global, Task, WeakEntity, actions};
use http_client::{AsyncBody, HttpClient, HttpClientWithUrl}; use http_client::{AsyncBody, HttpClient, HttpClientWithUrl};
use parking_lot::RwLock; use parking_lot::RwLock;
use postage::watch; use postage::watch;
@ -1086,7 +1086,7 @@ impl Client {
let rpc_url = self.rpc_url(http, release_channel); let rpc_url = self.rpc_url(http, release_channel);
let system_id = self.telemetry.system_id(); let system_id = self.telemetry.system_id();
let metrics_id = self.telemetry.metrics_id(); let metrics_id = self.telemetry.metrics_id();
cx.background_spawn(async move { cx.spawn(async move |cx| {
use HttpOrHttps::*; use HttpOrHttps::*;
#[derive(Debug)] #[derive(Debug)]
@ -1105,7 +1105,12 @@ impl Client {
.host_str() .host_str()
.zip(rpc_url.port_or_known_default()) .zip(rpc_url.port_or_known_default())
.ok_or_else(|| anyhow!("missing host in rpc url"))?; .ok_or_else(|| anyhow!("missing host in rpc url"))?;
let stream = connect_socks_proxy_stream(proxy.as_ref(), rpc_host).await?;
let stream = {
let handle = cx.update(|cx| gpui_tokio::Tokio::handle(cx)).ok().unwrap();
let _guard = handle.enter();
connect_socks_proxy_stream(proxy.as_ref(), rpc_host).await?
};
log::info!("connected to rpc endpoint {}", rpc_url); log::info!("connected to rpc endpoint {}", rpc_url);
@ -1144,30 +1149,19 @@ impl Client {
request_headers.insert("x-zed-metrics-id", HeaderValue::from_str(&metrics_id)?); request_headers.insert("x-zed-metrics-id", HeaderValue::from_str(&metrics_id)?);
} }
match url_scheme { let (stream, _) = async_tungstenite::tokio::client_async_tls_with_connector_and_config(
Https => { request,
let (stream, _) = stream,
async_tungstenite::async_tls::client_async_tls_with_connector( Some(Arc::new(http_client_tls::tls_config()).into()),
request, None,
stream, )
Some(http_client_tls::tls_config().into()), .await?;
)
.await?; Ok(Connection::new(
Ok(Connection::new( stream
stream .map_err(|error| anyhow!(error))
.map_err(|error| anyhow!(error)) .sink_map_err(|error| anyhow!(error)),
.sink_map_err(|error| anyhow!(error)), ))
))
}
Http => {
let (stream, _) = async_tungstenite::client_async(request, stream).await?;
Ok(Connection::new(
stream
.map_err(|error| anyhow!(error))
.sink_map_err(|error| anyhow!(error)),
))
}
}
}) })
} }
@ -1639,7 +1633,7 @@ mod tests {
use crate::test::FakeServer; use crate::test::FakeServer;
use clock::FakeSystemClock; use clock::FakeSystemClock;
use gpui::{BackgroundExecutor, TestAppContext}; use gpui::{AppContext as _, BackgroundExecutor, TestAppContext};
use http_client::FakeHttpClient; use http_client::FakeHttpClient;
use parking_lot::Mutex; use parking_lot::Mutex;
use proto::TypedEnvelope; use proto::TypedEnvelope;

View File

@ -1,11 +1,7 @@
//! socks proxy //! socks proxy
use anyhow::{Result, anyhow}; use anyhow::{Result, anyhow};
use futures::io::{AsyncRead, AsyncWrite};
use http_client::Uri; use http_client::Uri;
use tokio_socks::{ use tokio_socks::tcp::{Socks4Stream, Socks5Stream};
io::Compat,
tcp::{Socks4Stream, Socks5Stream},
};
pub(crate) async fn connect_socks_proxy_stream( pub(crate) async fn connect_socks_proxy_stream(
proxy: Option<&Uri>, proxy: Option<&Uri>,
@ -14,7 +10,7 @@ pub(crate) async fn connect_socks_proxy_stream(
let stream = match parse_socks_proxy(proxy) { let stream = match parse_socks_proxy(proxy) {
Some((socks_proxy, SocksVersion::V4)) => { Some((socks_proxy, SocksVersion::V4)) => {
let stream = Socks4Stream::connect_with_socket( let stream = Socks4Stream::connect_with_socket(
Compat::new(smol::net::TcpStream::connect(socks_proxy).await?), tokio::net::TcpStream::connect(socks_proxy).await?,
rpc_host, rpc_host,
) )
.await .await
@ -23,13 +19,15 @@ pub(crate) async fn connect_socks_proxy_stream(
} }
Some((socks_proxy, SocksVersion::V5)) => Box::new( Some((socks_proxy, SocksVersion::V5)) => Box::new(
Socks5Stream::connect_with_socket( Socks5Stream::connect_with_socket(
Compat::new(smol::net::TcpStream::connect(socks_proxy).await?), tokio::net::TcpStream::connect(socks_proxy).await?,
rpc_host, rpc_host,
) )
.await .await
.map_err(|err| anyhow!("error connecting to socks {}", err))?, .map_err(|err| anyhow!("error connecting to socks {}", err))?,
) as Box<dyn AsyncReadWrite>, ) as Box<dyn AsyncReadWrite>,
None => Box::new(smol::net::TcpStream::connect(rpc_host).await?) as Box<dyn AsyncReadWrite>, None => {
Box::new(tokio::net::TcpStream::connect(rpc_host).await?) as Box<dyn AsyncReadWrite>
}
}; };
Ok(stream) Ok(stream)
} }
@ -60,5 +58,11 @@ enum SocksVersion {
V5, V5,
} }
pub(crate) trait AsyncReadWrite: AsyncRead + AsyncWrite + Unpin + Send + 'static {} pub(crate) trait AsyncReadWrite:
impl<T: AsyncRead + AsyncWrite + Unpin + Send + 'static> AsyncReadWrite for T {} tokio::io::AsyncRead + tokio::io::AsyncWrite + Unpin + Send + 'static
{
}
impl<T: tokio::io::AsyncRead + tokio::io::AsyncWrite + Unpin + Send + 'static> AsyncReadWrite
for T
{
}

View File

@ -4153,13 +4153,13 @@ async fn get_llm_api_token(
fn to_axum_message(message: TungsteniteMessage) -> anyhow::Result<AxumMessage> { fn to_axum_message(message: TungsteniteMessage) -> anyhow::Result<AxumMessage> {
let message = match message { let message = match message {
TungsteniteMessage::Text(payload) => AxumMessage::Text(payload), TungsteniteMessage::Text(payload) => AxumMessage::Text(payload.as_str().to_string()),
TungsteniteMessage::Binary(payload) => AxumMessage::Binary(payload), TungsteniteMessage::Binary(payload) => AxumMessage::Binary(payload.into()),
TungsteniteMessage::Ping(payload) => AxumMessage::Ping(payload), TungsteniteMessage::Ping(payload) => AxumMessage::Ping(payload.into()),
TungsteniteMessage::Pong(payload) => AxumMessage::Pong(payload), TungsteniteMessage::Pong(payload) => AxumMessage::Pong(payload.into()),
TungsteniteMessage::Close(frame) => AxumMessage::Close(frame.map(|frame| AxumCloseFrame { TungsteniteMessage::Close(frame) => AxumMessage::Close(frame.map(|frame| AxumCloseFrame {
code: frame.code.into(), code: frame.code.into(),
reason: frame.reason, reason: frame.reason.as_str().to_owned().into(),
})), })),
// We should never receive a frame while reading the message, according // We should never receive a frame while reading the message, according
// to the `tungstenite` maintainers: // to the `tungstenite` maintainers:
@ -4179,14 +4179,14 @@ fn to_axum_message(message: TungsteniteMessage) -> anyhow::Result<AxumMessage> {
fn to_tungstenite_message(message: AxumMessage) -> TungsteniteMessage { fn to_tungstenite_message(message: AxumMessage) -> TungsteniteMessage {
match message { match message {
AxumMessage::Text(payload) => TungsteniteMessage::Text(payload), AxumMessage::Text(payload) => TungsteniteMessage::Text(payload.into()),
AxumMessage::Binary(payload) => TungsteniteMessage::Binary(payload), AxumMessage::Binary(payload) => TungsteniteMessage::Binary(payload.into()),
AxumMessage::Ping(payload) => TungsteniteMessage::Ping(payload), AxumMessage::Ping(payload) => TungsteniteMessage::Ping(payload.into()),
AxumMessage::Pong(payload) => TungsteniteMessage::Pong(payload), AxumMessage::Pong(payload) => TungsteniteMessage::Pong(payload.into()),
AxumMessage::Close(frame) => { AxumMessage::Close(frame) => {
TungsteniteMessage::Close(frame.map(|frame| TungsteniteCloseFrame { TungsteniteMessage::Close(frame.map(|frame| TungsteniteCloseFrame {
code: frame.code.into(), code: frame.code.into(),
reason: frame.reason, reason: frame.reason.as_ref().into(),
})) }))
} }
} }

View File

@ -16,7 +16,7 @@ doctest = false
alacritty_terminal.workspace = true alacritty_terminal.workspace = true
anyhow.workspace = true anyhow.workspace = true
async-dispatcher.workspace = true async-dispatcher.workspace = true
async-tungstenite = { workspace = true, features = ["async-std", "async-tls"] } async-tungstenite = { workspace = true, features = ["tokio", "tokio-rustls-manual-roots"] }
base64.workspace = true base64.workspace = true
client.workspace = true client.workspace = true
collections.workspace = true collections.workspace = true

View File

@ -3,10 +3,8 @@ use gpui::{App, AppContext as _, Entity, Task, Window};
use http_client::{AsyncBody, HttpClient, Request}; use http_client::{AsyncBody, HttpClient, Request};
use jupyter_protocol::{ExecutionState, JupyterKernelspec, JupyterMessage, KernelInfoReply}; use jupyter_protocol::{ExecutionState, JupyterKernelspec, JupyterMessage, KernelInfoReply};
use async_tungstenite::{ use async_tungstenite::tokio::connect_async;
async_std::connect_async, use async_tungstenite::tungstenite::{client::IntoClientRequest, http::HeaderValue};
tungstenite::{client::IntoClientRequest, http::HeaderValue},
};
use futures::StreamExt; use futures::StreamExt;
use smol::io::AsyncReadExt as _; use smol::io::AsyncReadExt as _;

View File

@ -8,6 +8,7 @@ use futures::{SinkExt as _, StreamExt as _};
use proto::Message as _; use proto::Message as _;
use std::time::Instant; use std::time::Instant;
use std::{fmt::Debug, io}; use std::{fmt::Debug, io};
use zstd::zstd_safe::WriteBuf;
const KIB: usize = 1024; const KIB: usize = 1024;
const MIB: usize = KIB * 1024; const MIB: usize = KIB * 1024;
@ -59,7 +60,9 @@ where
self.encoding_buffer.clear(); self.encoding_buffer.clear();
self.encoding_buffer.shrink_to(MAX_BUFFER_LEN); self.encoding_buffer.shrink_to(MAX_BUFFER_LEN);
self.stream.send(WebSocketMessage::Binary(buffer)).await?; self.stream
.send(WebSocketMessage::Binary(buffer.into()))
.await?;
} }
Message::Ping => { Message::Ping => {
self.stream self.stream

View File

@ -1030,7 +1030,7 @@ mod tests {
let _ = messages_ended_rx.await; let _ = messages_ended_rx.await;
assert!( assert!(
server_conn server_conn
.send(WebSocketMessage::Binary(vec![])) .send(WebSocketMessage::Binary(vec![].into()))
.await .await
.is_err() .is_err()
); );

View File

@ -1,5 +1,6 @@
# This file is generated by `cargo hakari`. # This file is generated by `cargo hakari`.
# To regenerate, run: # To regenerate, run:
# cargo install cargo-hakari
# cargo hakari generate # cargo hakari generate
[package] [package]
@ -19,7 +20,7 @@ anstream = { version = "0.6" }
arrayvec = { version = "0.7", features = ["serde"] } arrayvec = { version = "0.7", features = ["serde"] }
async-compression = { version = "0.4", default-features = false, features = ["deflate", "deflate64", "futures-io", "gzip"] } async-compression = { version = "0.4", default-features = false, features = ["deflate", "deflate64", "futures-io", "gzip"] }
async-std = { version = "1", features = ["attributes", "unstable"] } async-std = { version = "1", features = ["attributes", "unstable"] }
async-tungstenite = { version = "0.28", features = ["async-std-runtime", "async-tls"] } async-tungstenite = { version = "0.29", features = ["tokio-rustls-manual-roots"] }
aws-config = { version = "1", features = ["behavior-version-latest"] } aws-config = { version = "1", features = ["behavior-version-latest"] }
aws-credential-types = { version = "1", default-features = false, features = ["hardcoded-credentials", "test-util"] } aws-credential-types = { version = "1", default-features = false, features = ["hardcoded-credentials", "test-util"] }
aws-runtime = { version = "1", default-features = false, features = ["event-stream", "http-02x", "sigv4a"] } aws-runtime = { version = "1", default-features = false, features = ["event-stream", "http-02x", "sigv4a"] }
@ -112,6 +113,7 @@ tokio-rustls = { version = "0.26", default-features = false, features = ["tls12"
tokio-util = { version = "0.7", features = ["codec", "compat", "io"] } tokio-util = { version = "0.7", features = ["codec", "compat", "io"] }
tracing = { version = "0.1", features = ["log"] } tracing = { version = "0.1", features = ["log"] }
tracing-core = { version = "0.1" } tracing-core = { version = "0.1" }
tungstenite = { version = "0.26", default-features = false, features = ["__rustls-tls", "handshake"] }
unicode-properties = { version = "0.1" } unicode-properties = { version = "0.1" }
url = { version = "2", features = ["serde"] } url = { version = "2", features = ["serde"] }
uuid = { version = "1", features = ["serde", "v4", "v5", "v7"] } uuid = { version = "1", features = ["serde", "v4", "v5", "v7"] }
@ -127,7 +129,7 @@ anstream = { version = "0.6" }
arrayvec = { version = "0.7", features = ["serde"] } arrayvec = { version = "0.7", features = ["serde"] }
async-compression = { version = "0.4", default-features = false, features = ["deflate", "deflate64", "futures-io", "gzip"] } async-compression = { version = "0.4", default-features = false, features = ["deflate", "deflate64", "futures-io", "gzip"] }
async-std = { version = "1", features = ["attributes", "unstable"] } async-std = { version = "1", features = ["attributes", "unstable"] }
async-tungstenite = { version = "0.28", features = ["async-std-runtime", "async-tls"] } async-tungstenite = { version = "0.29", features = ["tokio-rustls-manual-roots"] }
aws-config = { version = "1", features = ["behavior-version-latest"] } aws-config = { version = "1", features = ["behavior-version-latest"] }
aws-credential-types = { version = "1", default-features = false, features = ["hardcoded-credentials", "test-util"] } aws-credential-types = { version = "1", default-features = false, features = ["hardcoded-credentials", "test-util"] }
aws-runtime = { version = "1", default-features = false, features = ["event-stream", "http-02x", "sigv4a"] } aws-runtime = { version = "1", default-features = false, features = ["event-stream", "http-02x", "sigv4a"] }
@ -231,6 +233,7 @@ tokio-rustls = { version = "0.26", default-features = false, features = ["tls12"
tokio-util = { version = "0.7", features = ["codec", "compat", "io"] } tokio-util = { version = "0.7", features = ["codec", "compat", "io"] }
tracing = { version = "0.1", features = ["log"] } tracing = { version = "0.1", features = ["log"] }
tracing-core = { version = "0.1" } tracing-core = { version = "0.1" }
tungstenite = { version = "0.26", default-features = false, features = ["__rustls-tls", "handshake"] }
unicode-properties = { version = "0.1" } unicode-properties = { version = "0.1" }
url = { version = "2", features = ["serde"] } url = { version = "2", features = ["serde"] }
uuid = { version = "1", features = ["serde", "v4", "v5", "v7"] } uuid = { version = "1", features = ["serde", "v4", "v5", "v7"] }
@ -257,8 +260,7 @@ ring = { version = "0.17", features = ["std"] }
rustix-d585fab2519d2d1 = { package = "rustix", version = "0.38", default-features = false, features = ["event", "mm", "param", "pipe", "process", "procfs", "termios", "time"] } rustix-d585fab2519d2d1 = { package = "rustix", version = "0.38", default-features = false, features = ["event", "mm", "param", "pipe", "process", "procfs", "termios", "time"] }
rustix-dff4ba8e3ae991db = { package = "rustix", version = "1", features = ["fs", "termios", "time"] } rustix-dff4ba8e3ae991db = { package = "rustix", version = "1", features = ["fs", "termios", "time"] }
scopeguard = { version = "1" } scopeguard = { version = "1" }
security-framework-7b89eefb6aaa9bf3 = { package = "security-framework", version = "3", features = ["OSX_10_14"] } security-framework = { version = "3", features = ["OSX_10_14"] }
security-framework-f595c2ba2a3f28df = { package = "security-framework", version = "2", features = ["alpn"] }
security-framework-sys = { version = "2", features = ["OSX_10_14"] } security-framework-sys = { version = "2", features = ["OSX_10_14"] }
tokio-rustls = { version = "0.26", default-features = false, features = ["ring"] } tokio-rustls = { version = "0.26", default-features = false, features = ["ring"] }
tokio-socks = { version = "0.5", features = ["futures-io"] } tokio-socks = { version = "0.5", features = ["futures-io"] }
@ -283,8 +285,7 @@ ring = { version = "0.17", features = ["std"] }
rustix-d585fab2519d2d1 = { package = "rustix", version = "0.38", default-features = false, features = ["event", "mm", "param", "pipe", "process", "procfs", "termios", "time"] } rustix-d585fab2519d2d1 = { package = "rustix", version = "0.38", default-features = false, features = ["event", "mm", "param", "pipe", "process", "procfs", "termios", "time"] }
rustix-dff4ba8e3ae991db = { package = "rustix", version = "1", features = ["fs", "termios", "time"] } rustix-dff4ba8e3ae991db = { package = "rustix", version = "1", features = ["fs", "termios", "time"] }
scopeguard = { version = "1" } scopeguard = { version = "1" }
security-framework-7b89eefb6aaa9bf3 = { package = "security-framework", version = "3", features = ["OSX_10_14"] } security-framework = { version = "3", features = ["OSX_10_14"] }
security-framework-f595c2ba2a3f28df = { package = "security-framework", version = "2", features = ["alpn"] }
security-framework-sys = { version = "2", features = ["OSX_10_14"] } security-framework-sys = { version = "2", features = ["OSX_10_14"] }
tokio-rustls = { version = "0.26", default-features = false, features = ["ring"] } tokio-rustls = { version = "0.26", default-features = false, features = ["ring"] }
tokio-socks = { version = "0.5", features = ["futures-io"] } tokio-socks = { version = "0.5", features = ["futures-io"] }
@ -307,8 +308,7 @@ ring = { version = "0.17", features = ["std"] }
rustix-d585fab2519d2d1 = { package = "rustix", version = "0.38", default-features = false, features = ["event", "mm", "param", "pipe", "process", "procfs", "termios", "time"] } rustix-d585fab2519d2d1 = { package = "rustix", version = "0.38", default-features = false, features = ["event", "mm", "param", "pipe", "process", "procfs", "termios", "time"] }
rustix-dff4ba8e3ae991db = { package = "rustix", version = "1", features = ["fs", "termios", "time"] } rustix-dff4ba8e3ae991db = { package = "rustix", version = "1", features = ["fs", "termios", "time"] }
scopeguard = { version = "1" } scopeguard = { version = "1" }
security-framework-7b89eefb6aaa9bf3 = { package = "security-framework", version = "3", features = ["OSX_10_14"] } security-framework = { version = "3", features = ["OSX_10_14"] }
security-framework-f595c2ba2a3f28df = { package = "security-framework", version = "2", features = ["alpn"] }
security-framework-sys = { version = "2", features = ["OSX_10_14"] } security-framework-sys = { version = "2", features = ["OSX_10_14"] }
tokio-rustls = { version = "0.26", default-features = false, features = ["ring"] } tokio-rustls = { version = "0.26", default-features = false, features = ["ring"] }
tokio-socks = { version = "0.5", features = ["futures-io"] } tokio-socks = { version = "0.5", features = ["futures-io"] }
@ -333,8 +333,7 @@ ring = { version = "0.17", features = ["std"] }
rustix-d585fab2519d2d1 = { package = "rustix", version = "0.38", default-features = false, features = ["event", "mm", "param", "pipe", "process", "procfs", "termios", "time"] } rustix-d585fab2519d2d1 = { package = "rustix", version = "0.38", default-features = false, features = ["event", "mm", "param", "pipe", "process", "procfs", "termios", "time"] }
rustix-dff4ba8e3ae991db = { package = "rustix", version = "1", features = ["fs", "termios", "time"] } rustix-dff4ba8e3ae991db = { package = "rustix", version = "1", features = ["fs", "termios", "time"] }
scopeguard = { version = "1" } scopeguard = { version = "1" }
security-framework-7b89eefb6aaa9bf3 = { package = "security-framework", version = "3", features = ["OSX_10_14"] } security-framework = { version = "3", features = ["OSX_10_14"] }
security-framework-f595c2ba2a3f28df = { package = "security-framework", version = "2", features = ["alpn"] }
security-framework-sys = { version = "2", features = ["OSX_10_14"] } security-framework-sys = { version = "2", features = ["OSX_10_14"] }
tokio-rustls = { version = "0.26", default-features = false, features = ["ring"] } tokio-rustls = { version = "0.26", default-features = false, features = ["ring"] }
tokio-socks = { version = "0.5", features = ["futures-io"] } tokio-socks = { version = "0.5", features = ["futures-io"] }