Files
2025-01-09 17:30:56 +08:00

101 lines
2.4 KiB
Go

package core
import (
"context"
"fmt"
"httppp/common"
"httppp/global"
"io"
"net"
"net/http"
"net/url"
"regexp"
"time"
)
// CheckHttpsProxy 检测代理是否可用的函数
func CheckHttpsProxy(node *common.Node, targetURL string) (bool, string) {
proxyURL, err := Node2ProxyURL(node)
if err != nil {
return false, fmt.Sprintf("节点转换代理URL失败: %v", err)
}
proxy, err := url.Parse(proxyURL)
if err != nil {
return false, fmt.Sprintf("代理解析失败: %v", err)
}
client := createHTTPClient(proxy)
if global.Conf.Debug {
fmt.Printf("发送请求到: %s 使用代理: %s\n", targetURL, proxyURL)
}
// 记录请求开始时间
startTime := time.Now()
resp, err := client.Get(targetURL)
if err != nil {
return false, fmt.Sprintf("通过代理发送请求失败 %s: %v", proxyURL, err)
}
defer resp.Body.Close()
// 计算延迟(转换为毫秒)
latencyMs := time.Since(startTime).Milliseconds()
// 读取响应体
body, err := io.ReadAll(resp.Body)
if err != nil {
return false, fmt.Sprintf("读取响应失败: %v", err)
}
// 检查网页标题
title := extractTitle(string(body))
if title == "" {
return false, "未找到网页标题"
}
if global.Conf.Debug {
printResponseDetails(resp)
fmt.Printf("网页标题: %s\n", title)
}
return true, fmt.Sprintf("标题: %s, 延迟: %dms", title, latencyMs)
}
// extractTitle 从HTML内容中提取标题
func extractTitle(html string) string {
// 匹配 <title> 标签内容,支持多行匹配
titleRegex := regexp.MustCompile(`(?i)<title.*?>(.*?)</title>`)
matches := titleRegex.FindStringSubmatch(html)
if len(matches) > 1 {
return matches[1]
}
return ""
}
// createHTTPClient 创建一个带有代理设置的 HTTP 客户端
func createHTTPClient(proxy *url.URL) *http.Client {
return &http.Client{
Transport: &http.Transport{
Proxy: http.ProxyURL(proxy),
DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
if global.Conf.Debug {
fmt.Printf("网络拨号: %s, 地址: %s\n", network, addr)
}
return net.Dial(network, addr)
},
},
Timeout: global.Conf.ProxyCheck.Timeout,
}
}
// printResponseDetails 打印响应的详细信息
func printResponseDetails(resp *http.Response) {
fmt.Printf("Response 状态码: %s\n", resp.Status)
fmt.Printf("Response 响应头: \n")
for key, value := range resp.Header {
fmt.Printf("\t%s: %s\n", key, value)
}
}