Rename ZedHttpClient for clarity (#8320)

This PR renames the `ZedHttpClient` to `HttpClientWithUrl` to make it
slightly clearer that it still is holding a `dyn HttpClient` as opposed
to being a concrete implementation.

Release Notes:

- N/A
This commit is contained in:
Marshall Bowers 2024-02-24 00:07:24 -05:00 committed by GitHub
parent 58463b2e97
commit ba4e1699ae
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 77 additions and 70 deletions

View file

@ -29,7 +29,7 @@ use std::{
};
use update_notification::UpdateNotification;
use util::{
http::{HttpClient, ZedHttpClient},
http::{HttpClient, HttpClientWithUrl},
ResultExt,
};
use workspace::Workspace;
@ -67,7 +67,7 @@ pub enum AutoUpdateStatus {
pub struct AutoUpdater {
status: AutoUpdateStatus,
current_version: SemanticVersion,
http_client: Arc<ZedHttpClient>,
http_client: Arc<HttpClientWithUrl>,
pending_poll: Option<Task<Option<()>>>,
}
@ -115,7 +115,7 @@ struct ReleaseNotesBody {
release_notes: String,
}
pub fn init(http_client: Arc<ZedHttpClient>, cx: &mut AppContext) {
pub fn init(http_client: Arc<HttpClientWithUrl>, cx: &mut AppContext) {
AutoUpdateSetting::register(cx);
cx.observe_new_views(|workspace: &mut Workspace, _cx| {
@ -181,7 +181,7 @@ pub fn view_release_notes(_: &ViewReleaseNotes, cx: &mut AppContext) -> Option<(
let current_version = auto_updater.current_version;
let url = &auto_updater
.http_client
.zed_url(&format!("/releases/{release_channel}/{current_version}"));
.build_url(&format!("/releases/{release_channel}/{current_version}"));
cx.open_url(&url);
}
@ -193,7 +193,7 @@ fn view_release_notes_locally(workspace: &mut Workspace, cx: &mut ViewContext<Wo
let version = env!("CARGO_PKG_VERSION");
let client = client::Client::global(cx).http_client();
let url = client.zed_url(&format!(
let url = client.build_url(&format!(
"/api/release_notes/{}/{}",
release_channel.dev_name(),
version
@ -283,7 +283,7 @@ impl AutoUpdater {
cx.default_global::<GlobalAutoUpdate>().0.clone()
}
fn new(current_version: SemanticVersion, http_client: Arc<ZedHttpClient>) -> Self {
fn new(current_version: SemanticVersion, http_client: Arc<HttpClientWithUrl>) -> Self {
Self {
status: AutoUpdateStatus::Idle,
current_version,
@ -337,7 +337,7 @@ impl AutoUpdater {
(this.http_client.clone(), this.current_version)
})?;
let mut url_string = client.zed_url(&format!(
let mut url_string = client.build_url(&format!(
"/api/releases/latest?asset=Zed.dmg&os={}&arch={}",
OS, ARCH
));

View file

@ -42,7 +42,7 @@ use std::{
use telemetry::Telemetry;
use thiserror::Error;
use url::Url;
use util::http::{HttpClient, ZedHttpClient};
use util::http::{HttpClient, HttpClientWithUrl};
use util::{ResultExt, TryFutureExt};
pub use rpc::*;
@ -153,7 +153,7 @@ impl Global for GlobalClient {}
pub struct Client {
id: AtomicU64,
peer: Arc<Peer>,
http: Arc<ZedHttpClient>,
http: Arc<HttpClientWithUrl>,
telemetry: Arc<Telemetry>,
state: RwLock<ClientState>,
@ -424,7 +424,7 @@ impl settings::Settings for TelemetrySettings {
impl Client {
pub fn new(
clock: Arc<dyn SystemClock>,
http: Arc<ZedHttpClient>,
http: Arc<HttpClientWithUrl>,
cx: &mut AppContext,
) -> Arc<Self> {
let client = Arc::new(Self {
@ -447,7 +447,7 @@ impl Client {
self.id.load(std::sync::atomic::Ordering::SeqCst)
}
pub fn http_client(&self) -> Arc<ZedHttpClient> {
pub fn http_client(&self) -> Arc<HttpClientWithUrl> {
self.http.clone()
}
@ -970,14 +970,14 @@ impl Client {
}
async fn get_rpc_url(
http: Arc<ZedHttpClient>,
http: Arc<HttpClientWithUrl>,
release_channel: Option<ReleaseChannel>,
) -> Result<Url> {
if let Some(url) = &*ZED_RPC_URL {
return Url::parse(url).context("invalid rpc url");
}
let mut url = http.zed_url("/rpc");
let mut url = http.build_url("/rpc");
if let Some(preview_param) =
release_channel.and_then(|channel| channel.release_query_param())
{
@ -1110,7 +1110,7 @@ impl Client {
// Open the Zed sign-in page in the user's browser, with query parameters that indicate
// that the user is signing in from a Zed app running on the same device.
let mut url = http.zed_url(&format!(
let mut url = http.build_url(&format!(
"/native_app_signin?native_app_port={}&native_app_public_key={}",
port, public_key_string
));
@ -1145,7 +1145,7 @@ impl Client {
}
let post_auth_url =
http.zed_url("/native_app_signin_succeeded");
http.build_url("/native_app_signin_succeeded");
req.respond(
tiny_http::Response::empty(302).with_header(
tiny_http::Header::from_bytes(
@ -1187,7 +1187,7 @@ impl Client {
}
async fn authenticate_as_admin(
http: Arc<ZedHttpClient>,
http: Arc<HttpClientWithUrl>,
login: String,
mut api_token: String,
) -> Result<Credentials> {

View file

@ -20,7 +20,7 @@ use telemetry_events::{
EditEvent, EditorEvent, Event, EventRequestBody, EventWrapper, MemoryEvent, SettingEvent,
};
use tempfile::NamedTempFile;
use util::http::{self, HttpClient, Method, ZedHttpClient};
use util::http::{self, HttpClient, HttpClientWithUrl, Method};
#[cfg(not(debug_assertions))]
use util::ResultExt;
use util::TryFutureExt;
@ -29,7 +29,7 @@ use self::event_coalescer::EventCoalescer;
pub struct Telemetry {
clock: Arc<dyn SystemClock>,
http_client: Arc<ZedHttpClient>,
http_client: Arc<HttpClientWithUrl>,
executor: BackgroundExecutor,
state: Arc<Mutex<TelemetryState>>,
}
@ -75,7 +75,7 @@ static ZED_CLIENT_CHECKSUM_SEED: Lazy<Option<Vec<u8>>> = Lazy::new(|| {
impl Telemetry {
pub fn new(
clock: Arc<dyn SystemClock>,
client: Arc<ZedHttpClient>,
client: Arc<HttpClientWithUrl>,
cx: &mut AppContext,
) -> Arc<Self> {
let release_channel =
@ -474,7 +474,7 @@ impl Telemetry {
let request = http::Request::builder()
.method(Method::POST)
.uri(this.http_client.zed_api_url("/telemetry/events"))
.uri(this.http_client.build_zed_api_url("/telemetry/events"))
.header("Content-Type", "text/plain")
.header("x-zed-checksum", checksum)
.body(json_bytes.into());

View file

@ -20,7 +20,7 @@ use std::{
time::Duration,
};
use theme::{ThemeRegistry, ThemeSettings};
use util::http::{AsyncBody, ZedHttpClient};
use util::http::{AsyncBody, HttpClientWithUrl};
use util::TryFutureExt;
use util::{http::HttpClient, paths::EXTENSIONS_DIR, ResultExt};
@ -69,7 +69,7 @@ impl ExtensionStatus {
pub struct ExtensionStore {
manifest: Arc<RwLock<Manifest>>,
fs: Arc<dyn Fs>,
http_client: Arc<ZedHttpClient>,
http_client: Arc<HttpClientWithUrl>,
extensions_dir: PathBuf,
extensions_being_installed: HashSet<Arc<str>>,
extensions_being_uninstalled: HashSet<Arc<str>>,
@ -125,7 +125,7 @@ actions!(zed, [ReloadExtensions]);
pub fn init(
fs: Arc<fs::RealFs>,
http_client: Arc<ZedHttpClient>,
http_client: Arc<HttpClientWithUrl>,
language_registry: Arc<LanguageRegistry>,
theme_registry: Arc<ThemeRegistry>,
cx: &mut AppContext,
@ -157,7 +157,7 @@ impl ExtensionStore {
pub fn new(
extensions_dir: PathBuf,
fs: Arc<dyn Fs>,
http_client: Arc<ZedHttpClient>,
http_client: Arc<HttpClientWithUrl>,
language_registry: Arc<LanguageRegistry>,
theme_registry: Arc<ThemeRegistry>,
cx: &mut ModelContext<Self>,
@ -236,7 +236,7 @@ impl ExtensionStore {
search: Option<&str>,
cx: &mut ModelContext<Self>,
) -> Task<Result<Vec<Extension>>> {
let url = self.http_client.zed_api_url(&format!(
let url = self.http_client.build_zed_api_url(&format!(
"/extensions{query}",
query = search
.map(|search| format!("?filter={search}"))
@ -276,7 +276,7 @@ impl ExtensionStore {
log::info!("installing extension {extension_id} {version}");
let url = self
.http_client
.zed_api_url(&format!("/extensions/{extension_id}/{version}/download"));
.build_zed_api_url(&format!("/extensions/{extension_id}/{version}/download"));
let extensions_dir = self.extensions_dir();
let http_client = self.http_client.clone();

View file

@ -299,7 +299,7 @@ impl FeedbackModal {
let installation_id = telemetry.installation_id();
let is_staff = telemetry.is_staff();
let http_client = zed_client.http_client();
let feedback_endpoint = http_client.zed_url("/api/feedback");
let feedback_endpoint = http_client.build_url("/api/feedback");
let request = FeedbackRequestBody {
feedback_text: &feedback_text,
email,

View file

@ -14,56 +14,62 @@ use std::fmt;
use std::{sync::Arc, time::Duration};
pub use url::Url;
pub struct ZedHttpClient {
pub zed_host: Mutex<String>,
client: Box<dyn HttpClient>,
/// An [`HttpClient`] that has a base URL.
pub struct HttpClientWithUrl {
base_url: Mutex<String>,
client: Arc<dyn HttpClient>,
}
impl ZedHttpClient {
pub fn zed_url(&self, path: &str) -> String {
format!("{}{}", self.zed_host.lock(), path)
impl HttpClientWithUrl {
/// Returns a new [`HttpClientWithUrl`] with the given base URL.
pub fn new(base_url: impl Into<String>) -> Self {
Self {
base_url: Mutex::new(base_url.into()),
client: client(),
}
}
pub fn zed_api_url(&self, path: &str) -> String {
let zed_host = self.zed_host.lock().clone();
/// Returns the base URL.
pub fn base_url(&self) -> String {
self.base_url.lock().clone()
}
let host = match zed_host.as_ref() {
/// Sets the base URL.
pub fn set_base_url(&self, base_url: impl Into<String>) {
*self.base_url.lock() = base_url.into();
}
/// Builds a URL using the given path.
pub fn build_url(&self, path: &str) -> String {
format!("{}{}", self.base_url.lock(), path)
}
/// Builds a Zed API URL using the given path.
pub fn build_zed_api_url(&self, path: &str) -> String {
let base_url = self.base_url.lock().clone();
let base_api_url = match base_url.as_ref() {
"https://zed.dev" => "https://api.zed.dev",
"https://staging.zed.dev" => "https://api-staging.zed.dev",
"http://localhost:3000" => "http://localhost:8080",
other => other,
};
format!("{}{}", host, path)
format!("{}{}", base_api_url, path)
}
}
impl HttpClient for Arc<ZedHttpClient> {
impl HttpClient for Arc<HttpClientWithUrl> {
fn send(&self, req: Request<AsyncBody>) -> BoxFuture<Result<Response<AsyncBody>, Error>> {
self.client.send(req)
}
}
impl HttpClient for ZedHttpClient {
impl HttpClient for HttpClientWithUrl {
fn send(&self, req: Request<AsyncBody>) -> BoxFuture<Result<Response<AsyncBody>, Error>> {
self.client.send(req)
}
}
pub fn zed_client(zed_host: &str) -> Arc<ZedHttpClient> {
Arc::new(ZedHttpClient {
zed_host: Mutex::new(zed_host.to_string()),
client: Box::new(
isahc::HttpClient::builder()
.connect_timeout(Duration::from_secs(5))
.low_speed_timeout(100, Duration::from_secs(5))
.proxy(http_proxy_from_env())
.build()
.unwrap(),
),
})
}
pub trait HttpClient: Send + Sync {
fn send(&self, req: Request<AsyncBody>) -> BoxFuture<Result<Response<AsyncBody>, Error>>;
@ -134,20 +140,20 @@ pub struct FakeHttpClient {
#[cfg(feature = "test-support")]
impl FakeHttpClient {
pub fn create<Fut, F>(handler: F) -> Arc<ZedHttpClient>
pub fn create<Fut, F>(handler: F) -> Arc<HttpClientWithUrl>
where
Fut: 'static + Send + futures::Future<Output = Result<Response<AsyncBody>, Error>>,
F: 'static + Send + Sync + Fn(Request<AsyncBody>) -> Fut,
{
Arc::new(ZedHttpClient {
zed_host: Mutex::new("http://test.example".into()),
client: Box::new(Self {
Arc::new(HttpClientWithUrl {
base_url: Mutex::new("http://test.example".into()),
client: Arc::new(Self {
handler: Box::new(move |req| Box::pin(handler(req))),
}),
})
}
pub fn with_404_response() -> Arc<ZedHttpClient> {
pub fn with_404_response() -> Arc<HttpClientWithUrl> {
Self::create(|_| async move {
Ok(Response::builder()
.status(404)
@ -156,7 +162,7 @@ impl FakeHttpClient {
})
}
pub fn with_200_response() -> Arc<ZedHttpClient> {
pub fn with_200_response() -> Arc<HttpClientWithUrl> {
Self::create(|_| async move {
Ok(Response::builder()
.status(200)

View file

@ -46,7 +46,7 @@ use std::{
use theme::{ActiveTheme, SystemAppearance, ThemeRegistry, ThemeSettings};
use util::{
async_maybe,
http::{self, HttpClient, ZedHttpClient},
http::{HttpClient, HttpClientWithUrl},
paths::{self, CRASHES_DIR, CRASHES_RETIRED_DIR},
ResultExt,
};
@ -140,7 +140,9 @@ fn main() {
client::init_settings(cx);
let clock = Arc::new(clock::RealSystemClock);
let http = http::zed_client(&client::ClientSettings::get_global(cx).server_url);
let http = Arc::new(HttpClientWithUrl::new(
&client::ClientSettings::get_global(cx).server_url,
));
let client = client::Client::new(clock, http.clone(), cx);
let mut languages = LanguageRegistry::new(login_shell_env_loaded);
@ -198,9 +200,8 @@ fn main() {
move |cx| {
languages.set_theme(cx.theme().clone());
let new_host = &client::ClientSettings::get_global(cx).server_url;
let mut host = http.zed_host.lock();
if &*host != new_host {
*host = new_host.clone();
if &http.base_url() != new_host {
http.set_base_url(new_host);
if client.status().borrow().is_connected() {
client.reconnect(&cx.to_async());
}
@ -677,7 +678,7 @@ fn init_panic_hook(app: &App, installation_id: Option<String>, session_id: Strin
}));
}
fn upload_panics_and_crashes(http: Arc<ZedHttpClient>, cx: &mut AppContext) {
fn upload_panics_and_crashes(http: Arc<HttpClientWithUrl>, cx: &mut AppContext) {
let telemetry_settings = *client::TelemetrySettings::get_global(cx);
cx.background_executor()
.spawn(async move {
@ -692,12 +693,12 @@ fn upload_panics_and_crashes(http: Arc<ZedHttpClient>, cx: &mut AppContext) {
.detach()
}
/// upload panics to us (via zed.dev)
/// Uploads panics via `zed.dev`.
async fn upload_previous_panics(
http: Arc<ZedHttpClient>,
http: Arc<HttpClientWithUrl>,
telemetry_settings: client::TelemetrySettings,
) -> Result<Option<(i64, String)>> {
let panic_report_url = http.zed_url("/api/panic");
let panic_report_url = http.build_url("/api/panic");
let mut children = smol::fs::read_dir(&*paths::LOGS_DIR).await?;
let mut most_recent_panic = None;
@ -766,7 +767,7 @@ static LAST_CRASH_UPLOADED: &'static str = "LAST_CRASH_UPLOADED";
/// upload crashes from apple's diagnostic reports to our server.
/// (only if telemetry is enabled)
async fn upload_previous_crashes(
http: Arc<ZedHttpClient>,
http: Arc<HttpClientWithUrl>,
most_recent_panic: Option<(i64, String)>,
telemetry_settings: client::TelemetrySettings,
) -> Result<()> {
@ -778,7 +779,7 @@ async fn upload_previous_crashes(
.unwrap_or("zed-2024-01-17-221900.ips".to_string()); // don't upload old crash reports from before we had this.
let mut uploaded = last_uploaded.clone();
let crash_report_url = http.zed_url("/api/crash");
let crash_report_url = http.build_url("/api/crash");
for dir in [&*CRASHES_DIR, &*CRASHES_RETIRED_DIR] {
let mut children = smol::fs::read_dir(&dir).await?;