Files
openidea/src-tauri/src/commands/http.rs
l0ng-aiandClaude 9d4e778c7b feat(settings): HTTP Proxy settings for the IDE's outgoing connections (#194)
* feat(settings): HTTP Proxy settings for the IDE's outgoing connections

Add Appearance & Behavior › System Settings › HTTP Proxy with three modes:
No proxy, Auto-detect proxy settings (the default; environment proxy as
before) and Manual proxy configuration (HTTP or SOCKS, host and port, a
comma-separated "No proxy for" list with `*` wildcards, optional proxy
authentication). "Check connection…" GETs a URL with the settings as edited
and reports the status or the error.

- ide-core: `ProxySettings` plus routing (no-proxy globs, loopback always
  direct, credentials percent-encoded), the current proxy for the process,
  curl arguments and child-process variables.
- ide-http: `client::build` / `client::shared` is the one HTTP client
  constructor; the HTTP Client requests and the update check go through it.
- ide-tools: curl downloads (tools, JDKs, debug adapters, agent registry,
  remote server) follow the setting.
- A manual proxy reaches child processes (language servers, debug adapters,
  terminals, git) as HTTP_PROXY / HTTPS_PROXY / ALL_PROXY / NO_PROXY.
- The proxy password is kept in the owner-only saved passwords file
  (`proxy-password.json` in the app data directory), not in settings.toml.

Co-Authored-By: Claude <[email protected]>

* fix(host): Allow the Unix-only post-start test helpers on Windows

Co-Authored-By: Claude <[email protected]>

---------

Co-authored-by: Claude <[email protected]>
2026-10-29 10:43:30 +08:00

87 lines
2.9 KiB
Rust
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
use crate::state::AppState;
use ide_core::{IdeError, IdeResult, IpcPath, RequestId};
use ide_http::{HistoryEntry, HttpExchange, HttpRequestBlock};
use tauri::{State, Window};
/// The requests of an `.http` file (gutter run icons, Run All).
#[tauri::command]
#[specta::specta]
pub fn http_requests(text: String) -> Vec<HttpRequestBlock> {
ide_http::parse::requests(&text)
}
/// Environment names from the `http-client(.private).env.json` files that apply to `path`.
#[tauri::command]
#[specta::specta]
pub async fn http_environments(
window: Window,
state: State<'_, AppState>,
path: Option<IpcPath>,
) -> IdeResult<Vec<String>> {
let root = state.project(window.label()).ok().map(|p| p.root.clone());
tauri::async_runtime::spawn_blocking(move || ide_http::environments(path.as_deref(), root.as_deref()))
.await
.map_err(|e| IdeError::internal(e.to_string()))?
}
/// Sends request `index` of `text` (the editor buffer of `path`) and records
/// the exchange in the response history. Cancel with `cancel_request(request)`.
#[tauri::command]
#[specta::specta]
pub async fn http_execute(
window: Window,
state: State<'_, AppState>,
request: RequestId,
path: Option<IpcPath>,
text: String,
index: u32,
env: Option<String>,
) -> IdeResult<HttpExchange> {
let project = state.project(window.label())?;
let cancel = state.begin_request(request);
let input = ide_http::RunInput {
text: &text,
index,
file: path.as_deref(),
root: Some(&project.root),
env: env.as_deref(),
};
let result = ide_http::run(input, &cancel).await;
state.end_request(request);
let exchange = result?;
let history = project.http_history.clone();
let saved = exchange.clone();
tauri::async_runtime::spawn_blocking(move || {
if let Err(e) = history.add(&saved) {
tracing::warn!("http history: {}", e.message);
}
});
Ok(exchange)
}
#[tauri::command]
#[specta::specta]
pub fn http_history(window: Window, state: State<'_, AppState>) -> IdeResult<Vec<HistoryEntry>> {
Ok(state.project(window.label())?.http_history.list())
}
#[tauri::command]
#[specta::specta]
pub fn http_history_get(window: Window, state: State<'_, AppState>, id: String) -> IdeResult<HttpExchange> {
state.project(window.label())?.http_history.get(&id)
}
#[tauri::command]
#[specta::specta]
pub fn http_history_clear(window: Window, state: State<'_, AppState>) -> IdeResult<()> {
state.project(window.label())?.http_history.clear()
}
/// System Settings › HTTP Proxy › Check connection: GETs `url` through `proxy` as
/// edited (not yet applied); the response status, or why there was none.
#[tauri::command]
#[specta::specta]
pub async fn proxy_check_connection(proxy: ide_core::settings::ProxySettings, url: String) -> IdeResult<String> {
ide_http::client::check_connection(&proxy, &url, &ide_core::CancellationToken::new()).await
}