Detailed changes
@@ -224,10 +224,10 @@ version = "0.1.0"
dependencies = [
"anyhow",
"futures 0.3.28",
+ "http 0.1.0",
"serde",
"serde_json",
"tokio",
- "util",
]
[[package]]
@@ -344,6 +344,7 @@ dependencies = [
"fs",
"futures 0.3.28",
"gpui",
+ "http 0.1.0",
"indoc",
"language",
"log",
@@ -388,6 +389,7 @@ dependencies = [
"futures 0.3.28",
"fuzzy",
"gpui",
+ "http 0.1.0",
"language",
"languages",
"log",
@@ -889,6 +891,7 @@ dependencies = [
"db",
"editor",
"gpui",
+ "http 0.1.0",
"isahc",
"log",
"markdown_preview",
@@ -1756,6 +1759,7 @@ dependencies = [
"fs",
"futures 0.3.28",
"gpui",
+ "http 0.1.0",
"language",
"live_kit_client",
"log",
@@ -1958,6 +1962,7 @@ dependencies = [
"collections",
"futures 0.3.28",
"gpui",
+ "http 0.1.0",
"language",
"log",
"rand 0.8.5",
@@ -2188,6 +2193,7 @@ dependencies = [
"feature_flags",
"futures 0.3.28",
"gpui",
+ "http 0.1.0",
"lazy_static",
"log",
"once_cell",
@@ -2318,6 +2324,7 @@ dependencies = [
"gpui",
"headless",
"hex",
+ "http 0.1.0",
"indoc",
"language",
"live_kit_client",
@@ -2387,6 +2394,7 @@ dependencies = [
"futures 0.3.28",
"fuzzy",
"gpui",
+ "http 0.1.0",
"language",
"lazy_static",
"menu",
@@ -2556,6 +2564,7 @@ dependencies = [
"fs",
"futures 0.3.28",
"gpui",
+ "http 0.1.0",
"indoc",
"language",
"lsp",
@@ -3414,6 +3423,7 @@ dependencies = [
"fuzzy",
"git",
"gpui",
+ "http 0.1.0",
"indoc",
"itertools 0.11.0",
"language",
@@ -3717,6 +3727,7 @@ dependencies = [
"fs",
"futures 0.3.28",
"gpui",
+ "http 0.1.0",
"isahc",
"language",
"log",
@@ -3864,6 +3875,7 @@ dependencies = [
"editor",
"futures 0.3.28",
"gpui",
+ "http 0.1.0",
"human_bytes",
"isahc",
"language",
@@ -4472,6 +4484,7 @@ dependencies = [
"derive_more",
"git2",
"gpui",
+ "http 0.1.0",
"lazy_static",
"log",
"parking_lot",
@@ -4511,6 +4524,7 @@ dependencies = [
"futures 0.3.28",
"git",
"gpui",
+ "http 0.1.0",
"isahc",
"pretty_assertions",
"regex",
@@ -4518,7 +4532,6 @@ dependencies = [
"serde_json",
"unindent",
"url",
- "util",
]
[[package]]
@@ -4596,9 +4609,9 @@ version = "0.1.0"
dependencies = [
"anyhow",
"futures 0.3.28",
+ "http 0.1.0",
"serde",
"serde_json",
- "util",
]
[[package]]
@@ -4666,6 +4679,7 @@ dependencies = [
"foreign-types 0.5.0",
"futures 0.3.28",
"gpui_macros",
+ "http 0.1.0",
"image",
"itertools 0.11.0",
"lazy_static",
@@ -4984,6 +4998,20 @@ version = "3.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4d13cdbd5dbb29f9c88095bbdc2590c9cba0d0a1269b983fef6b2cdd7e9f4db1"
+[[package]]
+name = "http"
+version = "0.1.0"
+dependencies = [
+ "anyhow",
+ "futures 0.3.28",
+ "futures-lite 1.13.0",
+ "isahc",
+ "log",
+ "serde",
+ "serde_json",
+ "url",
+]
+
[[package]]
name = "http"
version = "0.2.9"
@@ -5601,6 +5629,7 @@ dependencies = [
"git",
"globset",
"gpui",
+ "http 0.1.0",
"indoc",
"itertools 0.11.0",
"lazy_static",
@@ -5691,6 +5720,7 @@ dependencies = [
"feature_flags",
"futures 0.3.28",
"gpui",
+ "http 0.1.0",
"language",
"lazy_static",
"log",
@@ -6435,6 +6465,7 @@ dependencies = [
"async-trait",
"async_zip",
"futures 0.3.28",
+ "http 0.1.0",
"log",
"semver",
"serde",
@@ -6829,11 +6860,11 @@ version = "0.1.0"
dependencies = [
"anyhow",
"futures 0.3.28",
+ "http 0.1.0",
"isahc",
"schemars",
"serde",
"serde_json",
- "util",
]
[[package]]
@@ -7570,6 +7601,7 @@ dependencies = [
"git2",
"globset",
"gpui",
+ "http 0.1.0",
"itertools 0.11.0",
"language",
"log",
@@ -8841,6 +8873,7 @@ dependencies = [
"futures-batch",
"gpui",
"heed",
+ "http 0.1.0",
"language",
"languages",
"log",
@@ -9756,6 +9789,7 @@ dependencies = [
"env_logger",
"futures 0.3.28",
"gpui",
+ "http 0.1.0",
"language",
"log",
"postage",
@@ -9776,6 +9810,7 @@ version = "0.1.0"
dependencies = [
"anyhow",
"futures 0.3.28",
+ "http 0.1.0",
"serde",
"serde_json",
"smol",
@@ -10157,6 +10192,7 @@ dependencies = [
"ctor",
"env_logger",
"gpui",
+ "http 0.1.0",
"lazy_static",
"log",
"parking_lot",
@@ -11205,7 +11241,6 @@ dependencies = [
"futures-lite 1.13.0",
"git2",
"globset",
- "isahc",
"lazy_static",
"log",
"rand 0.8.5",
@@ -11217,7 +11252,6 @@ dependencies = [
"tempfile",
"tendril",
"unicase",
- "url",
]
[[package]]
@@ -12619,6 +12653,7 @@ dependencies = [
"fs",
"futures 0.3.28",
"gpui",
+ "http 0.1.0",
"itertools 0.11.0",
"language",
"lazy_static",
@@ -12654,6 +12689,7 @@ dependencies = [
"git",
"git2",
"gpui",
+ "http 0.1.0",
"ignore",
"itertools 0.11.0",
"language",
@@ -12903,6 +12939,7 @@ dependencies = [
"go_to_line",
"gpui",
"headless",
+ "http 0.1.0",
"image_viewer",
"inline_completion_button",
"install_cli",
@@ -41,6 +41,7 @@ members = [
"crates/gpui",
"crates/gpui_macros",
"crates/headless",
+ "crates/http",
"crates/image_viewer",
"crates/inline_completion_button",
"crates/install_cli",
@@ -183,6 +184,7 @@ google_ai = { path = "crates/google_ai" }
gpui = { path = "crates/gpui" }
gpui_macros = { path = "crates/gpui_macros" }
headless = { path = "crates/headless" }
+http = { path = "crates/http" }
install_cli = { path = "crates/install_cli" }
image_viewer = { path = "crates/image_viewer" }
inline_completion_button = { path = "crates/inline_completion_button" }
@@ -14,9 +14,9 @@ path = "src/anthropic.rs"
[dependencies]
anyhow.workspace = true
futures.workspace = true
+http.workspace = true
serde.workspace = true
serde_json.workspace = true
-util.workspace = true
[dev-dependencies]
tokio.workspace = true
@@ -1,8 +1,8 @@
use anyhow::{anyhow, Result};
use futures::{io::BufReader, stream::BoxStream, AsyncBufReadExt, AsyncReadExt, StreamExt};
+use http::{AsyncBody, HttpClient, Method, Request as HttpRequest};
use serde::{Deserialize, Serialize};
use std::{convert::TryFrom, sync::Arc};
-use util::http::{AsyncBody, HttpClient, Method, Request as HttpRequest};
#[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq)]
pub enum Model {
@@ -196,7 +196,7 @@ pub async fn stream_completion(
// #[cfg(test)]
// mod tests {
// use super::*;
-// use util::http::IsahcHttpClient;
+// use http::IsahcHttpClient;
// #[tokio::test]
// async fn stream_completion_success() {
@@ -20,6 +20,7 @@ file_icons.workspace = true
fs.workspace = true
futures.workspace = true
gpui.workspace = true
+http.workspace = true
indoc.workspace = true
language.workspace = true
log.workspace = true
@@ -5,13 +5,14 @@ use anyhow::{anyhow, Result};
use editor::{Editor, EditorElement, EditorStyle};
use futures::{future::BoxFuture, stream::BoxStream, FutureExt, StreamExt};
use gpui::{AnyView, AppContext, FontStyle, FontWeight, Task, TextStyle, View, WhiteSpace};
+use http::HttpClient;
use open_ai::{stream_completion, Request, RequestMessage, Role as OpenAiRole};
use settings::Settings;
use std::time::Duration;
use std::{env, sync::Arc};
use theme::ThemeSettings;
use ui::prelude::*;
-use util::{http::HttpClient, ResultExt};
+use util::ResultExt;
pub struct OpenAiCompletionProvider {
api_key: Option<String>,
@@ -62,4 +62,5 @@ release_channel.workspace = true
settings = { workspace = true, features = ["test-support"] }
theme = { workspace = true, features = ["test-support"] }
util = { workspace = true, features = ["test-support"] }
+http = { workspace = true, features = ["test-support"] }
workspace = { workspace = true, features = ["test-support"] }
@@ -18,6 +18,7 @@ client.workspace = true
db.workspace = true
editor.workspace = true
gpui.workspace = true
+http.workspace = true
isahc.workspace = true
log.workspace = true
markdown_preview.workspace = true
@@ -20,6 +20,7 @@ use smol::{fs, io::AsyncReadExt};
use settings::{Settings, SettingsSources, SettingsStore};
use smol::{fs::File, process::Command};
+use http::{HttpClient, HttpClientWithUrl};
use release_channel::{AppCommitSha, AppVersion, ReleaseChannel};
use std::{
env::consts::{ARCH, OS},
@@ -29,10 +30,7 @@ use std::{
time::Duration,
};
use update_notification::UpdateNotification;
-use util::{
- http::{HttpClient, HttpClientWithUrl},
- ResultExt,
-};
+use util::ResultExt;
use workspace::notifications::NotificationId;
use workspace::Workspace;
@@ -50,3 +50,4 @@ language = { workspace = true, features = ["test-support"] }
live_kit_client = { workspace = true, features = ["test-support"] }
project = { workspace = true, features = ["test-support"] }
util = { workspace = true, features = ["test-support"] }
+http = { workspace = true, features = ["test-support"] }
@@ -40,3 +40,4 @@ rpc = { workspace = true, features = ["test-support"] }
client = { workspace = true, features = ["test-support"] }
settings = { workspace = true, features = ["test-support"] }
util = { workspace = true, features = ["test-support"] }
+http = { workspace = true, features = ["test-support"] }
@@ -4,9 +4,9 @@ use super::*;
use client::{test::FakeServer, Client, UserStore};
use clock::FakeSystemClock;
use gpui::{AppContext, Context, Model, TestAppContext};
+use http::FakeHttpClient;
use rpc::proto::{self};
use settings::SettingsStore;
-use util::http::FakeHttpClient;
#[gpui::test]
fn test_update_channels(cx: &mut AppContext) {
@@ -25,6 +25,7 @@ collections.workspace = true
feature_flags.workspace = true
futures.workspace = true
gpui.workspace = true
+http.workspace = true
lazy_static.workspace = true
log.workspace = true
once_cell.workspace = true
@@ -56,3 +57,4 @@ gpui = { workspace = true, features = ["test-support"] }
rpc = { workspace = true, features = ["test-support"] }
settings = { workspace = true, features = ["test-support"] }
util = { workspace = true, features = ["test-support"] }
+http = { workspace = true, features = ["test-support"] }
@@ -20,6 +20,7 @@ use gpui::{
actions, AnyModel, AnyWeakModel, AppContext, AsyncAppContext, BorrowAppContext, Global, Model,
Task, WeakModel,
};
+use http::{HttpClient, HttpClientWithUrl};
use lazy_static::lazy_static;
use parking_lot::RwLock;
use postage::watch;
@@ -47,7 +48,6 @@ use std::{
use telemetry::Telemetry;
use thiserror::Error;
use url::Url;
-use util::http::{HttpClient, HttpClientWithUrl};
use util::{ResultExt, TryFutureExt};
pub use rpc::*;
@@ -204,7 +204,7 @@ pub enum EstablishConnectionError {
#[error("{0}")]
Other(#[from] anyhow::Error),
#[error("{0}")]
- Http(#[from] util::http::Error),
+ Http(#[from] http::Error),
#[error("{0}")]
Io(#[from] std::io::Error),
#[error("{0}")]
@@ -1679,10 +1679,10 @@ mod tests {
use clock::FakeSystemClock;
use gpui::{BackgroundExecutor, Context, TestAppContext};
+ use http::FakeHttpClient;
use parking_lot::Mutex;
use settings::SettingsStore;
use std::future;
- use util::http::FakeHttpClient;
#[gpui::test(iterations = 10)]
async fn test_reconnection(cx: &mut TestAppContext) {
@@ -0,0 +1 @@
+
@@ -5,6 +5,7 @@ use chrono::{DateTime, Utc};
use clock::SystemClock;
use futures::Future;
use gpui::{AppContext, AppMetadata, BackgroundExecutor, Task};
+use http::{self, HttpClient, HttpClientWithUrl, Method};
use once_cell::sync::Lazy;
use parking_lot::Mutex;
use release_channel::ReleaseChannel;
@@ -19,7 +20,6 @@ use telemetry_events::{
SettingEvent,
};
use tempfile::NamedTempFile;
-use util::http::{self, HttpClient, HttpClientWithUrl, Method};
#[cfg(not(debug_assertions))]
use util::ResultExt;
use util::TryFutureExt;
@@ -497,7 +497,7 @@ mod tests {
use chrono::TimeZone;
use clock::FakeSystemClock;
use gpui::TestAppContext;
- use util::http::FakeHttpClient;
+ use http::FakeHttpClient;
#[gpui::test]
fn test_telemetry_flush_on_max_queue_size(cx: &mut TestAppContext) {
@@ -35,6 +35,7 @@ envy = "0.4.2"
futures.workspace = true
google_ai.workspace = true
hex.workspace = true
+http.workspace = true
live_kit_server.workspace = true
log.workspace = true
nanoid.workspace = true
@@ -42,6 +42,7 @@ use futures::{
stream::FuturesUnordered,
FutureExt, SinkExt, StreamExt, TryStreamExt,
};
+use http::IsahcHttpClient;
use prometheus::{register_int_gauge, IntGauge};
use rpc::{
proto::{
@@ -73,7 +74,6 @@ use tracing::{
field::{self},
info_span, instrument, Instrument,
};
-use util::http::IsahcHttpClient;
use self::connection_pool::VersionedMessage;
@@ -19,6 +19,7 @@ use fs::FakeFs;
use futures::{channel::oneshot, StreamExt as _};
use git::GitHostingProviderRegistry;
use gpui::{BackgroundExecutor, Context, Model, Task, TestAppContext, View, VisualTestContext};
+use http::FakeHttpClient;
use language::LanguageRegistry;
use node_runtime::FakeNodeRuntime;
use notifications::NotificationStore;
@@ -41,7 +42,6 @@ use std::{
Arc,
},
};
-use util::http::FakeHttpClient;
use workspace::{Workspace, WorkspaceId, WorkspaceStore};
pub struct TestServer {
@@ -25,6 +25,7 @@ test-support = [
"settings/test-support",
"util/test-support",
"workspace/test-support",
+ "http/test-support",
]
[dependencies]
@@ -84,4 +85,5 @@ rpc = { workspace = true, features = ["test-support"] }
settings = { workspace = true, features = ["test-support"] }
tree-sitter-markdown.workspace = true
util = { workspace = true, features = ["test-support"] }
+http = { workspace = true, features = ["test-support"] }
workspace = { workspace = true, features = ["test-support"] }
@@ -557,11 +557,12 @@ mod tests {
use client::{Client, User, UserStore};
use clock::FakeSystemClock;
use gpui::TestAppContext;
+ use http::FakeHttpClient;
use language::{Language, LanguageConfig};
use project::Project;
use rpc::proto;
use settings::SettingsStore;
- use util::{http::FakeHttpClient, test::marked_text_ranges};
+ use util::test::marked_text_ranges;
#[gpui::test]
async fn test_message_editor(cx: &mut TestAppContext) {
@@ -32,6 +32,7 @@ command_palette_hooks.workspace = true
editor.workspace = true
futures.workspace = true
gpui.workspace = true
+http.workspace = true
language.workspace = true
lsp.workspace = true
menu.workspace = true
@@ -63,3 +64,4 @@ rpc = { workspace = true, features = ["test-support"] }
settings = { workspace = true, features = ["test-support"] }
theme = { workspace = true, features = ["test-support"] }
util = { workspace = true, features = ["test-support"] }
+http = { workspace = true, features = ["test-support"] }
@@ -12,6 +12,8 @@ use gpui::{
actions, AppContext, AsyncAppContext, Context, Entity, EntityId, EventEmitter, Global, Model,
ModelContext, Task, WeakModel,
};
+use http::github::latest_github_release;
+use http::HttpClient;
use language::{
language_settings::{all_language_settings, language_settings, InlineCompletionProvider},
point_from_lsp, point_to_lsp, Anchor, Bias, Buffer, BufferSnapshot, Language, PointUtf16,
@@ -31,9 +33,7 @@ use std::{
path::{Path, PathBuf},
sync::Arc,
};
-use util::{
- fs::remove_matching, github::latest_github_release, http::HttpClient, maybe, paths, ResultExt,
-};
+use util::{fs::remove_matching, maybe, paths, ResultExt};
pub use copilot_completion_provider::CopilotCompletionProvider;
pub use sign_in::CopilotCodeVerification;
@@ -393,7 +393,7 @@ impl Copilot {
Default::default(),
cx.to_async(),
);
- let http = util::http::FakeHttpClient::create(|_| async { unreachable!() });
+ let http = http::FakeHttpClient::create(|_| async { unreachable!() });
let node_runtime = FakeNodeRuntime::new();
let this = cx.new_model(|cx| Self {
server_id: LanguageServerId(0),
@@ -39,6 +39,7 @@ futures.workspace = true
fuzzy.workspace = true
git.workspace = true
gpui.workspace = true
+http.workspace = true
indoc.workspace = true
itertools.workspace = true
language.workspace = true
@@ -91,3 +92,4 @@ tree-sitter-typescript.workspace = true
unindent.workspace = true
util = { workspace = true, features = ["test-support"] }
workspace = { workspace = true, features = ["test-support"] }
+http = { workspace = true, features = ["test-support"] }
@@ -7,13 +7,13 @@ use git::{
parse_git_remote_url, GitHostingProvider, GitHostingProviderRegistry, Oid, PullRequest,
};
use gpui::{Model, ModelContext, Subscription, Task};
+use http::HttpClient;
use language::{markdown, Bias, Buffer, BufferSnapshot, Edit, LanguageRegistry, ParsedMarkdown};
use multi_buffer::MultiBufferRow;
use project::{Item, Project};
use smallvec::SmallVec;
use sum_tree::SumTree;
use url::Url;
-use util::http::HttpClient;
#[derive(Clone, Debug, Default)]
pub struct GitBlameEntry {
@@ -23,6 +23,7 @@ collections.workspace = true
fs.workspace = true
futures.workspace = true
gpui.workspace = true
+http.workspace = true
isahc.workspace = true
language.workspace = true
log.workspace = true
@@ -6,6 +6,7 @@ use async_compression::futures::bufread::GzipDecoder;
use async_tar::Archive;
use futures::io::BufReader;
use futures::AsyncReadExt;
+use http::{self, AsyncBody, HttpClient};
use serde::Deserialize;
use std::{
env, fs, mem,
@@ -13,7 +14,6 @@ use std::{
process::{Command, Stdio},
sync::Arc,
};
-use util::http::{self, AsyncBody, HttpClient};
use wasm_encoder::{ComponentSectionId, Encode as _, RawSection, Section as _};
use wasmparser::Parser;
use wit_component::ComponentEncoder;
@@ -28,6 +28,7 @@ use gpui::{
actions, AppContext, AsyncAppContext, Context, EventEmitter, Global, Model, ModelContext, Task,
WeakModel,
};
+use http::{AsyncBody, HttpClient, HttpClientWithUrl};
use language::{
ContextProviderWithTasks, LanguageConfig, LanguageMatcher, LanguageQueries, LanguageRegistry,
QUERY_FILENAME_PREFIXES,
@@ -46,12 +47,7 @@ use std::{
};
use theme::{ThemeRegistry, ThemeSettings};
use url::Url;
-use util::{
- http::{AsyncBody, HttpClient, HttpClientWithUrl},
- maybe,
- paths::EXTENSIONS_DIR,
- ResultExt,
-};
+use util::{maybe, paths::EXTENSIONS_DIR, ResultExt};
use wasm_host::{
wit::{is_supported_wasm_api_version, wasm_api_version_range},
WasmExtension, WasmHost,
@@ -10,6 +10,7 @@ use collections::BTreeMap;
use fs::{FakeFs, Fs, RealFs};
use futures::{io::BufReader, AsyncReadExt, StreamExt};
use gpui::{Context, TestAppContext};
+use http::{FakeHttpClient, Response};
use language::{LanguageMatcher, LanguageRegistry, LanguageServerBinaryStatus, LanguageServerName};
use node_runtime::FakeNodeRuntime;
use parking_lot::Mutex;
@@ -22,10 +23,7 @@ use std::{
sync::Arc,
};
use theme::ThemeRegistry;
-use util::{
- http::{FakeHttpClient, Response},
- test::temp_tree,
-};
+use util::test::temp_tree;
#[cfg(test)]
#[ctor::ctor]
@@ -13,6 +13,7 @@ use futures::{
Future, FutureExt, StreamExt as _,
};
use gpui::{AppContext, AsyncAppContext, BackgroundExecutor, Task};
+use http::HttpClient;
use language::LanguageRegistry;
use node_runtime::NodeRuntime;
use semantic_version::SemanticVersion;
@@ -20,7 +21,6 @@ use std::{
path::{Path, PathBuf},
sync::{Arc, OnceLock},
};
-use util::http::HttpClient;
use wasmtime::{
component::{Component, ResourceTable},
Engine, Store,
@@ -155,7 +155,7 @@ impl github::Host for WasmState {
options: github::GithubReleaseOptions,
) -> wasmtime::Result<Result<github::GithubRelease, String>> {
maybe!(async {
- let release = util::github::latest_github_release(
+ let release = http::github::latest_github_release(
&repo,
options.require_assets,
options.pre_release,
@@ -24,6 +24,7 @@ futures.workspace = true
gpui.workspace = true
human_bytes = "0.4.1"
isahc.workspace = true
+http.workspace = true
language.workspace = true
log.workspace = true
menu.workspace = true
@@ -10,13 +10,14 @@ use gpui::{
div, rems, AppContext, DismissEvent, EventEmitter, FocusHandle, FocusableView, Model,
PromptLevel, Render, Task, View, ViewContext,
};
+use http::HttpClient;
use isahc::Request;
use language::Buffer;
use project::Project;
use regex::Regex;
use serde_derive::Serialize;
use ui::{prelude::*, Button, ButtonStyle, IconPosition, Tooltip};
-use util::{http::HttpClient, ResultExt};
+use util::ResultExt;
use workspace::notifications::NotificationId;
use workspace::{DismissDecision, ModalView, Toast, Workspace};
@@ -19,6 +19,7 @@ collections.workspace = true
derive_more.workspace = true
git2.workspace = true
gpui.workspace = true
+http.workspace = true
lazy_static.workspace = true
log.workspace = true
parking_lot.workspace = true
@@ -5,9 +5,9 @@ use async_trait::async_trait;
use collections::BTreeMap;
use derive_more::{Deref, DerefMut};
use gpui::{AppContext, Global};
+use http::HttpClient;
use parking_lot::RwLock;
use url::Url;
-use util::http::HttpClient;
use crate::Oid;
@@ -17,12 +17,12 @@ async-trait.workspace = true
futures.workspace = true
git.workspace = true
gpui.workspace = true
+http.workspace = true
isahc.workspace = true
regex.workspace = true
serde.workspace = true
serde_json.workspace = true
url.workspace = true
-util.workspace = true
[dev-dependencies]
unindent.workspace = true
@@ -3,11 +3,11 @@ use std::sync::Arc;
use anyhow::{bail, Context, Result};
use async_trait::async_trait;
use futures::AsyncReadExt;
+use http::HttpClient;
use isahc::config::Configurable;
use isahc::{AsyncBody, Request};
use serde::Deserialize;
use url::Url;
-use util::http::HttpClient;
use git::{
BuildCommitPermalinkParams, BuildPermalinkParams, GitHostingProvider, Oid, ParsedGitRemote,
@@ -3,12 +3,12 @@ use std::sync::{Arc, OnceLock};
use anyhow::{bail, Context, Result};
use async_trait::async_trait;
use futures::AsyncReadExt;
+use http::HttpClient;
use isahc::config::Configurable;
use isahc::{AsyncBody, Request};
use regex::Regex;
use serde::Deserialize;
use url::Url;
-use util::http::HttpClient;
use git::{
BuildCommitPermalinkParams, BuildPermalinkParams, GitHostingProvider, Oid, ParsedGitRemote,
@@ -11,6 +11,6 @@ path = "src/google_ai.rs"
[dependencies]
anyhow.workspace = true
futures.workspace = true
+http.workspace = true
serde.workspace = true
serde_json.workspace = true
-util.workspace = true
@@ -2,8 +2,8 @@ use std::sync::Arc;
use anyhow::{anyhow, Result};
use futures::{io::BufReader, stream::BoxStream, AsyncBufReadExt, AsyncReadExt, StreamExt};
+use http::HttpClient;
use serde::{Deserialize, Serialize};
-use util::http::HttpClient;
pub const API_URL: &str = "https://generativelanguage.googleapis.com";
@@ -12,7 +12,7 @@ workspace = true
[features]
default = []
-test-support = ["backtrace", "collections/test-support", "util/test-support"]
+test-support = ["backtrace", "collections/test-support", "util/test-support", "http/test-support"]
runtime_shaders = []
macos-blade = ["blade-graphics", "blade-macros", "bytemuck"]
@@ -35,6 +35,7 @@ etagere = "0.2"
futures.workspace = true
font-kit = { git = "https://github.com/zed-industries/font-kit", rev = "5a5c4d4" }
gpui_macros.workspace = true
+http.workspace = true
image = "0.23"
itertools.workspace = true
lazy_static.workspace = true
@@ -72,6 +73,7 @@ waker-fn = "1.1.0"
backtrace = "0.3"
collections = { workspace = true, features = ["test-support"] }
util = { workspace = true, features = ["test-support"] }
+http = { workspace = true, features = ["test-support"] }
[target.'cfg(target_os = "macos")'.build-dependencies]
bindgen = "0.65.1"
@@ -19,13 +19,11 @@ use time::UtcOffset;
pub use async_context::*;
use collections::{FxHashMap, FxHashSet, VecDeque};
pub use entity_map::*;
+use http::{self, HttpClient};
pub use model_context::*;
#[cfg(any(test, feature = "test-support"))]
pub use test_context::*;
-use util::{
- http::{self, HttpClient},
- ResultExt,
-};
+use util::ResultExt;
use crate::{
current_platform, init_app_menus, Action, ActionRegistry, Any, AnyView, AnyWindowHandle,
@@ -104,7 +104,7 @@ impl TestAppContext {
let foreground_executor = ForegroundExecutor::new(arc_dispatcher);
let platform = TestPlatform::new(background_executor.clone(), foreground_executor.clone());
let asset_source = Arc::new(());
- let http_client = util::http::FakeHttpClient::with_404_response();
+ let http_client = http::FakeHttpClient::with_404_response();
let text_system = Arc::new(TextSystem::new(platform.text_system()));
Self {
@@ -13,8 +13,9 @@ use image::{ImageBuffer, ImageError};
#[cfg(target_os = "macos")]
use media::core_video::CVImageBuffer;
+use http;
use thiserror::Error;
-use util::{http, ResultExt};
+use util::ResultExt;
/// A source of image content.
#[derive(Clone, Debug)]
@@ -0,0 +1,26 @@
+[package]
+name = "http"
+version = "0.1.0"
+edition = "2021"
+publish = false
+license = "Apache-2.0"
+
+[lints]
+workspace = true
+
+[features]
+test-support = []
+
+[lib]
+path = "src/http.rs"
+doctest = true
+
+[dependencies]
+anyhow.workspace = true
+futures.workspace = true
+isahc.workspace = true
+log.workspace = true
+serde.workspace = true
+serde_json.workspace = true
+futures-lite.workspace = true
+url.workspace = true
@@ -1,4 +1,4 @@
-use crate::http::HttpClient;
+use crate::HttpClient;
use anyhow::{anyhow, bail, Context, Result};
use futures::AsyncReadExt;
use serde::Deserialize;
@@ -0,0 +1,242 @@
+pub mod github;
+
+pub use anyhow::{anyhow, Result};
+use futures::future::BoxFuture;
+use futures_lite::FutureExt;
+use isahc::config::{Configurable, RedirectPolicy};
+pub use isahc::{
+ http::{Method, StatusCode, Uri},
+ AsyncBody, Error, HttpClient as IsahcHttpClient, Request, Response,
+};
+#[cfg(feature = "test-support")]
+use std::fmt;
+use std::{
+ sync::{Arc, Mutex},
+ time::Duration,
+};
+pub use url::Url;
+
+fn http_proxy_from_env() -> Option<isahc::http::Uri> {
+ macro_rules! try_env {
+ ($($env:literal),+) => {
+ $(
+ if let Ok(env) = std::env::var($env) {
+ return env.parse::<isahc::http::Uri>().ok();
+ }
+ )+
+ };
+ }
+
+ try_env!(
+ "ALL_PROXY",
+ "all_proxy",
+ "HTTPS_PROXY",
+ "https_proxy",
+ "HTTP_PROXY",
+ "http_proxy"
+ );
+ None
+}
+
+/// An [`HttpClient`] that has a base URL.
+pub struct HttpClientWithUrl {
+ base_url: Mutex<String>,
+ client: Arc<dyn HttpClient>,
+}
+
+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(),
+ }
+ }
+
+ /// Returns the base URL.
+ pub fn base_url(&self) -> String {
+ self.base_url
+ .lock()
+ .map_or_else(|_| Default::default(), |url| url.clone())
+ }
+
+ /// Sets the base URL.
+ pub fn set_base_url(&self, base_url: impl Into<String>) {
+ let base_url = base_url.into();
+ self.base_url
+ .lock()
+ .map(|mut url| {
+ *url = base_url;
+ })
+ .ok();
+ }
+
+ /// Builds a URL using the given path.
+ pub fn build_url(&self, path: &str) -> String {
+ format!("{}{}", self.base_url(), path)
+ }
+
+ /// Builds a Zed API URL using the given path.
+ pub fn build_zed_api_url(&self, path: &str, query: &[(&str, &str)]) -> Result<Url> {
+ let base_url = self.base_url();
+ 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,
+ };
+
+ Ok(Url::parse_with_params(
+ &format!("{}{}", base_api_url, path),
+ query,
+ )?)
+ }
+}
+
+impl HttpClient for Arc<HttpClientWithUrl> {
+ fn send(
+ &self,
+ req: Request<AsyncBody>,
+ ) -> BoxFuture<'static, Result<Response<AsyncBody>, Error>> {
+ self.client.send(req)
+ }
+}
+
+impl HttpClient for HttpClientWithUrl {
+ fn send(
+ &self,
+ req: Request<AsyncBody>,
+ ) -> BoxFuture<'static, Result<Response<AsyncBody>, Error>> {
+ self.client.send(req)
+ }
+}
+
+pub trait HttpClient: Send + Sync {
+ fn send(
+ &self,
+ req: Request<AsyncBody>,
+ ) -> BoxFuture<'static, Result<Response<AsyncBody>, Error>>;
+
+ fn get<'a>(
+ &'a self,
+ uri: &str,
+ body: AsyncBody,
+ follow_redirects: bool,
+ ) -> BoxFuture<'a, Result<Response<AsyncBody>, Error>> {
+ let request = isahc::Request::builder()
+ .redirect_policy(if follow_redirects {
+ RedirectPolicy::Follow
+ } else {
+ RedirectPolicy::None
+ })
+ .method(Method::GET)
+ .uri(uri)
+ .body(body);
+ match request {
+ Ok(request) => self.send(request),
+ Err(error) => async move { Err(error.into()) }.boxed(),
+ }
+ }
+
+ fn post_json<'a>(
+ &'a self,
+ uri: &str,
+ body: AsyncBody,
+ ) -> BoxFuture<'a, Result<Response<AsyncBody>, Error>> {
+ let request = isahc::Request::builder()
+ .method(Method::POST)
+ .uri(uri)
+ .header("Content-Type", "application/json")
+ .body(body);
+ match request {
+ Ok(request) => self.send(request),
+ Err(error) => async move { Err(error.into()) }.boxed(),
+ }
+ }
+}
+
+pub fn client() -> Arc<dyn HttpClient> {
+ Arc::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(),
+ )
+}
+
+impl HttpClient for isahc::HttpClient {
+ fn send(
+ &self,
+ req: Request<AsyncBody>,
+ ) -> BoxFuture<'static, Result<Response<AsyncBody>, Error>> {
+ let client = self.clone();
+ Box::pin(async move { client.send_async(req).await })
+ }
+}
+
+#[cfg(feature = "test-support")]
+type FakeHttpHandler = Box<
+ dyn Fn(Request<AsyncBody>) -> BoxFuture<'static, Result<Response<AsyncBody>, Error>>
+ + Send
+ + Sync
+ + 'static,
+>;
+
+#[cfg(feature = "test-support")]
+pub struct FakeHttpClient {
+ handler: FakeHttpHandler,
+}
+
+#[cfg(feature = "test-support")]
+impl FakeHttpClient {
+ pub fn create<Fut, F>(handler: F) -> Arc<HttpClientWithUrl>
+ where
+ Fut: futures::Future<Output = Result<Response<AsyncBody>, Error>> + Send + 'static,
+ F: Fn(Request<AsyncBody>) -> Fut + Send + Sync + 'static,
+ {
+ 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<HttpClientWithUrl> {
+ Self::create(|_| async move {
+ Ok(Response::builder()
+ .status(404)
+ .body(Default::default())
+ .unwrap())
+ })
+ }
+
+ pub fn with_200_response() -> Arc<HttpClientWithUrl> {
+ Self::create(|_| async move {
+ Ok(Response::builder()
+ .status(200)
+ .body(Default::default())
+ .unwrap())
+ })
+ }
+}
+
+#[cfg(feature = "test-support")]
+impl fmt::Debug for FakeHttpClient {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.debug_struct("FakeHttpClient").finish()
+ }
+}
+
+#[cfg(feature = "test-support")]
+impl HttpClient for FakeHttpClient {
+ fn send(
+ &self,
+ req: Request<AsyncBody>,
+ ) -> BoxFuture<'static, Result<Response<AsyncBody>, Error>> {
+ let future = (self.handler)(req);
+ Box::pin(async move { future.await.map(Into::into) })
+ }
+}
@@ -34,6 +34,7 @@ fuzzy.workspace = true
git.workspace = true
globset.workspace = true
gpui.workspace = true
+http.workspace = true
itertools.workspace = true
lazy_static.workspace = true
log.workspace = true
@@ -82,3 +83,4 @@ tree-sitter-rust.workspace = true
tree-sitter-typescript.workspace = true
unindent.workspace = true
util = { workspace = true, features = ["test-support"] }
+http = { workspace = true, features = ["test-support"] }
@@ -27,6 +27,7 @@ use collections::{HashMap, HashSet};
use futures::Future;
use gpui::{AppContext, AsyncAppContext, Model, Task};
pub use highlight_map::HighlightMap;
+use http::HttpClient;
use lazy_static::lazy_static;
use lsp::{CodeActionKind, LanguageServerBinary};
use parking_lot::Mutex;
@@ -62,7 +63,6 @@ pub use task_context::{
};
use theme::SyntaxTheme;
use tree_sitter::{self, wasmtime, Query, QueryCursor, WasmStore};
-use util::http::HttpClient;
pub use buffer::Operation;
pub use buffer::*;
@@ -17,6 +17,7 @@ collections.workspace = true
feature_flags.workspace = true
futures.workspace = true
gpui.workspace = true
+http.workspace = true
language.workspace = true
lazy_static.workspace = true
log.workspace = true
@@ -2,17 +2,14 @@ use anyhow::{anyhow, bail, Context, Result};
use async_trait::async_trait;
use futures::StreamExt;
use gpui::AsyncAppContext;
+use http::github::{latest_github_release, GitHubLspBinaryVersion};
pub use language::*;
use lsp::LanguageServerBinary;
use project::project_settings::{BinarySettings, ProjectSettings};
use settings::Settings;
use smol::fs::{self, File};
use std::{any::Any, env::consts, path::PathBuf, sync::Arc};
-use util::{
- fs::remove_matching,
- github::{latest_github_release, GitHubLspBinaryVersion},
- maybe, ResultExt,
-};
+use util::{fs::remove_matching, maybe, ResultExt};
pub struct CLspAdapter;
@@ -2,6 +2,7 @@ use anyhow::{anyhow, Context, Result};
use async_trait::async_trait;
use futures::StreamExt;
use gpui::{AsyncAppContext, Task};
+use http::github::latest_github_release;
pub use language::*;
use lazy_static::lazy_static;
use lsp::LanguageServerBinary;
@@ -21,7 +22,7 @@ use std::{
Arc,
},
};
-use util::{fs::remove_matching, github::latest_github_release, maybe, ResultExt};
+use util::{fs::remove_matching, maybe, ResultExt};
fn server_binary_arguments() -> Vec<OsString> {
vec!["-mode=stdio".into()]
@@ -3,6 +3,7 @@ use async_compression::futures::bufread::GzipDecoder;
use async_trait::async_trait;
use futures::{io::BufReader, StreamExt};
use gpui::AsyncAppContext;
+use http::github::{latest_github_release, GitHubLspBinaryVersion};
pub use language::*;
use lazy_static::lazy_static;
use lsp::LanguageServerBinary;
@@ -18,11 +19,7 @@ use std::{
sync::Arc,
};
use task::{TaskTemplate, TaskTemplates, TaskVariables, VariableName};
-use util::{
- fs::remove_matching,
- github::{latest_github_release, GitHubLspBinaryVersion},
- maybe, ResultExt,
-};
+use util::{fs::remove_matching, maybe, ResultExt};
pub struct RustLspAdapter;
@@ -4,6 +4,7 @@ use async_tar::Archive;
use async_trait::async_trait;
use collections::HashMap;
use gpui::AsyncAppContext;
+use http::github::{build_tarball_url, GitHubLspBinaryVersion};
use language::{LanguageServerName, LspAdapter, LspAdapterDelegate};
use lsp::{CodeActionKind, LanguageServerBinary};
use node_runtime::NodeRuntime;
@@ -17,11 +18,7 @@ use std::{
path::{Path, PathBuf},
sync::Arc,
};
-use util::{
- fs::remove_matching,
- github::{build_tarball_url, GitHubLspBinaryVersion},
- maybe, ResultExt,
-};
+use util::{fs::remove_matching, maybe, ResultExt};
fn typescript_server_binary_arguments(server_path: &Path) -> Vec<OsString> {
vec![server_path.into(), "--stdio".into()]
@@ -22,6 +22,7 @@ async-tar.workspace = true
async-trait.workspace = true
async_zip.workspace = true
futures.workspace = true
+http.workspace = true
log.workspace = true
semver.workspace = true
serde.workspace = true
@@ -4,6 +4,7 @@ use anyhow::{anyhow, bail, Context, Result};
use async_compression::futures::bufread::GzipDecoder;
use async_tar::Archive;
use futures::AsyncReadExt;
+use http::HttpClient;
use semver::Version;
use serde::Deserialize;
use smol::io::BufReader;
@@ -15,7 +16,6 @@ use std::{
path::{Path, PathBuf},
sync::Arc,
};
-use util::http::HttpClient;
use util::ResultExt;
#[cfg(windows)]
@@ -15,8 +15,8 @@ schemars = ["dep:schemars"]
[dependencies]
anyhow.workspace = true
futures.workspace = true
+http.workspace = true
isahc.workspace = true
schemars = { workspace = true, optional = true }
serde.workspace = true
serde_json.workspace = true
-util.workspace = true
@@ -1,11 +1,11 @@
use anyhow::{anyhow, Context, Result};
use futures::{io::BufReader, stream::BoxStream, AsyncBufReadExt, AsyncReadExt, StreamExt};
+use http::{AsyncBody, HttpClient, Method, Request as HttpRequest};
use isahc::config::Configurable;
use serde::{Deserialize, Serialize};
use serde_json::{Map, Value};
use std::time::Duration;
use std::{convert::TryFrom, future::Future};
-use util::http::{AsyncBody, HttpClient, Method, Request as HttpRequest};
pub const OPEN_AI_API_URL: &str = "https://api.openai.com/v1";
@@ -36,6 +36,7 @@ fuzzy.workspace = true
git.workspace = true
globset.workspace = true
gpui.workspace = true
+http.workspace = true
itertools.workspace = true
language.workspace = true
log.workspace = true
@@ -69,6 +69,7 @@ use rand::prelude::*;
use search_history::SearchHistory;
use worktree::LocalSnapshot;
+use http::{HttpClient, Url};
use rpc::{ErrorCode, ErrorExt as _};
use search::SearchQuery;
use serde::Serialize;
@@ -99,9 +100,7 @@ use task::static_source::{StaticSource, TrackedFile};
use terminals::Terminals;
use text::{Anchor, BufferId, LineEnding};
use util::{
- debug_panic, defer,
- http::{HttpClient, Url},
- maybe, merge_json_value_into, parse_env_output,
+ debug_panic, defer, maybe, merge_json_value_into, parse_env_output,
paths::{
LOCAL_SETTINGS_RELATIVE_PATH, LOCAL_TASKS_RELATIVE_PATH, LOCAL_VSCODE_TASKS_RELATIVE_PATH,
},
@@ -1003,7 +1002,7 @@ impl Project {
let fs = Arc::new(RealFs::default());
let languages = LanguageRegistry::test(cx.background_executor().clone());
let clock = Arc::new(FakeSystemClock::default());
- let http_client = util::http::FakeHttpClient::with_404_response();
+ let http_client = http::FakeHttpClient::with_404_response();
let client = cx
.update(|cx| client::Client::new(clock, http_client.clone(), cx))
.unwrap();
@@ -1047,7 +1046,7 @@ impl Project {
let languages = LanguageRegistry::test(cx.executor());
let clock = Arc::new(FakeSystemClock::default());
- let http_client = util::http::FakeHttpClient::with_404_response();
+ let http_client = http::FakeHttpClient::with_404_response();
let client = cx.update(|cx| client::Client::new(clock, http_client.clone(), cx));
let user_store = cx.new_model(|cx| UserStore::new(client.clone(), cx));
let project = cx.update(|cx| {
@@ -29,6 +29,7 @@ gpui.workspace = true
language.workspace = true
log.workspace = true
heed.workspace = true
+http.workspace = true
open_ai.workspace = true
parking_lot.workspace = true
project.workspace = true
@@ -58,3 +59,4 @@ tempfile.workspace = true
util = { workspace = true, features = ["test-support"] }
worktree = { workspace = true, features = ["test-support"] }
workspace = { workspace = true, features = ["test-support"] }
+http = { workspace = true, features = ["test-support"] }
@@ -1,6 +1,7 @@
use client::Client;
use futures::channel::oneshot;
use gpui::App;
+use http::HttpClientWithUrl;
use language::language_settings::AllLanguageSettings;
use project::Project;
use semantic_index::{OpenAiEmbeddingModel, OpenAiEmbeddingProvider, SemanticIndex};
@@ -9,7 +10,6 @@ use std::{
path::{Path, PathBuf},
sync::Arc,
};
-use util::http::HttpClientWithUrl;
fn main() {
env_logger::init();
@@ -1,8 +1,8 @@
use anyhow::{Context as _, Result};
use futures::{future::BoxFuture, AsyncReadExt, FutureExt};
+use http::HttpClient;
use serde::{Deserialize, Serialize};
use std::sync::Arc;
-use util::http::HttpClient;
use crate::{Embedding, EmbeddingProvider, TextToEmbed};
@@ -1,9 +1,9 @@
use crate::{Embedding, EmbeddingProvider, TextToEmbed};
use anyhow::Result;
use futures::{future::BoxFuture, FutureExt};
+use http::HttpClient;
pub use open_ai::OpenAiEmbeddingModel;
use std::sync::Arc;
-use util::http::HttpClient;
pub struct OpenAiEmbeddingProvider {
client: Arc<dyn HttpClient>,
@@ -39,3 +39,4 @@ project = { workspace = true, features = ["test-support"] }
settings = { workspace = true, features = ["test-support"] }
theme = { workspace = true, features = ["test-support"] }
util = { workspace = true, features = ["test-support"] }
+http = { workspace = true, features = ["test-support"] }
@@ -15,6 +15,7 @@ doctest = false
[dependencies]
anyhow.workspace = true
futures.workspace = true
+http.workspace = true
serde.workspace = true
serde_json.workspace = true
smol.workspace = true
@@ -1,12 +1,12 @@
use anyhow::{anyhow, Context, Result};
use futures::io::BufReader;
use futures::{AsyncReadExt, Future};
+use http::{AsyncBody, HttpClient, Request as HttpRequest};
use serde::{Deserialize, Serialize};
use smol::fs::{self, File};
use smol::stream::StreamExt;
use std::path::{Path, PathBuf};
use std::sync::Arc;
-use util::http::{AsyncBody, HttpClient, Request as HttpRequest};
use util::paths::SUPERMAVEN_DIR;
#[derive(Serialize)]
@@ -37,3 +37,4 @@ env_logger.workspace = true
gpui = { workspace = true, features = ["test-support"] }
rand.workspace = true
util = { workspace = true, features = ["test-support"] }
+http = { workspace = true, features = ["test-support"] }
@@ -22,7 +22,6 @@ dirs = "3.0"
futures.workspace = true
git2 = { workspace = true, optional = true }
globset.workspace = true
-isahc.workspace = true
lazy_static.workspace = true
log.workspace = true
rand.workspace = true
@@ -35,7 +34,6 @@ futures-lite.workspace = true
take-until = "0.2.0"
tempfile = { workspace = true, optional = true }
unicase.workspace = true
-url.workspace = true
[target.'cfg(windows)'.dependencies]
tendril = "0.4.3"
@@ -1,219 +1 @@
-use crate::http_proxy_from_env;
-pub use anyhow::{anyhow, Result};
-use futures::future::BoxFuture;
-use futures_lite::FutureExt;
-use isahc::config::{Configurable, RedirectPolicy};
-pub use isahc::{
- http::{Method, StatusCode, Uri},
- AsyncBody, Error, HttpClient as IsahcHttpClient, Request, Response,
-};
-#[cfg(feature = "test-support")]
-use std::fmt;
-use std::{
- sync::{Arc, Mutex},
- time::Duration,
-};
-pub use url::Url;
-/// An [`HttpClient`] that has a base URL.
-pub struct HttpClientWithUrl {
- base_url: Mutex<String>,
- client: Arc<dyn HttpClient>,
-}
-
-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(),
- }
- }
-
- /// Returns the base URL.
- pub fn base_url(&self) -> String {
- self.base_url
- .lock()
- .map_or_else(|_| Default::default(), |url| url.clone())
- }
-
- /// Sets the base URL.
- pub fn set_base_url(&self, base_url: impl Into<String>) {
- let base_url = base_url.into();
- self.base_url
- .lock()
- .map(|mut url| {
- *url = base_url;
- })
- .ok();
- }
-
- /// Builds a URL using the given path.
- pub fn build_url(&self, path: &str) -> String {
- format!("{}{}", self.base_url(), path)
- }
-
- /// Builds a Zed API URL using the given path.
- pub fn build_zed_api_url(&self, path: &str, query: &[(&str, &str)]) -> Result<Url> {
- let base_url = self.base_url();
- 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,
- };
-
- Ok(Url::parse_with_params(
- &format!("{}{}", base_api_url, path),
- query,
- )?)
- }
-}
-
-impl HttpClient for Arc<HttpClientWithUrl> {
- fn send(
- &self,
- req: Request<AsyncBody>,
- ) -> BoxFuture<'static, Result<Response<AsyncBody>, Error>> {
- self.client.send(req)
- }
-}
-
-impl HttpClient for HttpClientWithUrl {
- fn send(
- &self,
- req: Request<AsyncBody>,
- ) -> BoxFuture<'static, Result<Response<AsyncBody>, Error>> {
- self.client.send(req)
- }
-}
-
-pub trait HttpClient: Send + Sync {
- fn send(
- &self,
- req: Request<AsyncBody>,
- ) -> BoxFuture<'static, Result<Response<AsyncBody>, Error>>;
-
- fn get<'a>(
- &'a self,
- uri: &str,
- body: AsyncBody,
- follow_redirects: bool,
- ) -> BoxFuture<'a, Result<Response<AsyncBody>, Error>> {
- let request = isahc::Request::builder()
- .redirect_policy(if follow_redirects {
- RedirectPolicy::Follow
- } else {
- RedirectPolicy::None
- })
- .method(Method::GET)
- .uri(uri)
- .body(body);
- match request {
- Ok(request) => self.send(request),
- Err(error) => async move { Err(error.into()) }.boxed(),
- }
- }
-
- fn post_json<'a>(
- &'a self,
- uri: &str,
- body: AsyncBody,
- ) -> BoxFuture<'a, Result<Response<AsyncBody>, Error>> {
- let request = isahc::Request::builder()
- .method(Method::POST)
- .uri(uri)
- .header("Content-Type", "application/json")
- .body(body);
- match request {
- Ok(request) => self.send(request),
- Err(error) => async move { Err(error.into()) }.boxed(),
- }
- }
-}
-
-pub fn client() -> Arc<dyn HttpClient> {
- Arc::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(),
- )
-}
-
-impl HttpClient for isahc::HttpClient {
- fn send(
- &self,
- req: Request<AsyncBody>,
- ) -> BoxFuture<'static, Result<Response<AsyncBody>, Error>> {
- let client = self.clone();
- Box::pin(async move { client.send_async(req).await })
- }
-}
-
-#[cfg(feature = "test-support")]
-type FakeHttpHandler = Box<
- dyn Fn(Request<AsyncBody>) -> BoxFuture<'static, Result<Response<AsyncBody>, Error>>
- + Send
- + Sync
- + 'static,
->;
-
-#[cfg(feature = "test-support")]
-pub struct FakeHttpClient {
- handler: FakeHttpHandler,
-}
-
-#[cfg(feature = "test-support")]
-impl FakeHttpClient {
- pub fn create<Fut, F>(handler: F) -> Arc<HttpClientWithUrl>
- where
- Fut: futures::Future<Output = Result<Response<AsyncBody>, Error>> + Send + 'static,
- F: Fn(Request<AsyncBody>) -> Fut + Send + Sync + 'static,
- {
- 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<HttpClientWithUrl> {
- Self::create(|_| async move {
- Ok(Response::builder()
- .status(404)
- .body(Default::default())
- .unwrap())
- })
- }
-
- pub fn with_200_response() -> Arc<HttpClientWithUrl> {
- Self::create(|_| async move {
- Ok(Response::builder()
- .status(200)
- .body(Default::default())
- .unwrap())
- })
- }
-}
-
-#[cfg(feature = "test-support")]
-impl fmt::Debug for FakeHttpClient {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.debug_struct("FakeHttpClient").finish()
- }
-}
-
-#[cfg(feature = "test-support")]
-impl HttpClient for FakeHttpClient {
- fn send(
- &self,
- req: Request<AsyncBody>,
- ) -> BoxFuture<'static, Result<Response<AsyncBody>, Error>> {
- let future = (self.handler)(req);
- Box::pin(async move { future.await.map(Into::into) })
- }
-}
@@ -1,7 +1,5 @@
pub mod arc_cow;
pub mod fs;
-pub mod github;
-pub mod http;
pub mod paths;
pub mod serde;
#[cfg(any(test, feature = "test-support"))]
@@ -43,28 +41,6 @@ pub fn truncate(s: &str, max_chars: usize) -> &str {
}
}
-pub fn http_proxy_from_env() -> Option<isahc::http::Uri> {
- macro_rules! try_env {
- ($($env:literal),+) => {
- $(
- if let Ok(env) = std::env::var($env) {
- return env.parse::<isahc::http::Uri>().ok();
- }
- )+
- };
- }
-
- try_env!(
- "ALL_PROXY",
- "all_proxy",
- "HTTPS_PROXY",
- "https_proxy",
- "HTTP_PROXY",
- "http_proxy"
- );
- None
-}
-
/// Removes characters from the end of the string if its length is greater than `max_chars` and
/// appends "..." to the string. Returns string unchanged if its length is smaller than max_chars.
pub fn truncate_and_trailoff(s: &str, max_chars: usize) -> String {
@@ -16,6 +16,7 @@ doctest = false
test-support = [
"call/test-support",
"client/test-support",
+ "http/test-support",
"db/test-support",
"project/test-support",
"settings/test-support",
@@ -37,6 +38,7 @@ derive_more.workspace = true
fs.workspace = true
futures.workspace = true
gpui.workspace = true
+http.workspace = true
itertools.workspace = true
language.workspace = true
lazy_static.workspace = true
@@ -67,3 +69,4 @@ fs = { workspace = true, features = ["test-support"] }
gpui = { workspace = true, features = ["test-support"] }
project = { workspace = true, features = ["test-support"] }
settings = { workspace = true, features = ["test-support"] }
+http = { workspace = true, features = ["test-support"] }
@@ -463,7 +463,7 @@ impl AppState {
let fs = fs::FakeFs::new(cx.background_executor().clone());
let languages = Arc::new(LanguageRegistry::test(cx.background_executor().clone()));
let clock = Arc::new(clock::FakeSystemClock::default());
- let http_client = util::http::FakeHttpClient::with_404_response();
+ let http_client = http::FakeHttpClient::with_404_response();
let client = Client::new(clock, http_client.clone(), cx);
let user_store = cx.new_model(|cx| UserStore::new(client.clone(), cx));
let workspace_store = cx.new_model(|cx| WorkspaceStore::new(client.clone(), cx));
@@ -19,6 +19,7 @@ test-support = [
"settings/test-support",
"text/test-support",
"gpui/test-support",
+ "http/test-support",
]
[dependencies]
@@ -53,6 +54,7 @@ clock = {workspace = true, features = ["test-support"]}
collections = { workspace = true, features = ["test-support"] }
git2.workspace = true
gpui = {workspace = true, features = ["test-support"]}
+http.workspace = true
rand.workspace = true
settings = {workspace = true, features = ["test-support"]}
pretty_assertions.workspace = true
@@ -8,6 +8,7 @@ use clock::FakeSystemClock;
use fs::{FakeFs, Fs, RealFs, RemoveOptions};
use git::{repository::GitFileStatus, GITIGNORE};
use gpui::{BorrowAppContext, ModelContext, Task, TestAppContext};
+use http::FakeHttpClient;
use parking_lot::Mutex;
use postage::stream::Stream;
use pretty_assertions::assert_eq;
@@ -21,7 +22,7 @@ use std::{
path::{Path, PathBuf},
sync::Arc,
};
-use util::{http::FakeHttpClient, test::temp_tree, ResultExt};
+use util::{test::temp_tree, ResultExt};
#[gpui::test]
async fn test_traversal(cx: &mut TestAppContext) {
@@ -50,6 +50,7 @@ git_hosting_providers.workspace = true
go_to_line.workspace = true
gpui.workspace = true
headless.workspace = true
+http.workspace = true
image_viewer.workspace = true
inline_completion_button.workspace = true
install_cli.workspace = true
@@ -5,6 +5,7 @@ use db::kvp::KEY_VALUE_STORE;
use gpui::{App, AppContext, SemanticVersion};
use isahc::config::Configurable;
+use http::{self, HttpClient, HttpClientWithUrl};
use paths::{CRASHES_DIR, CRASHES_RETIRED_DIR};
use release_channel::ReleaseChannel;
use release_channel::RELEASE_CHANNEL;
@@ -17,10 +18,7 @@ use std::{
sync::{atomic::Ordering, Arc},
};
use std::{io::Write, panic, sync::atomic::AtomicU32, thread};
-use util::{
- http::{self, HttpClient, HttpClientWithUrl},
- paths, ResultExt,
-};
+use util::{paths, ResultExt};
use crate::stdout_is_a_pty;
@@ -198,13 +196,13 @@ pub fn monitor_main_thread_hangs(
use parking_lot::Mutex;
+ use http::Method;
use std::{
ffi::c_int,
sync::{mpsc, OnceLock},
time::Duration,
};
use telemetry_events::{BacktraceFrame, HangReport};
- use util::http::Method;
use nix::sys::pthread;