测试代理是否可用
This commit is contained in:
108
common/file.go
Normal file
108
common/file.go
Normal file
@@ -0,0 +1,108 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// ReadNodesFile 读取nodes.txt文件并解析所有节点
|
||||
func ReadNodesFile(filename string) ([]*Node, error) {
|
||||
file, err := os.Open(filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
var nodes []*Node
|
||||
nodeSet := make(map[string]bool) // 用于去重
|
||||
|
||||
scanner := bufio.NewScanner(file)
|
||||
for scanner.Scan() {
|
||||
line := strings.TrimSpace(scanner.Text())
|
||||
if line == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
// 检查是否已经存在
|
||||
if _, exists := nodeSet[line]; exists {
|
||||
continue // 跳过重复的节点
|
||||
}
|
||||
|
||||
node, err := ParseNodeURL(line)
|
||||
if err != nil {
|
||||
fmt.Printf("解析节点失败: %v\n", err)
|
||||
continue // 跳过解析失败的行
|
||||
}
|
||||
|
||||
nodes = append(nodes, node)
|
||||
nodeSet[line] = true // 标记为已存在
|
||||
}
|
||||
|
||||
if err := scanner.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return nodes, nil
|
||||
}
|
||||
|
||||
// ParseNodeURL 解析代理URL字符串为Node结构
|
||||
func ParseNodeURL(urlStr string) (*Node, error) {
|
||||
u, err := url.Parse(urlStr)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("解析URL失败: %v", err)
|
||||
}
|
||||
|
||||
// 获取用户信息
|
||||
username := ""
|
||||
password := ""
|
||||
if u.User != nil {
|
||||
username = u.User.Username()
|
||||
if pass, ok := u.User.Password(); ok {
|
||||
password = pass
|
||||
}
|
||||
}
|
||||
|
||||
// 解析端口
|
||||
port := 443 // 默认端口
|
||||
if u.Port() != "" {
|
||||
port, err = strconv.Atoi(u.Port())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("解析端口失败: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
return &Node{
|
||||
Protocol: u.Scheme,
|
||||
Username: username,
|
||||
Password: password,
|
||||
Addr: u.Hostname(),
|
||||
Port: port,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// SaveAvailableNodes 保存可用的节点到文件
|
||||
func SaveAvailableNodes(filename string, nodes []*Node) error {
|
||||
file, err := os.Create(filename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
for _, node := range nodes {
|
||||
// 重新构建URL格式
|
||||
url := fmt.Sprintf("https://%s:%s@%s:%d\n",
|
||||
node.Username,
|
||||
node.Password,
|
||||
node.Addr,
|
||||
node.Port)
|
||||
if _, err := file.WriteString(url); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user