Remove reqwest dependency from gpui (#44424)

This was pulling in tokio which is pretty unfortunate. The solution is
to do the `reqwest::Form` to `http::Reqwest` conversion in the
reliability crate instead of our http client wrapper.

Release Notes:

- N/A
This commit is contained in:
Julia Ryan 2025-12-09 09:29:40 -08:00 committed by GitHub
parent 20fa9983ad
commit 04d920016f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 10 additions and 67 deletions

1
Cargo.lock generated
View file

@ -7756,7 +7756,6 @@ dependencies = [
"tempfile",
"url",
"util",
"zed-reqwest",
]
[[package]]

View file

@ -28,7 +28,6 @@ http-body.workspace = true
http.workspace = true
log.workspace = true
parking_lot.workspace = true
reqwest.workspace = true
serde.workspace = true
serde_json.workspace = true
serde_urlencoded.workspace = true

View file

@ -88,17 +88,6 @@ impl From<&'static str> for AsyncBody {
}
}
impl TryFrom<reqwest::Body> for AsyncBody {
type Error = anyhow::Error;
fn try_from(value: reqwest::Body) -> Result<Self, Self::Error> {
value
.as_bytes()
.ok_or_else(|| anyhow::anyhow!("Underlying data is a stream"))
.map(|bytes| Self::from_bytes(Bytes::copy_from_slice(bytes)))
}
}
impl<T: Into<Self>> From<Option<T>> for AsyncBody {
fn from(body: Option<T>) -> Self {
match body {

View file

@ -8,10 +8,7 @@ use derive_more::Deref;
use http::HeaderValue;
pub use http::{self, Method, Request, Response, StatusCode, Uri, request::Builder};
use futures::{
FutureExt as _,
future::{self, BoxFuture},
};
use futures::future::BoxFuture;
use parking_lot::Mutex;
use serde::Serialize;
use std::sync::Arc;
@ -110,14 +107,6 @@ pub trait HttpClient: 'static + Send + Sync {
fn as_fake(&self) -> &FakeHttpClient {
panic!("called as_fake on {}", type_name::<Self>())
}
fn send_multipart_form<'a>(
&'a self,
_url: &str,
_request: reqwest::multipart::Form,
) -> BoxFuture<'a, anyhow::Result<Response<AsyncBody>>> {
future::ready(Err(anyhow!("not implemented"))).boxed()
}
}
/// An [`HttpClient`] that may have a proxy.
@ -165,14 +154,6 @@ impl HttpClient for HttpClientWithProxy {
fn as_fake(&self) -> &FakeHttpClient {
self.client.as_fake()
}
fn send_multipart_form<'a>(
&'a self,
url: &str,
form: reqwest::multipart::Form,
) -> BoxFuture<'a, anyhow::Result<Response<AsyncBody>>> {
self.client.send_multipart_form(url, form)
}
}
/// An [`HttpClient`] that has a base URL.
@ -306,14 +287,6 @@ impl HttpClient for HttpClientWithUrl {
fn as_fake(&self) -> &FakeHttpClient {
self.client.as_fake()
}
fn send_multipart_form<'a>(
&'a self,
url: &str,
request: reqwest::multipart::Form,
) -> BoxFuture<'a, anyhow::Result<Response<AsyncBody>>> {
self.client.send_multipart_form(url, request)
}
}
pub fn read_proxy_from_env() -> Option<Url> {

View file

@ -270,26 +270,6 @@ impl http_client::HttpClient for ReqwestClient {
}
.boxed()
}
fn send_multipart_form<'a>(
&'a self,
url: &str,
form: reqwest::multipart::Form,
) -> futures::future::BoxFuture<'a, anyhow::Result<http_client::Response<http_client::AsyncBody>>>
{
let response = self.client.post(url).multipart(form).send();
self.handle
.spawn(async move {
let response = response.await?;
let mut builder = http::response::Builder::new().status(response.status());
for (k, v) in response.headers() {
builder = builder.header(k, v)
}
Ok(builder.body(response.bytes().await?.into())?)
})
.map(|e| e?)
.boxed()
}
}
#[cfg(test)]

View file

@ -1,8 +1,8 @@
use anyhow::{Context as _, Result};
use client::{Client, telemetry::MINIDUMP_ENDPOINT};
use futures::AsyncReadExt;
use futures::{AsyncReadExt, TryStreamExt};
use gpui::{App, AppContext as _, SerializedThreadTaskTimings};
use http_client::{self, HttpClient};
use http_client::{self, AsyncBody, HttpClient, Request};
use log::info;
use project::Project;
use proto::{CrashReport, GetCrashFilesResponse};
@ -296,11 +296,14 @@ async fn upload_minidump(
// TODO: feature-flag-context, and more of device-context like screen resolution, available ram, device model, etc
let stream = form
.into_stream()
.map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e))
.into_async_read();
let body = AsyncBody::from_reader(stream);
let req = Request::builder().uri(endpoint).body(body)?;
let mut response_text = String::new();
let mut response = client
.http_client()
.send_multipart_form(endpoint, form)
.await?;
let mut response = client.http_client().send(req).await?;
response
.body_mut()
.read_to_string(&mut response_text)