|
|
@@ -1,4 +1,5 @@
|
|
|
use crate::utils::shell::run_shell_hidden;
|
|
|
+use crate::utils::http::HttpRequest;
|
|
|
use serde::{Deserialize, Serialize};
|
|
|
use regex::Regex;
|
|
|
use super::config::{get_git_mirror_config, get_nodejs_mirror_config};
|
|
|
@@ -142,8 +143,6 @@ async fn get_nodejs_versions() -> Result<VersionResult, String> {
|
|
|
let mirror_config = get_nodejs_mirror_config().await;
|
|
|
let mirror = mirror_config.mirror.as_str();
|
|
|
|
|
|
- let client = reqwest::Client::new();
|
|
|
-
|
|
|
// 根据镜像源选择 API 地址
|
|
|
let (api_url, mirror_name) = if mirror == "huaweicloud" {
|
|
|
("https://mirrors.huaweicloud.com/nodejs/index.json", "华为云镜像")
|
|
|
@@ -151,14 +150,13 @@ async fn get_nodejs_versions() -> Result<VersionResult, String> {
|
|
|
("https://nodejs.org/dist/index.json", "Node.js 官方")
|
|
|
};
|
|
|
|
|
|
- let response = client
|
|
|
- .get(api_url)
|
|
|
- .timeout(std::time::Duration::from_secs(10))
|
|
|
+ let versions: Vec<serde_json::Value> = HttpRequest::get(api_url)
|
|
|
+ .timeout_secs(15)
|
|
|
.send()
|
|
|
.await
|
|
|
- .map_err(|e| format!("请求 {} 失败: {}", mirror_name, e))?;
|
|
|
-
|
|
|
- let versions: Vec<serde_json::Value> = response.json().await.map_err(|e| e.to_string())?;
|
|
|
+ .map_err(|e| format!("请求 {} 失败: {}", mirror_name, e))?
|
|
|
+ .json()
|
|
|
+ .await?;
|
|
|
|
|
|
let version_items: Vec<VersionItem> = versions
|
|
|
.iter()
|
|
|
@@ -200,17 +198,15 @@ async fn get_git_versions() -> Result<VersionResult, String> {
|
|
|
let mirror_config = get_git_mirror_config().await;
|
|
|
let mirror = mirror_config.mirror.as_str();
|
|
|
|
|
|
- let client = reqwest::Client::new();
|
|
|
-
|
|
|
// 根据镜像类型选择不同的获取方式
|
|
|
let (versions, mirror_name) = match mirror {
|
|
|
"huaweicloud" => {
|
|
|
- let versions = get_git_versions_from_huaweicloud(&client).await;
|
|
|
+ let versions = get_git_versions_from_huaweicloud().await;
|
|
|
(versions, "华为云镜像")
|
|
|
}
|
|
|
_ => {
|
|
|
// 默认使用 GitHub
|
|
|
- let versions = get_git_versions_from_github(&client).await;
|
|
|
+ let versions = get_git_versions_from_github().await;
|
|
|
(versions, "GitHub 官方")
|
|
|
}
|
|
|
};
|
|
|
@@ -240,33 +236,26 @@ async fn get_git_versions() -> Result<VersionResult, String> {
|
|
|
}
|
|
|
|
|
|
/// 从 GitHub API 获取 Git 版本列表
|
|
|
-async fn get_git_versions_from_github(client: &reqwest::Client) -> Vec<String> {
|
|
|
- let response = match client
|
|
|
- .get("https://api.github.com/repos/git-for-windows/git/releases")
|
|
|
- .header("User-Agent", "Claude-AI-Installer")
|
|
|
+async fn get_git_versions_from_github() -> Vec<String> {
|
|
|
+ // 只获取前30个releases,减少响应体大小
|
|
|
+ let response = match HttpRequest::get("https://api.github.com/repos/git-for-windows/git/releases?per_page=30")
|
|
|
.header("Accept", "application/vnd.github.v3+json")
|
|
|
- .timeout(std::time::Duration::from_secs(10))
|
|
|
+ .timeout_secs(30)
|
|
|
.send()
|
|
|
.await
|
|
|
{
|
|
|
Ok(resp) => resp,
|
|
|
- Err(e) => {
|
|
|
- eprintln!("GitHub API 请求失败: {}", e);
|
|
|
- return vec![];
|
|
|
- }
|
|
|
+ Err(_) => return vec![],
|
|
|
};
|
|
|
|
|
|
- if !response.status().is_success() {
|
|
|
- eprintln!("GitHub API 返回错误状态: {}", response.status());
|
|
|
+ if !response.is_success() {
|
|
|
+ log::error!("GitHub API 返回错误状态: {}", response.status());
|
|
|
return vec![];
|
|
|
}
|
|
|
|
|
|
let releases: Vec<serde_json::Value> = match response.json().await {
|
|
|
Ok(r) => r,
|
|
|
- Err(e) => {
|
|
|
- eprintln!("解析 GitHub 响应失败: {}", e);
|
|
|
- return vec![];
|
|
|
- }
|
|
|
+ Err(_) => return vec![],
|
|
|
};
|
|
|
|
|
|
let mut versions: Vec<String> = vec![];
|
|
|
@@ -292,32 +281,24 @@ async fn get_git_versions_from_github(client: &reqwest::Client) -> Vec<String> {
|
|
|
}
|
|
|
|
|
|
/// 从华为云镜像获取 Git 版本列表
|
|
|
-async fn get_git_versions_from_huaweicloud(client: &reqwest::Client) -> Vec<String> {
|
|
|
- let response = match client
|
|
|
- .get("https://mirrors.huaweicloud.com/git-for-windows/")
|
|
|
- .header("User-Agent", "Claude-AI-Installer")
|
|
|
- .timeout(std::time::Duration::from_secs(10))
|
|
|
+async fn get_git_versions_from_huaweicloud() -> Vec<String> {
|
|
|
+ let response = match HttpRequest::get("https://mirrors.huaweicloud.com/git-for-windows/")
|
|
|
+ .timeout_secs(15)
|
|
|
.send()
|
|
|
.await
|
|
|
{
|
|
|
Ok(resp) => resp,
|
|
|
- Err(e) => {
|
|
|
- eprintln!("华为云镜像请求失败: {}", e);
|
|
|
- return vec![];
|
|
|
- }
|
|
|
+ Err(_) => return vec![],
|
|
|
};
|
|
|
|
|
|
- if !response.status().is_success() {
|
|
|
- eprintln!("华为云镜像返回错误状态: {}", response.status());
|
|
|
+ if !response.is_success() {
|
|
|
+ log::error!("华为云镜像返回错误状态: {}", response.status());
|
|
|
return vec![];
|
|
|
}
|
|
|
|
|
|
let html = match response.text().await {
|
|
|
Ok(h) => h,
|
|
|
- Err(e) => {
|
|
|
- eprintln!("读取华为云响应失败: {}", e);
|
|
|
- return vec![];
|
|
|
- }
|
|
|
+ Err(_) => return vec![],
|
|
|
};
|
|
|
|
|
|
// 解析 HTML 页面,查找版本目录链接
|
|
|
@@ -355,26 +336,18 @@ async fn get_git_versions_from_huaweicloud(client: &reqwest::Client) -> Vec<Stri
|
|
|
}
|
|
|
|
|
|
async fn get_vscode_versions() -> Result<VersionResult, String> {
|
|
|
- let client = reqwest::Client::new();
|
|
|
-
|
|
|
// 从 VS Code 官方 API 获取版本列表
|
|
|
- let response = client
|
|
|
- .get("https://update.code.visualstudio.com/api/releases/stable")
|
|
|
- .header("User-Agent", "Claude-AI-Installer")
|
|
|
- .timeout(std::time::Duration::from_secs(10))
|
|
|
+ let response = HttpRequest::get("https://update.code.visualstudio.com/api/releases/stable")
|
|
|
+ .timeout_secs(15)
|
|
|
.send()
|
|
|
- .await
|
|
|
- .map_err(|e| format!("请求 VS Code 版本列表失败: {}", e))?;
|
|
|
+ .await?;
|
|
|
|
|
|
- if !response.status().is_success() {
|
|
|
+ if !response.is_success() {
|
|
|
return Err(format!("VS Code API 返回错误状态: {}", response.status()));
|
|
|
}
|
|
|
|
|
|
// API 返回格式是版本号数组: ["1.96.0", "1.95.3", ...]
|
|
|
- let versions: Vec<String> = response
|
|
|
- .json()
|
|
|
- .await
|
|
|
- .map_err(|e| format!("解析 VS Code 版本列表失败: {}", e))?;
|
|
|
+ let versions: Vec<String> = response.json().await?;
|
|
|
|
|
|
let version_items: Vec<VersionItem> = versions
|
|
|
.into_iter()
|