Skip to content

Commit dd60cc2

Browse files
client: Send User-Agent header on WebSocket connection requests (cherry-pick #35280) (#35283)
Cherry-picked client: Send `User-Agent` header on WebSocket connection requests (#35280) This PR makes it so we send the `User-Agent` header on the WebSocket connection requests when connecting to Collab. We use the user agent set on the parent HTTP client. Release Notes: - N/A Co-authored-by: Marshall Bowers <git@maxdeviant.com>
1 parent bd1cc7f commit dd60cc2

File tree

4 files changed

+50
-4
lines changed

4 files changed

+50
-4
lines changed

crates/client/src/client.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use futures::{
2121
channel::oneshot, future::BoxFuture,
2222
};
2323
use gpui::{App, AsyncApp, Entity, Global, Task, WeakEntity, actions};
24-
use http_client::{AsyncBody, HttpClient, HttpClientWithUrl};
24+
use http_client::{AsyncBody, HttpClient, HttpClientWithUrl, http};
2525
use parking_lot::RwLock;
2626
use postage::watch;
2727
use proxy::connect_proxy_stream;
@@ -1158,6 +1158,7 @@ impl Client {
11581158

11591159
let http = self.http.clone();
11601160
let proxy = http.proxy().cloned();
1161+
let user_agent = http.user_agent().cloned();
11611162
let credentials = credentials.clone();
11621163
let rpc_url = self.rpc_url(http, release_channel);
11631164
let system_id = self.telemetry.system_id();
@@ -1209,7 +1210,7 @@ impl Client {
12091210
// We then modify the request to add our desired headers.
12101211
let request_headers = request.headers_mut();
12111212
request_headers.insert(
1212-
"Authorization",
1213+
http::header::AUTHORIZATION,
12131214
HeaderValue::from_str(&credentials.authorization_header())?,
12141215
);
12151216
request_headers.insert(
@@ -1221,6 +1222,9 @@ impl Client {
12211222
"x-zed-release-channel",
12221223
HeaderValue::from_str(release_channel.map(|r| r.dev_name()).unwrap_or("unknown"))?,
12231224
);
1225+
if let Some(user_agent) = user_agent {
1226+
request_headers.insert(http::header::USER_AGENT, user_agent);
1227+
}
12241228
if let Some(system_id) = system_id {
12251229
request_headers.insert("x-zed-system-id", HeaderValue::from_str(&system_id)?);
12261230
}

crates/gpui/src/app.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2023,6 +2023,10 @@ impl HttpClient for NullHttpClient {
20232023
.boxed()
20242024
}
20252025

2026+
fn user_agent(&self) -> Option<&http_client::http::HeaderValue> {
2027+
None
2028+
}
2029+
20262030
fn proxy(&self) -> Option<&Url> {
20272031
None
20282032
}

crates/http_client/src/http_client.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ pub mod github;
44
pub use anyhow::{Result, anyhow};
55
pub use async_body::{AsyncBody, Inner};
66
use derive_more::Deref;
7+
use http::HeaderValue;
78
pub use http::{self, Method, Request, Response, StatusCode, Uri};
89

910
use futures::future::BoxFuture;
@@ -39,6 +40,8 @@ impl HttpRequestExt for http::request::Builder {
3940
pub trait HttpClient: 'static + Send + Sync {
4041
fn type_name(&self) -> &'static str;
4142

43+
fn user_agent(&self) -> Option<&HeaderValue>;
44+
4245
fn send(
4346
&self,
4447
req: http::Request<AsyncBody>,
@@ -118,6 +121,10 @@ impl HttpClient for HttpClientWithProxy {
118121
self.client.send(req)
119122
}
120123

124+
fn user_agent(&self) -> Option<&HeaderValue> {
125+
self.client.user_agent()
126+
}
127+
121128
fn proxy(&self) -> Option<&Url> {
122129
self.proxy.as_ref()
123130
}
@@ -135,6 +142,10 @@ impl HttpClient for Arc<HttpClientWithProxy> {
135142
self.client.send(req)
136143
}
137144

145+
fn user_agent(&self) -> Option<&HeaderValue> {
146+
self.client.user_agent()
147+
}
148+
138149
fn proxy(&self) -> Option<&Url> {
139150
self.proxy.as_ref()
140151
}
@@ -250,6 +261,10 @@ impl HttpClient for Arc<HttpClientWithUrl> {
250261
self.client.send(req)
251262
}
252263

264+
fn user_agent(&self) -> Option<&HeaderValue> {
265+
self.client.user_agent()
266+
}
267+
253268
fn proxy(&self) -> Option<&Url> {
254269
self.client.proxy.as_ref()
255270
}
@@ -267,6 +282,10 @@ impl HttpClient for HttpClientWithUrl {
267282
self.client.send(req)
268283
}
269284

285+
fn user_agent(&self) -> Option<&HeaderValue> {
286+
self.client.user_agent()
287+
}
288+
270289
fn proxy(&self) -> Option<&Url> {
271290
self.client.proxy.as_ref()
272291
}
@@ -314,6 +333,10 @@ impl HttpClient for BlockedHttpClient {
314333
})
315334
}
316335

336+
fn user_agent(&self) -> Option<&HeaderValue> {
337+
None
338+
}
339+
317340
fn proxy(&self) -> Option<&Url> {
318341
None
319342
}
@@ -334,6 +357,7 @@ type FakeHttpHandler = Box<
334357
#[cfg(feature = "test-support")]
335358
pub struct FakeHttpClient {
336359
handler: FakeHttpHandler,
360+
user_agent: HeaderValue,
337361
}
338362

339363
#[cfg(feature = "test-support")]
@@ -348,6 +372,7 @@ impl FakeHttpClient {
348372
client: HttpClientWithProxy {
349373
client: Arc::new(Self {
350374
handler: Box::new(move |req| Box::pin(handler(req))),
375+
user_agent: HeaderValue::from_static(type_name::<Self>()),
351376
}),
352377
proxy: None,
353378
},
@@ -390,6 +415,10 @@ impl HttpClient for FakeHttpClient {
390415
future
391416
}
392417

418+
fn user_agent(&self) -> Option<&HeaderValue> {
419+
Some(&self.user_agent)
420+
}
421+
393422
fn proxy(&self) -> Option<&Url> {
394423
None
395424
}

crates/reqwest_client/src/reqwest_client.rs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ static REDACT_REGEX: LazyLock<Regex> = LazyLock::new(|| Regex::new(r"key=[^&]+")
2020
pub struct ReqwestClient {
2121
client: reqwest::Client,
2222
proxy: Option<Url>,
23+
user_agent: Option<HeaderValue>,
2324
handle: tokio::runtime::Handle,
2425
}
2526

@@ -44,9 +45,11 @@ impl ReqwestClient {
4445
Ok(client.into())
4546
}
4647

47-
pub fn proxy_and_user_agent(proxy: Option<Url>, agent: &str) -> anyhow::Result<Self> {
48+
pub fn proxy_and_user_agent(proxy: Option<Url>, user_agent: &str) -> anyhow::Result<Self> {
49+
let user_agent = HeaderValue::from_str(user_agent)?;
50+
4851
let mut map = HeaderMap::new();
49-
map.insert(http::header::USER_AGENT, HeaderValue::from_str(agent)?);
52+
map.insert(http::header::USER_AGENT, user_agent.clone());
5053
let mut client = Self::builder().default_headers(map);
5154
let client_has_proxy;
5255

@@ -73,6 +76,7 @@ impl ReqwestClient {
7376
.build()?;
7477
let mut client: ReqwestClient = client.into();
7578
client.proxy = client_has_proxy.then_some(proxy).flatten();
79+
client.user_agent = Some(user_agent);
7680
Ok(client)
7781
}
7882
}
@@ -96,6 +100,7 @@ impl From<reqwest::Client> for ReqwestClient {
96100
client,
97101
handle,
98102
proxy: None,
103+
user_agent: None,
99104
}
100105
}
101106
}
@@ -216,6 +221,10 @@ impl http_client::HttpClient for ReqwestClient {
216221
type_name::<Self>()
217222
}
218223

224+
fn user_agent(&self) -> Option<&HeaderValue> {
225+
self.user_agent.as_ref()
226+
}
227+
219228
fn send(
220229
&self,
221230
req: http::Request<http_client::AsyncBody>,

0 commit comments

Comments
 (0)