2024-05-13 19:58:26 +08:00
|
|
|
|
package proxy
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"context"
|
|
|
|
|
"fmt"
|
|
|
|
|
"log/slog"
|
|
|
|
|
"math/rand"
|
2024-12-04 19:30:22 +08:00
|
|
|
|
"os"
|
2024-05-13 19:58:26 +08:00
|
|
|
|
"time"
|
2024-12-04 19:30:22 +08:00
|
|
|
|
|
2024-12-11 13:29:43 +08:00
|
|
|
|
"gitea.timerzz.com/timerzz/proxy-detector/config"
|
|
|
|
|
"gitea.timerzz.com/timerzz/proxy-detector/pkg/getter"
|
|
|
|
|
"gitea.timerzz.com/timerzz/proxy-detector/pkg/proxy/structs"
|
2024-12-04 19:30:22 +08:00
|
|
|
|
"github.com/golang/glog"
|
2024-05-13 19:58:26 +08:00
|
|
|
|
)
|
|
|
|
|
|
2024-12-11 13:29:43 +08:00
|
|
|
|
type Pool struct {
|
2024-12-11 13:54:03 +08:00
|
|
|
|
proxies *structs.Proxies
|
2024-12-04 19:30:22 +08:00
|
|
|
|
cfg *Option
|
|
|
|
|
updated time.Time
|
2024-05-13 19:58:26 +08:00
|
|
|
|
}
|
|
|
|
|
|
2024-12-11 13:29:43 +08:00
|
|
|
|
func InitDefaultProxyPool() (*Pool, error) {
|
2024-12-04 19:30:22 +08:00
|
|
|
|
path := os.Getenv(ProxyConfigEnv)
|
|
|
|
|
if path == "" {
|
|
|
|
|
path = DefaultProxyConfigPath
|
|
|
|
|
}
|
|
|
|
|
cfg, err := LoadProxyConfig(path)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, fmt.Errorf("获取代理池配置失败:%v", err)
|
|
|
|
|
}
|
|
|
|
|
return NewProxyPool(cfg), nil
|
|
|
|
|
}
|
2024-12-11 13:29:43 +08:00
|
|
|
|
func NewProxyPool(cfg *Option) *Pool {
|
2024-12-11 13:54:03 +08:00
|
|
|
|
var p = &Pool{
|
|
|
|
|
proxies: structs.NewProxies([]structs.Proxy{}),
|
|
|
|
|
}
|
2024-12-04 19:30:22 +08:00
|
|
|
|
p.cfg = cfg
|
2024-05-13 19:58:26 +08:00
|
|
|
|
p.Update()
|
|
|
|
|
return p
|
|
|
|
|
}
|
|
|
|
|
|
2024-12-11 13:29:43 +08:00
|
|
|
|
func (p *Pool) Status() ([]structs.Proxy, time.Time) {
|
|
|
|
|
return p.proxies.Get(), p.updated
|
2024-05-13 19:58:26 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Update 更新代理池
|
2024-12-11 13:29:43 +08:00
|
|
|
|
func (p *Pool) Update() {
|
|
|
|
|
var list = make([]structs.Proxy, 0, p.proxies.Len())
|
2024-12-04 19:30:22 +08:00
|
|
|
|
var getters = make([]getter.Getter, 0, len(p.cfg.Clash)+len(p.cfg.Subscribes))
|
|
|
|
|
for _, url := range p.cfg.Subscribes {
|
2024-12-11 13:29:43 +08:00
|
|
|
|
gtr, err := getter.NewSubscribeGetter(config.CrawOption{
|
|
|
|
|
Url: url,
|
|
|
|
|
})
|
2024-05-13 19:58:26 +08:00
|
|
|
|
if err != nil {
|
|
|
|
|
slog.Warn(fmt.Sprintf("创建Subscribe Getter失败:%v", err))
|
|
|
|
|
continue
|
|
|
|
|
}
|
2024-12-04 19:30:22 +08:00
|
|
|
|
getters = append(getters, gtr)
|
2024-05-13 19:58:26 +08:00
|
|
|
|
}
|
2024-12-04 19:30:22 +08:00
|
|
|
|
for _, url := range p.cfg.Clash {
|
2024-12-11 13:29:43 +08:00
|
|
|
|
gtr, err := getter.NewClashGetter(config.CrawOption{Url: url})
|
2024-12-04 19:30:22 +08:00
|
|
|
|
if err != nil {
|
|
|
|
|
slog.Warn(fmt.Sprintf("创建Clash Getter失败:%v", err))
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
getters = append(getters, gtr)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for _, gtr := range getters {
|
2024-12-11 13:29:43 +08:00
|
|
|
|
list = append(list, gtr.Get()...)
|
2024-12-04 19:30:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
glog.Infof("代理源共 %d 个: %v", len(p.cfg.Subscribes), p.cfg.Subscribes)
|
2024-05-13 19:58:26 +08:00
|
|
|
|
glog.Infof("获取代理共 %d 个", len(list))
|
2024-12-11 13:29:43 +08:00
|
|
|
|
p.proxies.Replace(list)
|
2024-05-13 19:58:26 +08:00
|
|
|
|
p.updated = time.Now()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// CronUpdate 定时更新
|
2024-12-11 13:29:43 +08:00
|
|
|
|
func (p *Pool) CronUpdate(ctx context.Context) {
|
2024-12-04 19:32:57 +08:00
|
|
|
|
if p.cfg.Interval == 0 {
|
|
|
|
|
p.cfg.Interval = time.Minute * 30
|
2024-05-13 19:58:26 +08:00
|
|
|
|
}
|
2024-12-04 19:32:57 +08:00
|
|
|
|
ticker := time.NewTicker(p.cfg.Interval)
|
2024-05-13 19:58:26 +08:00
|
|
|
|
defer ticker.Stop()
|
|
|
|
|
for {
|
|
|
|
|
select {
|
|
|
|
|
case <-ctx.Done():
|
|
|
|
|
return
|
|
|
|
|
case <-ticker.C:
|
|
|
|
|
p.Update()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// RandomIterator 获取随机代理的迭代器
|
2024-12-11 13:29:43 +08:00
|
|
|
|
func (p *Pool) RandomIterator() func() *structs.Proxy {
|
|
|
|
|
proxies := p.proxies.Get()
|
|
|
|
|
return func() (proxy *structs.Proxy) {
|
|
|
|
|
if len(proxies) == 0 {
|
2024-05-13 19:58:26 +08:00
|
|
|
|
return nil
|
|
|
|
|
}
|
2024-12-11 13:29:43 +08:00
|
|
|
|
curIndex := rand.Intn(len(proxies))
|
|
|
|
|
return &proxies[curIndex]
|
2024-05-13 19:58:26 +08:00
|
|
|
|
}
|
|
|
|
|
}
|