mirror of
https://github.com/isboyjc/GoProxy.git
synced 2026-05-06 20:02:54 +08:00
feat: ✨ init
This commit is contained in:
121
test/README.md
Normal file
121
test/README.md
Normal file
@@ -0,0 +1,121 @@
|
||||
# GoProxy 测试脚本
|
||||
|
||||
本目录包含用于测试 GoProxy 代理服务的脚本。所有脚本都采用**持续运行模式**(类似 `ping` 命令),按 `Ctrl+C` 停止并显示统计。
|
||||
|
||||
## 📝 脚本列表
|
||||
|
||||
| 脚本 | 语言 | 依赖 | 运行模式 | 推荐度 |
|
||||
|------|------|------|----------|--------|
|
||||
| `test_proxy.sh` | Bash | curl + Python3 | 持续运行 | ⭐⭐⭐ |
|
||||
| `test_proxy.go` | Go | `golang.org/x/net/proxy` | 持续运行 | ⭐⭐ |
|
||||
| `test_proxy.py` | Python | `requests`, `pysocks` | 持续运行 | ⭐⭐ |
|
||||
|
||||
## 🚀 快速使用
|
||||
|
||||
### Bash 脚本(推荐)
|
||||
|
||||
```bash
|
||||
# 从项目根目录运行(持续测试 HTTP)
|
||||
./test/test_proxy.sh
|
||||
|
||||
# 测试 HTTP 协议
|
||||
./test/test_proxy.sh http
|
||||
|
||||
# 测试 SOCKS5 协议
|
||||
./test/test_proxy.sh socks5
|
||||
|
||||
# 按 Ctrl+C 停止并查看统计
|
||||
```
|
||||
|
||||
### Go 脚本
|
||||
|
||||
```bash
|
||||
# 安装依赖
|
||||
go get golang.org/x/net/proxy
|
||||
|
||||
# 运行测试
|
||||
go run test/test_proxy.go
|
||||
|
||||
# 或编译后运行
|
||||
cd test
|
||||
go build -o test_proxy test_proxy.go
|
||||
./test_proxy
|
||||
```
|
||||
|
||||
### Python 脚本
|
||||
|
||||
```bash
|
||||
# 安装依赖
|
||||
pip install requests pysocks
|
||||
|
||||
# 运行测试
|
||||
python test/test_proxy.py
|
||||
```
|
||||
|
||||
## 📊 测试内容
|
||||
|
||||
所有脚本都会:
|
||||
1. 通过指定端口代理发送请求(默认 `127.0.0.1:7777`)
|
||||
2. 访问 `http://ip-api.com/json` 获取出口 IP 和国家信息
|
||||
3. **持续发送请求**,间隔 1 秒(类似 `ping` 命令)
|
||||
4. 实时显示国旗 emoji、出口 IP 和延迟
|
||||
5. 按 `Ctrl+C` 停止并显示统计摘要
|
||||
|
||||
## 📖 详细文档
|
||||
|
||||
完整的测试指南、故障排查、高级用法,请查看:
|
||||
|
||||
👉 [TEST_GUIDE.md](./TEST_GUIDE.md)
|
||||
|
||||
## 🔀 测试不同端口策略
|
||||
|
||||
```bash
|
||||
# 对比两个端口的行为差异:
|
||||
|
||||
# 随机轮换模式 - IP 高度分散
|
||||
./test/test_proxy.sh 7777
|
||||
|
||||
# 最低延迟模式 - 固定使用最快代理
|
||||
./test/test_proxy.sh 7776
|
||||
```
|
||||
|
||||
**观察要点**:
|
||||
- **7777 端口**:每次请求的出口 IP 应该不同(证明在轮换)
|
||||
- **7776 端口**:连续多次请求的出口 IP 基本相同(证明固定使用最优代理)
|
||||
|
||||
## 🔍 预期输出
|
||||
|
||||
```
|
||||
PROXY 127.0.0.1:7777 (http://ip-api.com/json/?fields=countryCode,query): continuous mode
|
||||
|
||||
proxy from 🇺🇸 203.0.113.45: seq=1 time=1234ms
|
||||
proxy from 🇩🇪 198.51.100.78: seq=2 time=987ms
|
||||
proxy from 🇬🇧 192.0.2.123: seq=3 time=1567ms
|
||||
proxy #4: request failed (timeout)
|
||||
proxy from 🇯🇵 198.51.100.12: seq=5 time=890ms
|
||||
proxy from 🇫🇷 192.0.2.234: seq=6 time=1456ms
|
||||
...
|
||||
(持续运行,按 Ctrl+C 停止)
|
||||
|
||||
^C
|
||||
---
|
||||
50 requests transmitted, 47 received, 3 failed, 6.0% packet loss
|
||||
```
|
||||
|
||||
**输出风格**:
|
||||
- 简洁清晰,类似 `ping` 命令
|
||||
- 一行一个结果
|
||||
- 显示国旗 emoji、出口 IP、序号、延迟
|
||||
- 统计信息简洁明了
|
||||
|
||||
**观察要点**:
|
||||
- 每次请求的出口 IP 应该不同(证明代理轮换)
|
||||
- 延迟应该在合理范围(< 2000ms)
|
||||
- 丢包率应该 < 10%
|
||||
- 可以长时间运行观察稳定性
|
||||
|
||||
## 📝 注意事项
|
||||
|
||||
1. 确保 GoProxy 服务已启动:`./goproxy`
|
||||
2. 首次启动需等待代理池就绪(约 30-60 秒)
|
||||
3. 可配合 WebUI (http://localhost:7778) 查看实时状态
|
||||
245
test/TEST_GUIDE.md
Normal file
245
test/TEST_GUIDE.md
Normal file
@@ -0,0 +1,245 @@
|
||||
# GoProxy 测试指南
|
||||
|
||||
本项目提供了三种测试脚本,用于验证代理服务的功能和性能。所有脚本都采用**持续运行模式**(类似 `ping` 命令),按 `Ctrl+C` 停止并显示统计信息。
|
||||
|
||||
## 📋 测试脚本说明
|
||||
|
||||
所有测试脚本位于 `test/` 目录下。
|
||||
|
||||
### 1. Bash 脚本(推荐)- `test_proxy.sh`
|
||||
|
||||
最简单直接,使用 `curl` 命令持续测试代理服务。
|
||||
|
||||
**使用方法:**
|
||||
|
||||
```bash
|
||||
# 测试随机轮换模式(默认 7777 端口)
|
||||
./test/test_proxy.sh
|
||||
|
||||
# 测试最低延迟模式(7776 端口)
|
||||
./test/test_proxy.sh 7776
|
||||
|
||||
# 自定义端口
|
||||
./test/test_proxy.sh 8080
|
||||
```
|
||||
|
||||
**特点:**
|
||||
- 无需安装依赖(仅需 curl 和 Python3)
|
||||
- 兼容 macOS 和 Linux
|
||||
- 持续运行,按 Ctrl+C 停止
|
||||
- 显示国旗 emoji 和出口 IP
|
||||
|
||||
---
|
||||
|
||||
### 2. Go 脚本 - `test_proxy.go`
|
||||
|
||||
使用 Go 语言编写,与项目本身技术栈一致。
|
||||
|
||||
**使用方法:**
|
||||
|
||||
```bash
|
||||
# 测试随机轮换模式(默认 7777 端口)
|
||||
go run test/test_proxy.go
|
||||
|
||||
# 测试最低延迟模式(7776 端口)
|
||||
go run test/test_proxy.go 7776
|
||||
|
||||
# 自定义端口
|
||||
go run test/test_proxy.go 8080
|
||||
|
||||
# 或编译后运行
|
||||
cd test && go build -o test_proxy test_proxy.go
|
||||
./test_proxy 7776
|
||||
```
|
||||
|
||||
**特点:**
|
||||
- 与项目技术栈统一
|
||||
- 可编译为独立二进制
|
||||
- 显示国旗 emoji 和出口 IP
|
||||
- 持续运行,按 Ctrl+C 停止
|
||||
- 彩色输出
|
||||
|
||||
---
|
||||
|
||||
### 3. Python 脚本 - `test_proxy.py`
|
||||
|
||||
使用 Python 编写,语法简洁易读。
|
||||
|
||||
**使用方法:**
|
||||
|
||||
```bash
|
||||
# 安装依赖
|
||||
pip install requests
|
||||
|
||||
# 测试随机轮换模式(默认 7777 端口)
|
||||
python test/test_proxy.py
|
||||
|
||||
# 测试最低延迟模式(7776 端口)
|
||||
python test/test_proxy.py 7776
|
||||
|
||||
# 自定义端口
|
||||
python test/test_proxy.py 8080
|
||||
```
|
||||
|
||||
**特点:**
|
||||
- Python 生态丰富
|
||||
- 易于扩展和修改
|
||||
- 持续运行,按 Ctrl+C 停止
|
||||
- 显示国旗 emoji 和出口 IP
|
||||
|
||||
---
|
||||
|
||||
## 🎯 测试输出示例
|
||||
|
||||
```
|
||||
PROXY 127.0.0.1:7777 (http://ip-api.com/json/?fields=countryCode,query): continuous mode
|
||||
|
||||
proxy from 🇺🇸 203.0.113.45: seq=1 time=1234ms
|
||||
proxy from 🇩🇪 198.51.100.78: seq=2 time=987ms
|
||||
proxy from 🇬🇧 192.0.2.123: seq=3 time=1567ms
|
||||
proxy from 🇺🇸 203.0.113.45: seq=4 time=1123ms
|
||||
proxy #5: request failed (timeout)
|
||||
proxy from 🇯🇵 198.51.100.12: seq=6 time=890ms
|
||||
proxy from 🇫🇷 192.0.2.234: seq=7 time=1456ms
|
||||
proxy from 🇨🇳 68.71.249.153: seq=8 time=1102ms
|
||||
...
|
||||
^C
|
||||
---
|
||||
50 requests transmitted, 47 received, 3 failed, 6.0% packet loss
|
||||
```
|
||||
|
||||
**特点:**
|
||||
- ✅ 简洁输出,类似 `ping` 命令
|
||||
- ✅ 一行一个结果,清晰易读
|
||||
- ✅ 显示国旗 emoji、出口 IP 和延迟
|
||||
- ✅ 按 Ctrl+C 停止并显示统计摘要
|
||||
- ✅ 显示丢包率(失败率)
|
||||
|
||||
## 🔍 观察要点
|
||||
|
||||
### 1. 出口 IP 变化
|
||||
- 每次请求的出口 IP **应该不同**,证明代理池在轮换
|
||||
- 如果连续多次是同一个 IP,说明池子中可用代理较少
|
||||
- 持续运行可以观察到代理的循环使用模式
|
||||
|
||||
### 2. 延迟表现
|
||||
- 延迟应该在合理范围内(通常 < 2000ms)
|
||||
- 如果延迟过高或超时,说明代理质量下降
|
||||
- 观察延迟趋势:是否稳定在某个范围
|
||||
|
||||
### 3. 成功率(动态显示)
|
||||
- 正常情况下成功率应该 > 90%
|
||||
- 持续运行时成功率会动态更新
|
||||
- 如果成功率持续下降,需要检查:
|
||||
- 代理池是否有足够的健康代理
|
||||
- 网络连接是否正常
|
||||
- 代理源质量是否下降
|
||||
|
||||
### 4. 协议对比
|
||||
- HTTP 代理:速度通常较快,兼容性好
|
||||
- SOCKS5 代理:更底层,可传输各种协议数据
|
||||
|
||||
### 5. 持续测试优势
|
||||
- 可以长时间运行,观察代理池的稳定性
|
||||
- 实时监控成功率变化
|
||||
- 按 Ctrl+C 随时查看统计结果
|
||||
- 类似 `ping` 命令的使用体验
|
||||
|
||||
## 📊 配合 WebUI 监控
|
||||
|
||||
测试时可以同时打开 WebUI (http://localhost:7778):
|
||||
|
||||
1. **代理列表**:查看正在使用的代理
|
||||
2. **使用统计**:观察 `使用次数` 列的变化
|
||||
3. **系统日志**:实时查看代理请求日志
|
||||
4. **质量分布**:查看当前池子的质量分布
|
||||
|
||||
## ⚙️ 自定义配置
|
||||
|
||||
修改脚本顶部的配置变量:
|
||||
|
||||
```bash
|
||||
PROXY_HOST="127.0.0.1" # 代理服务地址
|
||||
PROXY_PORT="7777" # 代理服务端口
|
||||
TEST_URL="http://httpbin.org/ip" # 测试目标 URL
|
||||
DELAY=1 # 每次请求间隔(秒)
|
||||
```
|
||||
|
||||
**注意**:所有脚本现在都是持续运行模式,按 `Ctrl+C` 停止,无需配置请求次数。
|
||||
|
||||
## 🛠️ 高级测试
|
||||
|
||||
### 测试特定网站
|
||||
|
||||
```bash
|
||||
# 测试访问 Google
|
||||
curl -x "http://127.0.0.1:7777" https://www.google.com
|
||||
|
||||
# 测试访问 GitHub API
|
||||
curl -x "http://127.0.0.1:7777" https://api.github.com/users/github
|
||||
|
||||
# 测试中国网站
|
||||
curl -x "http://127.0.0.1:7777" https://www.baidu.com
|
||||
```
|
||||
|
||||
### 并发压力测试
|
||||
|
||||
```bash
|
||||
# 使用 ab (Apache Bench) 进行压力测试
|
||||
ab -n 100 -c 10 -X 127.0.0.1:7777 http://httpbin.org/ip
|
||||
|
||||
# 使用 wrk 进行压力测试
|
||||
wrk -t4 -c100 -d30s --proxy http://127.0.0.1:7777 http://httpbin.org/ip
|
||||
```
|
||||
|
||||
### 查看当前使用的代理
|
||||
|
||||
```bash
|
||||
# 通过 httpbin 获取当前出口 IP
|
||||
curl -x "http://127.0.0.1:7777" http://httpbin.org/ip
|
||||
|
||||
# 获取更详细的信息(包括 headers)
|
||||
curl -x "http://127.0.0.1:7777" http://httpbin.org/anything
|
||||
```
|
||||
|
||||
## 📝 注意事项
|
||||
|
||||
1. **启动代理服务**:测试前确保 `goproxy` 已启动
|
||||
```bash
|
||||
./goproxy
|
||||
```
|
||||
|
||||
2. **等待代理池就绪**:首次启动需要等待代理抓取和验证(约 30-60 秒)
|
||||
|
||||
3. **网络环境**:确保服务器可以访问外部代理源和测试 URL
|
||||
|
||||
4. **防火墙**:确保 7777 端口没有被防火墙阻止
|
||||
|
||||
5. **代理协议**:不同协议可能表现不同,建议都测试一遍
|
||||
|
||||
## 🐛 故障排查
|
||||
|
||||
### 全部请求失败
|
||||
- 检查 `goproxy` 服务是否正在运行
|
||||
- 检查代理池是否有可用代理(访问 WebUI 查看)
|
||||
- 检查端口 7777 是否被占用
|
||||
|
||||
### 成功率低
|
||||
- 查看 WebUI 日志,确认代理质量
|
||||
- 可能需要等待池子优化(系统会自动轮换低质量代理)
|
||||
- 检查网络连接是否稳定
|
||||
|
||||
### SOCKS5 测试失败
|
||||
- 确认 curl 版本支持 SOCKS5(`curl --version`)
|
||||
- Python 脚本需要安装 `pysocks`:`pip install pysocks`
|
||||
- Go 脚本需要安装依赖:`go get golang.org/x/net/proxy`
|
||||
|
||||
### Bash 脚本时间戳错误(macOS)
|
||||
如果看到 `value too great for base` 错误:
|
||||
- 脚本已自动使用 Python3 获取毫秒时间戳(macOS 兼容)
|
||||
- 确保系统已安装 Python3(macOS 自带)
|
||||
- 或安装 GNU coreutils:`brew install coreutils`
|
||||
|
||||
---
|
||||
|
||||
**Happy Testing! 🚀**
|
||||
122
test/test_proxy.go
Normal file
122
test/test_proxy.go
Normal file
@@ -0,0 +1,122 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"os/signal"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
proxyHost = "127.0.0.1"
|
||||
testURL = "http://ip-api.com/json/?fields=countryCode,query"
|
||||
delaySeconds = 1
|
||||
)
|
||||
|
||||
var proxyPort = "7777"
|
||||
|
||||
type IPResponse struct {
|
||||
Query string `json:"query"`
|
||||
CountryCode string `json:"countryCode"`
|
||||
}
|
||||
|
||||
var (
|
||||
totalCount = 0
|
||||
successCount = 0
|
||||
)
|
||||
|
||||
// 国家代码转 emoji 旗帜
|
||||
func countryToEmoji(countryCode string) string {
|
||||
if countryCode == "" {
|
||||
return "🌐"
|
||||
}
|
||||
|
||||
countryCode = strings.ToUpper(countryCode)
|
||||
if len(countryCode) != 2 {
|
||||
return "🌐"
|
||||
}
|
||||
|
||||
// 将国家代码转换为 emoji
|
||||
// A=127462, 所以 'US' -> 🇺🇸
|
||||
first := rune(countryCode[0]) - 'A' + 127462
|
||||
second := rune(countryCode[1]) - 'A' + 127462
|
||||
|
||||
return string([]rune{first, second})
|
||||
}
|
||||
|
||||
func printStats() {
|
||||
fmt.Println()
|
||||
fmt.Println("---")
|
||||
lossCount := totalCount - successCount
|
||||
lossRate := 0.0
|
||||
if totalCount > 0 {
|
||||
lossRate = float64(lossCount) / float64(totalCount) * 100
|
||||
}
|
||||
fmt.Printf("%d requests transmitted, %d received, %d failed, %.1f%% packet loss\n",
|
||||
totalCount, successCount, lossCount, lossRate)
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
func testHTTPProxyContinuous() {
|
||||
fmt.Printf("PROXY %s:%s (%s): continuous mode\n", proxyHost, proxyPort, testURL)
|
||||
fmt.Println()
|
||||
|
||||
proxyURL, _ := url.Parse(fmt.Sprintf("http://%s:%s", proxyHost, proxyPort))
|
||||
client := &http.Client{
|
||||
Transport: &http.Transport{
|
||||
Proxy: http.ProxyURL(proxyURL),
|
||||
},
|
||||
Timeout: 15 * time.Second,
|
||||
}
|
||||
|
||||
// 捕获 Ctrl+C 信号
|
||||
sigChan := make(chan os.Signal, 1)
|
||||
signal.Notify(sigChan, os.Interrupt, syscall.SIGTERM)
|
||||
go func() {
|
||||
<-sigChan
|
||||
printStats()
|
||||
}()
|
||||
|
||||
for {
|
||||
totalCount++
|
||||
|
||||
start := time.Now()
|
||||
resp, err := client.Get(testURL)
|
||||
elapsed := time.Since(start).Milliseconds()
|
||||
|
||||
if err != nil {
|
||||
fmt.Printf("proxy #%d: request failed (%v)\n", totalCount, err)
|
||||
time.Sleep(delaySeconds * time.Second)
|
||||
continue
|
||||
}
|
||||
|
||||
body, _ := io.ReadAll(resp.Body)
|
||||
resp.Body.Close()
|
||||
|
||||
var ipResp IPResponse
|
||||
if err := json.Unmarshal(body, &ipResp); err == nil {
|
||||
flag := countryToEmoji(ipResp.CountryCode)
|
||||
fmt.Printf("proxy from %s %s: seq=%d time=%dms\n", flag, ipResp.Query, totalCount, elapsed)
|
||||
successCount++
|
||||
} else {
|
||||
fmt.Printf("proxy #%d: parse error\n", totalCount)
|
||||
}
|
||||
|
||||
time.Sleep(delaySeconds * time.Second)
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
// 支持指定端口号
|
||||
if len(os.Args) > 1 {
|
||||
proxyPort = os.Args[1]
|
||||
}
|
||||
|
||||
testHTTPProxyContinuous()
|
||||
}
|
||||
97
test/test_proxy.py
Normal file
97
test/test_proxy.py
Normal file
@@ -0,0 +1,97 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
GoProxy 持续测试脚本 - 类似 ping 命令的简洁输出
|
||||
按 Ctrl+C 停止测试
|
||||
"""
|
||||
|
||||
import requests
|
||||
import time
|
||||
import sys
|
||||
import signal
|
||||
from requests.exceptions import RequestException
|
||||
|
||||
# 配置
|
||||
PROXY_HOST = "127.0.0.1"
|
||||
PROXY_PORT = int(sys.argv[1]) if len(sys.argv) > 1 and sys.argv[1].isdigit() else 7777
|
||||
TEST_URL = "http://ip-api.com/json/?fields=countryCode,query"
|
||||
DELAY_SECONDS = 1
|
||||
|
||||
# 统计变量
|
||||
total_count = 0
|
||||
success_count = 0
|
||||
|
||||
|
||||
def country_to_emoji(country_code):
|
||||
"""将国家代码转换为 emoji 旗帜"""
|
||||
if not country_code or country_code == "null":
|
||||
return "🌐"
|
||||
|
||||
# 将国家代码转换为区域指示符号
|
||||
# A=127462, 所以 'US' -> 🇺🇸
|
||||
try:
|
||||
first = ord(country_code[0].upper()) - ord('A') + 127462
|
||||
second = ord(country_code[1].upper()) - ord('A') + 127462
|
||||
return chr(first) + chr(second)
|
||||
except:
|
||||
return "🌐"
|
||||
|
||||
|
||||
def signal_handler(sig, frame):
|
||||
"""处理 Ctrl+C 信号"""
|
||||
print()
|
||||
print("---")
|
||||
loss_count = total_count - success_count
|
||||
loss_rate = 0.0
|
||||
if total_count > 0:
|
||||
loss_rate = loss_count / total_count * 100
|
||||
print(f"{total_count} requests transmitted, {success_count} received, {loss_count} failed, {loss_rate:.1f}% packet loss")
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
def test_http_proxy_continuous():
|
||||
"""持续测试 HTTP 代理"""
|
||||
global total_count, success_count
|
||||
|
||||
proxy_url = f"http://{PROXY_HOST}:{PROXY_PORT}"
|
||||
proxies = {
|
||||
"http": proxy_url,
|
||||
"https": proxy_url,
|
||||
}
|
||||
|
||||
print(f"PROXY {PROXY_HOST}:{PROXY_PORT} ({TEST_URL}): continuous mode")
|
||||
print()
|
||||
|
||||
# 注册信号处理
|
||||
signal.signal(signal.SIGINT, signal_handler)
|
||||
|
||||
while True:
|
||||
total_count += 1
|
||||
|
||||
try:
|
||||
start_time = time.time()
|
||||
response = requests.get(
|
||||
TEST_URL,
|
||||
proxies=proxies,
|
||||
timeout=15,
|
||||
)
|
||||
elapsed = int((time.time() - start_time) * 1000)
|
||||
|
||||
if response.status_code == 200:
|
||||
data = response.json()
|
||||
exit_ip = data.get("query", "Unknown")
|
||||
country_code = data.get("countryCode", "")
|
||||
flag = country_to_emoji(country_code)
|
||||
print(f"proxy from {flag} {exit_ip}: seq={total_count} time={elapsed}ms")
|
||||
success_count += 1
|
||||
else:
|
||||
print(f"proxy #{total_count}: request failed (HTTP {response.status_code})")
|
||||
|
||||
except RequestException as e:
|
||||
error_msg = str(e).split(':')[0]
|
||||
print(f"proxy #{total_count}: {error_msg}")
|
||||
|
||||
time.sleep(DELAY_SECONDS)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
test_http_proxy_continuous()
|
||||
95
test/test_proxy.sh
Executable file
95
test/test_proxy.sh
Executable file
@@ -0,0 +1,95 @@
|
||||
#!/bin/bash
|
||||
|
||||
# GoProxy 持续测试脚本 - 类似 ping 命令的简洁输出
|
||||
# 按 Ctrl+C 停止测试
|
||||
# 用法: ./test_proxy.sh [端口号,默认7777]
|
||||
|
||||
PROXY_HOST="127.0.0.1"
|
||||
PROXY_PORT="${1:-7777}"
|
||||
TEST_URL="http://ip-api.com/json/?fields=countryCode,query"
|
||||
DELAY=1
|
||||
|
||||
# 统计变量
|
||||
total=0
|
||||
success=0
|
||||
fail=0
|
||||
|
||||
# 获取毫秒时间戳(兼容 macOS 和 Linux)
|
||||
get_ms_time() {
|
||||
python3 -c 'import time; print(int(time.time() * 1000))'
|
||||
}
|
||||
|
||||
# 国家代码转 emoji 旗帜
|
||||
country_to_emoji() {
|
||||
local country_code="$1"
|
||||
if [ -z "$country_code" ] || [ "$country_code" = "null" ]; then
|
||||
echo "🌐"
|
||||
return
|
||||
fi
|
||||
|
||||
# 将国家代码转换为 emoji(使用 Unicode 区域指示符)
|
||||
# 每个字母转换为对应的区域指示符号字符
|
||||
local first="${country_code:0:1}"
|
||||
local second="${country_code:1:1}"
|
||||
|
||||
# A=127462, 所以 A->🇦 就是 127462,B->🇧 就是 127463
|
||||
# 使用 printf 和 Unicode 编码
|
||||
python3 -c "print(chr(127462 + ord('$first') - ord('A')) + chr(127462 + ord('$second') - ord('A')))"
|
||||
}
|
||||
|
||||
# 捕获 Ctrl+C 信号
|
||||
trap ctrl_c INT
|
||||
function ctrl_c() {
|
||||
echo ""
|
||||
echo "---"
|
||||
loss_rate=$(awk "BEGIN {printf \"%.1f\", ($total - $success)/$total*100}")
|
||||
echo "$total requests transmitted, $success received, $((total - success)) failed, ${loss_rate}% packet loss"
|
||||
exit 0
|
||||
}
|
||||
|
||||
# 测试 HTTP 代理
|
||||
test_http_proxy() {
|
||||
echo "PROXY $PROXY_HOST:$PROXY_PORT ($TEST_URL): continuous mode"
|
||||
echo ""
|
||||
|
||||
while true; do
|
||||
total=$((total + 1))
|
||||
|
||||
# 使用 HTTP 代理发送请求
|
||||
start_time=$(get_ms_time)
|
||||
response=$(curl -x "http://${PROXY_HOST}:${PROXY_PORT}" \
|
||||
-s \
|
||||
-w "\n%{http_code}" \
|
||||
--connect-timeout 10 \
|
||||
--max-time 15 \
|
||||
"${TEST_URL}" 2>&1)
|
||||
end_time=$(get_ms_time)
|
||||
elapsed=$((end_time - start_time))
|
||||
|
||||
# 分离响应体和状态码
|
||||
http_code=$(echo "$response" | tail -n 1)
|
||||
body=$(echo "$response" | sed '$d')
|
||||
|
||||
if [ "$http_code" = "200" ]; then
|
||||
exit_ip=$(echo "$body" | grep -o '"query":"[^"]*"' | cut -d'"' -f4)
|
||||
country_code=$(echo "$body" | grep -o '"countryCode":"[^"]*"' | cut -d'"' -f4)
|
||||
|
||||
if [ -n "$exit_ip" ]; then
|
||||
flag=$(country_to_emoji "$country_code")
|
||||
echo "proxy from $flag $exit_ip: seq=$total time=${elapsed}ms"
|
||||
success=$((success + 1))
|
||||
else
|
||||
echo "proxy #$total: parse error"
|
||||
fail=$((fail + 1))
|
||||
fi
|
||||
else
|
||||
echo "proxy #$total: request failed (HTTP $http_code)"
|
||||
fail=$((fail + 1))
|
||||
fi
|
||||
|
||||
sleep $DELAY
|
||||
done
|
||||
}
|
||||
|
||||
# 主函数
|
||||
test_http_proxy
|
||||
Reference in New Issue
Block a user