测试代理是否可用
This commit is contained in:
@@ -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
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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user