测试代理是否可用

This commit is contained in:
2025-01-09 17:19:44 +08:00
parent fee0c7d845
commit c7124bda81
13 changed files with 3499 additions and 188 deletions

View File

@@ -1,14 +1,34 @@
package common
const (
AppEnv = "dev"
EnvConfig = "config.json"
)
import "time"
type Config struct {
Debug bool `mapstructure:"debug" json:"debug" yaml:"debug"`
TargetURL string `mapstructure:"target_url" json:"target_url" yaml:"target_url"`
Nodes []Node `mapstructure:"nodes" json:"nodes" yaml:"nodes"`
Debug bool `mapstructure:"debug" yaml:"debug"`
TargetURL string `mapstructure:"target_url" yaml:"target_url"`
ProxyCheck ProxyCheck `mapstructure:"proxy_check" yaml:"proxy_check"`
Files Files `mapstructure:"files" yaml:"files"`
Output Output `mapstructure:"output" yaml:"output"`
}
type ProxyCheck struct {
Workers int `mapstructure:"workers" yaml:"workers"`
MaxRetries int `mapstructure:"max_retries" yaml:"max_retries"`
RetryDelay time.Duration `mapstructure:"retry_delay" yaml:"retry_delay"`
Timeout time.Duration `mapstructure:"timeout" yaml:"timeout"`
SortByLatency bool `mapstructure:"sort_by_latency" yaml:"sort_by_latency"`
SaveReport bool `mapstructure:"save_report" yaml:"save_report"`
}
type Files struct {
Nodes string `mapstructure:"nodes" yaml:"nodes"`
AvailableNodes string `mapstructure:"available_nodes" yaml:"available_nodes"`
Report string `mapstructure:"report" yaml:"report"`
}
type Output struct {
ShowProgress bool `mapstructure:"show_progress" yaml:"show_progress"`
ShowTitle bool `mapstructure:"show_title" yaml:"show_title"`
ShowLatency bool `mapstructure:"show_latency" yaml:"show_latency"`
}
type Node struct {
@@ -17,5 +37,4 @@ type Node struct {
Password string `mapstructure:"password" yaml:"password" json:"password"`
Addr string `mapstructure:"addr" yaml:"addr" json:"addr"`
Port int `mapstructure:"port" yaml:"port" json:"port"`
Ports []int `mapstructure:"ports" yaml:"ports" json:"ports"`
}

108
common/file.go Normal file
View 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
}

View File

@@ -1,54 +1,27 @@
package viper
import (
"flag"
"fmt"
"github.com/fsnotify/fsnotify"
"github.com/spf13/viper"
"httppp/common"
"httppp/global"
"os"
)
func InitViper(path ...string) {
var confPath string
if len(path) == 0 {
flag.StringVar(&confPath, "c", "", "choose config file.")
flag.Parse()
if confPath == "" {
if AppEnv := os.Getenv(common.AppEnv); AppEnv == "" {
confPath = common.EnvConfig
} else {
confPath = AppEnv
}
} else {
}
} else {
confPath = path[0]
}
func InitViper() {
v := viper.New()
v.SetConfigFile(confPath)
v.SetConfigType("json")
v.SetConfigFile("config.yaml")
v.SetConfigType("yaml")
err := v.ReadInConfig()
if err != nil {
fmt.Printf("[-]读取配置文件错误: %s \n", err)
os.Exit(0)
panic(fmt.Errorf("读取配置文件失败: %s", err))
}
v.WatchConfig()
v.OnConfigChange(func(e fsnotify.Event) {
if err = v.Unmarshal(&global.Conf); err != nil {
fmt.Printf("[-]重新解析配置文件失败: %s \n", err)
os.Exit(0)
}
fmt.Println("[+]重新加载配置文件完成")
})
if err = v.Unmarshal(&global.Conf); err != nil {
fmt.Printf("[-]解析配置文件失败: %s \n", err)
os.Exit(0)
config := &common.Config{}
err = v.Unmarshal(config)
if err != nil {
panic(fmt.Errorf("解析配置文件失败: %s", err))
}
fmt.Println("[+]加载配置文件完成")
//dump.P(global.AppConf)
global.Conf = config
}