https 节点检测

This commit is contained in:
2025-01-08 14:41:07 +08:00
commit fee0c7d845
15 changed files with 512 additions and 0 deletions

124
core/check.go Normal file
View File

@@ -0,0 +1,124 @@
package core
import (
"context"
"fmt"
"httppp/common"
"httppp/global"
"io"
"net"
"net/http"
"net/url"
"time"
)
//for _, node := range global.Conf.Nodes {
//for _, port := range node.Ports {
//node.Port = port
//success, message := core.CheckHttpsProxy(&node, global.Conf.TargetURL)
//if success {
//fmt.Printf("代理 %s 端口 %d 可用.\n", node.Addr, node.Port)
//} else {
//fmt.Printf("代理 %s 端口 %d 不可用: %s\n", node.Addr, node.Port, message)
//}
//}
//}
// CheckHttpsProxy 检测代理是否可用的函数
func CheckHttpsProxy(node *common.Node, targetURL string) (bool, string) {
proxyURL, err := Node2ProxyURL(node)
if err != nil {
fmt.Printf("节点转换代理URL失败: %v\n", err)
return false, err.Error()
}
// 解析代理 URL
proxy, err := url.Parse(proxyURL)
if err != nil {
fmt.Printf("代理解析失败: %v\n", err)
return false, err.Error()
}
// 创建自定义 Transport用于调试代理信息
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)
}
conn, err := net.Dial(network, addr)
if err != nil {
fmt.Printf("网络拨号失败: %v\n", err)
}
return conn, err
},
}
// 创建 HTTP 客户端并使用自定义 Transport
client := &http.Client{
Transport: transport,
Timeout: 30 * time.Second, // 设置超时时间
}
if global.Conf.Debug {
fmt.Printf("发送请求到: %s 使用代理: %s\n", targetURL, proxyURL)
}
// 发起 GET 请求
resp, err := client.Get(targetURL)
if err != nil {
fmt.Printf("通过代理发送请求失败 %s: %v\n", proxyURL, err)
return false, err.Error()
}
defer resp.Body.Close()
if global.Conf.Debug {
// 打印响应状态
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)
}
}
if global.Conf.Debug {
// 创建一个缓冲区,用于分块读取响应体
buffer := make([]byte, 4096) // 4KB 缓冲区
fmt.Printf("分块读取响应正文:\n")
// 分块读取响应体
for {
n, err := resp.Body.Read(buffer)
if err == io.EOF {
fmt.Println("响应正文读取完毕.")
break
}
if err != nil {
fmt.Printf("响应正文读取错误: %v\n", err)
return false, err.Error()
}
// 打印每次读取的内容
fmt.Printf("%s\n", string(buffer[:n])) // 不打印内容,只检测可用性
}
}
// 检查是否发生了重定向
if resp.StatusCode == 301 || resp.StatusCode == 302 {
redirectURL := resp.Header.Get("Location")
if global.Conf.Debug {
fmt.Printf("重定向到: %s\n", redirectURL)
}
// 如果需要处理重定向,可以发起新的请求
newResp, err := client.Get(redirectURL)
if err != nil {
fmt.Printf("重定向失败: %v\n", err)
return false, err.Error()
}
defer newResp.Body.Close()
// 打印重定向后的响应状态
if global.Conf.Debug {
fmt.Printf("重定向响应状态: %s\n", newResp.Status)
}
}
return true, "代理可用"
}