Files
check-https-proxy-node/core/check.go
2025-01-08 14:41:07 +08:00

125 lines
3.2 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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, "代理可用"
}