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

View file

@ -20,7 +20,7 @@ use futures::{
AsyncReadExt, FutureExt, SinkExt, Stream, StreamExt, TryFutureExt as _, TryStreamExt,
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 parking_lot::RwLock;
use postage::watch;
@ -1086,7 +1086,7 @@ impl Client {
let rpc_url = self.rpc_url(http, release_channel);
let system_id = self.telemetry.system_id();
let metrics_id = self.telemetry.metrics_id();
cx.background_spawn(async move {
cx.spawn(async move |cx| {
use HttpOrHttps::*;
#[derive(Debug)]
@ -1105,7 +1105,12 @@ impl Client {
.host_str()
.zip(rpc_url.port_or_known_default())
.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);
@ -1144,30 +1149,19 @@ impl Client {
request_headers.insert("x-zed-metrics-id", HeaderValue::from_str(&metrics_id)?);
}
match url_scheme {
Https => {
let (stream, _) =
async_tungstenite::async_tls::client_async_tls_with_connector(
request,
stream,
Some(http_client_tls::tls_config().into()),
)
.await?;
Ok(Connection::new(
stream
.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)),
))
}
}
let (stream, _) = async_tungstenite::tokio::client_async_tls_with_connector_and_config(
request,
stream,
Some(Arc::new(http_client_tls::tls_config()).into()),
None,
)
.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 clock::FakeSystemClock;
use gpui::{BackgroundExecutor, TestAppContext};
use gpui::{AppContext as _, BackgroundExecutor, TestAppContext};
use http_client::FakeHttpClient;
use parking_lot::Mutex;
use proto::TypedEnvelope;