This commit is contained in:
2025-01-09 17:30:56 +08:00
parent c7124bda81
commit c9b7824937
2 changed files with 62 additions and 67 deletions

View File

@@ -86,7 +86,7 @@ func createHTTPClient(proxy *url.URL) *http.Client {
return net.Dial(network, addr) return net.Dial(network, addr)
}, },
}, },
Timeout: 30 * time.Second, Timeout: global.Conf.ProxyCheck.Timeout,
} }
} }

View File

@@ -4,6 +4,7 @@ import (
"bufio" "bufio"
"fmt" "fmt"
"httppp/common" "httppp/common"
"httppp/global"
"log" "log"
"os" "os"
"regexp" "regexp"
@@ -66,11 +67,13 @@ func (p *Progress) increment() {
p.mu.Lock() p.mu.Lock()
defer p.mu.Unlock() defer p.mu.Unlock()
p.current++ p.current++
if global.Conf.Output.ShowProgress { // 根据配置决定是否显示进度
elapsed := time.Since(p.startTime) elapsed := time.Since(p.startTime)
fmt.Printf("\r进度: %d/%d (%.1f%%) 已用时间: %v", fmt.Printf("\r进度: %d/%d (%.1f%%) 已用时间: %v\n",
p.current, p.total, p.current, p.total,
float64(p.current)/float64(p.total)*100, float64(p.current)/float64(p.total)*100,
elapsed.Round(time.Second)) elapsed.Round(time.Second))
}
} }
func NewProxyChecker(config common.ProxyCheck, nodes []*common.Node, targetURL string) *ProxyChecker { func NewProxyChecker(config common.ProxyCheck, nodes []*common.Node, targetURL string) *ProxyChecker {
@@ -119,7 +122,7 @@ func (pc *ProxyChecker) Check() ([]*common.Node, []*common.Node) {
func (pc *ProxyChecker) worker(wg *sync.WaitGroup, nodes chan *common.Node, results chan<- ProxyResult) { func (pc *ProxyChecker) worker(wg *sync.WaitGroup, nodes chan *common.Node, results chan<- ProxyResult) {
defer wg.Done() defer wg.Done()
for node := range nodes { for node := range nodes {
success, message := pc.checkWithRetry(node, 3) success, message := pc.checkWithRetry(node, pc.config.MaxRetries)
results <- ProxyResult{ results <- ProxyResult{
Node: node, Node: node,
Success: success, Success: success,
@@ -130,7 +133,8 @@ func (pc *ProxyChecker) worker(wg *sync.WaitGroup, nodes chan *common.Node, resu
} }
func (pc *ProxyChecker) checkWithRetry(node *common.Node, maxRetries int) (bool, string) { func (pc *ProxyChecker) checkWithRetry(node *common.Node, maxRetries int) (bool, string) {
for i := 0; i < maxRetries; i++ { // 使用配置中的重试次数
for i := 0; i < pc.config.MaxRetries; i++ {
success, message := CheckHttpsProxy(node, pc.targetURL) success, message := CheckHttpsProxy(node, pc.targetURL)
if success { if success {
return true, message return true, message
@@ -138,12 +142,13 @@ func (pc *ProxyChecker) checkWithRetry(node *common.Node, maxRetries int) (bool,
if !strings.Contains(message, "timeout") { if !strings.Contains(message, "timeout") {
return false, message return false, message
} }
time.Sleep(time.Second) // 使用配置中的重试延迟
time.Sleep(pc.config.RetryDelay)
} }
return false, fmt.Sprintf("重试%d次后仍然失败", maxRetries) return false, fmt.Sprintf("重试%d次后仍然失败", pc.config.MaxRetries)
} }
// 添加一个新的结构体来保存节点和延迟信息 // NodeWithLatency 添加一个新的结构体来保存节点和延迟信息
type NodeWithLatency struct { type NodeWithLatency struct {
Node *common.Node Node *common.Node
Latency int64 // 延迟(毫秒) Latency int64 // 延迟(毫秒)
@@ -158,14 +163,14 @@ func (pc *ProxyChecker) processResults(results <-chan ProxyResult) ([]*common.No
// 收集结果 // 收集结果
for result := range results { for result := range results {
if result.Success { if result.Success {
// 从消息中提取延迟时间
latency := extractLatency(result.Message) latency := extractLatency(result.Message)
nodesWithLatency = append(nodesWithLatency, NodeWithLatency{ nodesWithLatency = append(nodesWithLatency, NodeWithLatency{
Node: result.Node, Node: result.Node,
Latency: latency, Latency: latency,
Message: result.Message, // 保存原始消息 Message: result.Message,
}) })
} else { } else {
if global.Conf.Output.ShowTitle { // 根据配置决定是否显示错误信息
if strings.Contains(result.Message, "标题") { if strings.Contains(result.Message, "标题") {
fmt.Printf("❌ %s:%d [%s]\n", fmt.Printf("❌ %s:%d [%s]\n",
result.Node.Addr, result.Node.Addr,
@@ -177,16 +182,19 @@ func (pc *ProxyChecker) processResults(results <-chan ProxyResult) ([]*common.No
result.Node.Port, result.Node.Port,
simplifyErrorMessage(result.Message)) simplifyErrorMessage(result.Message))
} }
}
unavailableNodes = append(unavailableNodes, result.Node) unavailableNodes = append(unavailableNodes, result.Node)
} }
} }
// 按延迟排序 if pc.config.SortByLatency {
sort.Slice(nodesWithLatency, func(i, j int) bool { sort.Slice(nodesWithLatency, func(i, j int) bool {
return nodesWithLatency[i].Latency < nodesWithLatency[j].Latency return nodesWithLatency[i].Latency < nodesWithLatency[j].Latency
}) })
}
// 输出排序后的结果 // 输出排序后的结果
if global.Conf.Output.ShowTitle {
for _, nwl := range nodesWithLatency { for _, nwl := range nodesWithLatency {
fmt.Printf("✅ %s:%d [%s]\n", fmt.Printf("✅ %s:%d [%s]\n",
nwl.Node.Addr, nwl.Node.Addr,
@@ -194,8 +202,8 @@ func (pc *ProxyChecker) processResults(results <-chan ProxyResult) ([]*common.No
extractTitleAndLatency(nwl.Message)) extractTitleAndLatency(nwl.Message))
availableNodes = append(availableNodes, nwl.Node) availableNodes = append(availableNodes, nwl.Node)
} }
fmt.Println()
fmt.Println() // 添加一个空行,使输出更清晰 }
return availableNodes, unavailableNodes return availableNodes, unavailableNodes
} }
@@ -222,21 +230,6 @@ func extractTitleAndLatency(message string) string {
return message return message
} }
func SaveResults(availableNodes []*common.Node, totalNodes int) {
fmt.Printf("\n检测完成! 总计 %d 个节点:\n", totalNodes)
fmt.Printf("✅ 可用节点: %d\n", len(availableNodes))
fmt.Printf("❌ 不可用节点: %d\n", totalNodes-len(availableNodes))
if len(availableNodes) > 0 {
filename := fmt.Sprintf("available_nodes_%s.txt", time.Now().Format("20060102_150405"))
if err := common.SaveAvailableNodes(filename, availableNodes); err != nil {
log.Printf("保存可用节点失败: %v", err)
} else {
fmt.Printf("可用节点已保存到: %s\n", filename)
}
}
}
func SaveDetailedReport(filename string, availableNodes []*common.Node, unavailableNodes []*common.Node, duration time.Duration) { func SaveDetailedReport(filename string, availableNodes []*common.Node, unavailableNodes []*common.Node, duration time.Duration) {
file, err := os.Create(filename) file, err := os.Create(filename)
if err != nil { if err != nil {
@@ -246,7 +239,13 @@ func SaveDetailedReport(filename string, availableNodes []*common.Node, unavaila
defer file.Close() defer file.Close()
w := bufio.NewWriter(file) w := bufio.NewWriter(file)
defer w.Flush()
// 写入报告内容
writeReportContent(w, availableNodes, unavailableNodes, duration)
}
func writeReportContent(w *bufio.Writer, availableNodes, unavailableNodes []*common.Node, duration time.Duration) {
// 写入报告头部 // 写入报告头部
fmt.Fprintf(w, "代理测试报告\n") fmt.Fprintf(w, "代理测试报告\n")
fmt.Fprintf(w, "测试时间: %s\n", time.Now().Format("2006-01-02 15:04:05")) fmt.Fprintf(w, "测试时间: %s\n", time.Now().Format("2006-01-02 15:04:05"))
@@ -255,23 +254,19 @@ func SaveDetailedReport(filename string, availableNodes []*common.Node, unavaila
fmt.Fprintf(w, "可用节点: %d\n", len(availableNodes)) fmt.Fprintf(w, "可用节点: %d\n", len(availableNodes))
fmt.Fprintf(w, "不可用节点: %d\n\n", len(unavailableNodes)) fmt.Fprintf(w, "不可用节点: %d\n\n", len(unavailableNodes))
// 写入可用节点 // 写入节点列表
fmt.Fprintf(w, "=== 可用节点列表 ===\n") writeNodeList(w, "可用节点列表", availableNodes)
for _, node := range availableNodes { writeNodeList(w, "不可用节点列表", unavailableNodes)
fmt.Fprintf(w, "https://%s:%s@%s:%d\n",
node.Username, node.Password, node.Addr, node.Port)
}
// 写入不可用节点
fmt.Fprintf(w, "\n=== 不可用节点列表 ===\n")
for _, node := range unavailableNodes {
fmt.Fprintf(w, "https://%s:%s@%s:%d\n",
node.Username, node.Password, node.Addr, node.Port)
}
// 写入报告时间 // 写入报告时间
fmt.Fprintf(w, "\n报告生成时间: %s\n", time.Now().Format("2006-01-02 15:04:05")) fmt.Fprintf(w, "\n报告生成时间: %s\n", time.Now().Format("2006-01-02 15:04:05"))
}
w.Flush()
//fmt.Printf("详细报告已保存到: %s\n", filename) func writeNodeList(w *bufio.Writer, title string, nodes []*common.Node) {
fmt.Fprintf(w, "=== %s ===\n", title)
for _, node := range nodes {
fmt.Fprintf(w, "https://%s:%s@%s:%d\n",
node.Username, node.Password, node.Addr, node.Port)
}
fmt.Fprintln(w)
} }