Skip to content

Commit e268d50

Browse files
committed
feat: use dynamic timeout
1 parent a087259 commit e268d50

File tree

4 files changed

+54
-41
lines changed

4 files changed

+54
-41
lines changed

src/cgi_trace.rs

Lines changed: 31 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,14 @@ const CF_TRACE_URL: &str = "https://1.0.0.1/cdn-cgi/trace";
1818
#[allow(unused)]
1919
const CF_CN_TRACE_URL: &str = "https://cf-ns.com/cdn-cgi/trace";
2020

21-
// IP 查询超时时间
22-
const TIMEOUT: Duration = Duration::from_secs(5);
23-
2421
type IpBoxFuture<'a> = BoxFuture<'a, Result<(IpAddr, &'a str), Box<dyn std::error::Error>>>;
2522

26-
pub async fn get_ip(proxy_url: &str) -> Result<(IpAddr, &str), Box<dyn std::error::Error>> {
27-
let cf_future: IpBoxFuture = async {
28-
match get_trace_info_with_proxy(proxy_url, CF_TRACE_URL).await {
23+
pub async fn get_ip(
24+
proxy_url: &str,
25+
timeout: Duration,
26+
) -> Result<(IpAddr, &str), Box<dyn std::error::Error>> {
27+
let cf_future: IpBoxFuture = async move {
28+
match get_trace_info_with_proxy(proxy_url, CF_TRACE_URL, timeout).await {
2929
Ok(trace) => Ok((trace.ip, "cf")),
3030
Err(e) => {
3131
error!("从 Cloudflare 获取 IP 失败, {e}");
@@ -35,8 +35,8 @@ pub async fn get_ip(proxy_url: &str) -> Result<(IpAddr, &str), Box<dyn std::erro
3535
}
3636
.boxed();
3737

38-
let ipify_future: IpBoxFuture = async {
39-
match get_ip_by_ipify(proxy_url).await {
38+
let ipify_future: IpBoxFuture = async move {
39+
match get_ip_by_ipify(proxy_url, timeout).await {
4040
Ok(ip) => Ok((ip, "ipify")),
4141
Err(e) => {
4242
error!("从 ipify 获取 IP 失败, {e}");
@@ -46,8 +46,8 @@ pub async fn get_ip(proxy_url: &str) -> Result<(IpAddr, &str), Box<dyn std::erro
4646
}
4747
.boxed();
4848

49-
let openai_future: IpBoxFuture = async {
50-
match get_trace_info_with_proxy(proxy_url, OPENAI_TRACE_URL).await {
49+
let openai_future: IpBoxFuture = async move {
50+
match get_trace_info_with_proxy(proxy_url, OPENAI_TRACE_URL, timeout).await {
5151
Ok(trace) => Ok((trace.ip, "openai")),
5252
Err(e) => {
5353
error!("从 OpenAI 获取 IP 失败, {e}");
@@ -66,9 +66,12 @@ pub async fn get_ip(proxy_url: &str) -> Result<(IpAddr, &str), Box<dyn std::erro
6666

6767
// clash 规则走的是国内,没走代理所以寄
6868
#[allow(dead_code)]
69-
async fn get_ip_by_ipip(proxy_url: &str) -> Result<IpAddr, Box<dyn std::error::Error>> {
69+
async fn get_ip_by_ipip(
70+
proxy_url: &str,
71+
timeout: Duration,
72+
) -> Result<IpAddr, Box<dyn std::error::Error>> {
7073
let client = Client::builder()
71-
.timeout(TIMEOUT)
74+
.timeout(timeout)
7275
.proxy(reqwest::Proxy::all(proxy_url)?)
7376
.build()?;
7477

@@ -85,9 +88,12 @@ async fn get_ip_by_ipip(proxy_url: &str) -> Result<IpAddr, Box<dyn std::error::E
8588
Err("Failed to parse IP address".into())
8689
}
8790

88-
async fn get_ip_by_ipify(proxy_url: &str) -> Result<IpAddr, Box<dyn std::error::Error>> {
91+
async fn get_ip_by_ipify(
92+
proxy_url: &str,
93+
timeout: Duration,
94+
) -> Result<IpAddr, Box<dyn std::error::Error>> {
8995
let client = Client::builder()
90-
.timeout(TIMEOUT)
96+
.timeout(timeout)
9197
.proxy(reqwest::Proxy::all(proxy_url)?)
9298
.build()?;
9399

@@ -140,9 +146,10 @@ fn parse_trace_info(text: String) -> TraceInfo {
140146
async fn get_trace_info_with_proxy(
141147
proxy_url: &str,
142148
trace_url: &str,
149+
timeout: Duration,
143150
) -> Result<TraceInfo, Box<dyn std::error::Error>> {
144151
let client = Client::builder()
145-
.timeout(TIMEOUT)
152+
.timeout(timeout)
146153
.proxy(reqwest::Proxy::all(proxy_url)?)
147154
.build()?;
148155

@@ -197,27 +204,30 @@ mod tests {
197204
#[tokio::test]
198205
#[ignore]
199206
async fn test_get_ip() {
200-
let result = get_ip(PROXY_URL).await;
207+
let result = get_ip(PROXY_URL, Duration::from_secs(5)).await;
201208
println!("{:?}", result.unwrap())
202209
}
203210

204211
#[tokio::test]
205212
#[ignore]
206213
async fn test_get_trace_info_with_proxy() {
207-
let result = get_trace_info_with_proxy(PROXY_URL, OPENAI_TRACE_URL).await;
214+
let result =
215+
get_trace_info_with_proxy(PROXY_URL, OPENAI_TRACE_URL, Duration::from_secs(5)).await;
208216
println!("{:?}", result);
209-
let result = get_trace_info_with_proxy(PROXY_URL, CF_TRACE_URL).await;
217+
let result =
218+
get_trace_info_with_proxy(PROXY_URL, CF_TRACE_URL, Duration::from_secs(5)).await;
210219
println!("{:?}", result);
211-
let result = get_trace_info_with_proxy(PROXY_URL, CF_CN_TRACE_URL).await;
220+
let result =
221+
get_trace_info_with_proxy(PROXY_URL, CF_CN_TRACE_URL, Duration::from_secs(5)).await;
212222
println!("{:?}", result);
213223
}
214224

215225
#[tokio::test]
216226
#[ignore]
217227
async fn test_get_ip_from_ipip() {
218-
let result = get_ip_by_ipip(PROXY_URL).await;
228+
let result = get_ip_by_ipip(PROXY_URL, Duration::from_millis(2500)).await;
219229
println!("{:?}", result);
220-
let result = get_ip_by_ipify(PROXY_URL).await;
230+
let result = get_ip_by_ipify(PROXY_URL, Duration::from_millis(2500)).await;
221231
println!("{:?}", result);
222232
}
223233
}

src/clash.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ pub struct ProxyDelay {
186186
pub struct DelayTestConfig {
187187
pub url: String,
188188
pub expected: Option<u16>,
189-
pub timeout: u16,
189+
pub timeout: u64,
190190
}
191191

192192
#[derive(Debug, Serialize, Deserialize)]

src/main.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use std::collections::HashSet;
33
use std::env;
44
use std::fs;
55
use std::path::Path;
6+
use std::time::Duration;
67

78
use clap::Parser;
89
use proxrs::protocol::Proxy;
@@ -162,7 +163,7 @@ async fn run(config: Settings) {
162163
} else {
163164
info!("当前总可用节点个数:{}", &useful_proxies.len());
164165
}
165-
166+
let timeout: Duration = Duration::from_millis(config.connect_test.timeout + 2000);
166167
if config.fast_mode {
167168
SubManager::save_proxies_into_clash_file(
168169
&useful_proxies,
@@ -203,12 +204,12 @@ async fn run(config: Settings) {
203204
.set_group_proxy(TEST_PROXY_GROUP_NAME, node)
204205
.await;
205206
if ip_result.is_ok() {
206-
let ip_result = cgi_trace::get_ip(&clash_meta.proxy_url).await;
207+
let ip_result = cgi_trace::get_ip(&clash_meta.proxy_url, timeout).await;
207208
if ip_result.is_ok() {
208209
let (proxy_ip, from) = ip_result.unwrap();
209210
info!("「{}」ip: {} from: {}", node, proxy_ip, from);
210211
let mut gemini_is_ok = false;
211-
match website::gemini_is_ok(&clash_meta.proxy_url).await {
212+
match website::gemini_is_ok(&clash_meta.proxy_url, timeout).await {
212213
Ok(_) => {
213214
info!("「{}」 gemini is ok", node);
214215
gemini_is_ok = true;
@@ -219,7 +220,7 @@ async fn run(config: Settings) {
219220
}
220221

221222
let mut claude_is_ok = false;
222-
match website::claude_is_ok(&clash_meta.proxy_url).await {
223+
match website::claude_is_ok(&clash_meta.proxy_url, timeout).await {
223224
Ok(_) => {
224225
info!("「{}」 claude is ok", node);
225226
claude_is_ok = true;

src/website.rs

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,21 +9,20 @@ use reqwest::Client;
99
use reqwest::StatusCode;
1010

1111
const USER_AGENT: &str = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36";
12-
const TIMEOUT: Duration = Duration::from_secs(5);
1312

14-
fn build_client(proxy_url: &str) -> Result<Client> {
13+
fn build_client(proxy_url: &str, timeout: Duration) -> Result<Client> {
1514
Client::builder()
1615
.proxy(reqwest::Proxy::all(proxy_url).context("Failed to create proxy configuration")?)
1716
.redirect(Policy::none())
18-
.timeout(TIMEOUT)
17+
.timeout(timeout)
1918
.build()
2019
.context("Failed to build HTTP client")
2120
}
2221

2322
#[allow(dead_code)]
24-
pub async fn claude_is_ok(proxy_url: &str) -> Result<()> {
23+
pub async fn claude_is_ok(proxy_url: &str, timeout: Duration) -> Result<()> {
2524
let url = "https://claude.ai/favicon.ico";
26-
let client = build_client(proxy_url)?;
25+
let client = build_client(proxy_url, timeout)?;
2726
let resp = client
2827
.get(url)
2928
.header("User-Agent", USER_AGENT)
@@ -55,9 +54,9 @@ pub async fn claude_is_ok(proxy_url: &str) -> Result<()> {
5554
}
5655

5756
#[allow(dead_code)]
58-
pub async fn openai_is_ok(proxy_url: &str) -> Result<()> {
57+
pub async fn openai_is_ok(proxy_url: &str, timeout: Duration) -> Result<()> {
5958
let url = "https://auth.openai.com/favicon.ico";
60-
let client = build_client(proxy_url)?;
59+
let client = build_client(proxy_url, timeout)?;
6160
let resp = client
6261
.get(url)
6362
.header("User-Agent", USER_AGENT)
@@ -72,9 +71,9 @@ pub async fn openai_is_ok(proxy_url: &str) -> Result<()> {
7271
}
7372

7473
#[allow(dead_code)]
75-
pub async fn youtube_music_is_ok(proxy_url: &str) -> Result<()> {
74+
pub async fn youtube_music_is_ok(proxy_url: &str, timeout: Duration) -> Result<()> {
7675
let url = "https://music.youtube.com/generate_204";
77-
let client = build_client(proxy_url)?;
76+
let client = build_client(proxy_url, timeout)?;
7877
let resp = client
7978
.head(url)
8079
.header("User-Agent", USER_AGENT)
@@ -88,9 +87,9 @@ pub async fn youtube_music_is_ok(proxy_url: &str) -> Result<()> {
8887
Err(anyhow!("error status code: {}", status))
8988
}
9089

91-
pub async fn gemini_is_ok(proxy_url: &str) -> Result<()> {
90+
pub async fn gemini_is_ok(proxy_url: &str, timeout: Duration) -> Result<()> {
9291
let url = "https://gemini.google.com";
93-
let client = build_client(proxy_url)?;
92+
let client = build_client(proxy_url, timeout)?;
9493
let resp = client
9594
.get(url)
9695
.header("User-Agent", USER_AGENT)
@@ -127,32 +126,35 @@ pub async fn gemini_is_ok(proxy_url: &str) -> Result<()> {
127126
Err(anyhow!("error status code: {}", status))
128127
}
129128

129+
#[cfg(test)]
130130
mod test {
131+
use super::*;
132+
131133
#[tokio::test]
132134
#[ignore]
133135
async fn test_gemini_is_ok() {
134-
let result = super::gemini_is_ok("http://localhost:7890").await;
136+
let result = gemini_is_ok("http://localhost:7890", Duration::from_secs(5)).await;
135137
println!("{:?}", result);
136138
}
137139

138140
#[tokio::test]
139141
#[ignore]
140142
async fn test_youtube_music_is_ok() {
141-
let result = super::youtube_music_is_ok("http://localhost:7890").await;
143+
let result = youtube_music_is_ok("http://localhost:7890", Duration::from_secs(5)).await;
142144
println!("{:?}", result);
143145
}
144146

145147
#[tokio::test]
146148
#[ignore]
147149
async fn test_claude_is_ok() {
148-
let result = super::claude_is_ok("http://localhost:7890").await;
150+
let result = claude_is_ok("http://localhost:7890", Duration::from_secs(5)).await;
149151
println!("{:?}", result);
150152
}
151153

152154
#[tokio::test]
153155
#[ignore]
154156
async fn test_openai_is_ok() {
155-
let result = super::openai_is_ok("http://localhost:7890").await;
157+
let result = openai_is_ok("http://localhost:7890", Duration::from_secs(5)).await;
156158
println!("{:?}", result);
157159
}
158160
}

0 commit comments

Comments
 (0)