go-proxy-pool

一个面向 Decodo residential proxy 的 Go pkg,负责:
- 建模 Decodo
user:pass backconnect 配置
- 解析通用
ip:port:username:password 简单代理格式
- 生成可直接用于
httpcloak、net/http 和 SOCKS5 的代理 URL
- 管理按业务 key 复用的 sticky session
- 支持 100+ 国家、8 个城市、50 个美国州的端点预设
安装
go env -w GOPRIVATE=github.com/VectorSprint/*
go get github.com/VectorSprint/go-proxy-pool@latest
导入路径
import "github.com/VectorSprint/go-proxy-pool/pkg/decodo"
import "github.com/VectorSprint/go-proxy-pool/pkg/simpleproxy"
import httpcloakadapter "github.com/VectorSprint/go-proxy-pool/pkg/decodo/adapter/httpcloak"
import nethttpadapter "github.com/VectorSprint/go-proxy-pool/pkg/decodo/adapter/nethttp"
快速开始
// NewAuth 会尽早校验原始 proxy user,非法字符会直接返回 error,
// 避免请求真正打到代理时才出现 407。
auth, err := decodo.NewAuth("my-proxy-user", "my-proxy-password")
if err != nil {
return err
}
cfg := decodo.Config{
Auth: auth,
Targeting: decodo.Targeting{
Country: "us",
City: "new_york",
},
Session: decodo.Session{
Type: decodo.SessionTypeSticky,
ID: "account-1",
DurationMinutes: 30,
},
}
proxyURL, err := cfg.ProxyURL()
if err != nil {
return err
}
生成结果:
http://user-my-proxy-user-country-us-city-new_york-session-account-1-sessionduration-30:my-proxy-password@gate.decodo.com:7000
简单代理格式
如果代理供应商给的是 ip:port:username:password 这种简单格式,可以使用 pkg/simpleproxy 解析并生成标准 HTTP proxy URL:
proxy, err := simpleproxy.Parse("40.27.182.2:3128:tgkoroke:tgkorfedwoksokfed")
if err != nil {
return err
}
proxyURL := proxy.URL()
// http://tgkoroke:tgkorfedwoksokfed@40.27.182.2:3128
如果同一段代理只需要替换 IPv4 最后一位,也可以由调用方传入范围动态生成,不需要把代理信息硬编码在 pkg 里:
base, err := simpleproxy.Parse("40.27.182.2:3128:tgkoroke:tgkorfedwoksokfed")
if err != nil {
return err
}
proxies, err := simpleproxy.IPv4Range(base, 1, 251)
if err != nil {
return err
}
HTTP/HTTPS 代理接入
httpcloak
proxy, err := httpcloakadapter.ProxyString(cfg)
if err != nil {
return err
}
client := client.NewClient("chrome-latest")
client.SetProxy(proxy)
net/http
proxyFunc, err := nethttpadapter.ProxyFunc(cfg)
if err != nil {
return err
}
transport := &http.Transport{
Proxy: proxyFunc,
}
httpClient := &http.Client{
Transport: transport,
}
SOCKS5 代理接入
SOCKS5 只能 使用 gate.decodo.com:7000,地理位置通过 username 参数指定。
不要把 country / city / state endpoint(例如 us.decodo.com、city.decodo.com)直接用于 SOCKS5;这些 endpoint 只适用于 HTTP/HTTPS 代理。
如果你需要 sticky SOCKS5,请显式设置 Session.ID。仅设置 Session.DurationMinutes 不会让 SOCKS5 固定到同一个会话。
httpcloak + SOCKS5
proxy, err := httpcloakadapter.ProxyStringSOCKS5(cfg)
if err != nil {
return err
}
// socks5h://user-my-proxy-user-country-us-city-new_york-session-account-1-sessionduration-30:my-proxy-password@gate.decodo.com:7000
net/http + SOCKS5
net/http 原生不支持 SOCKS5,需要配合第三方 dialer 使用:
proxyURL, err := nethttpadapter.ProxyURLSOCKS5(cfg)
if err != nil {
return err
}
// proxyURL 可用于 golang.org/x/net/proxy
端点预设 (Endpoint Presets)
内置 100+ 国家、8 个城市、50 个美国州的端点配置,自动根据 targeting 选择正确的端点和端口。
自动应用预设
cfg := decodo.Config{
Auth: auth,
Targeting: decodo.Targeting{
Country: "us",
City: "new_york",
},
Session: decodo.Session{
Type: decodo.SessionTypeSticky,
DurationMinutes: 30,
},
}
// 自动选择 city.decodo.com:21000 和 sticky port range(HTTP/HTTPS 用)
cfg.ApplyPreset()
ApplyPreset() 主要用于 HTTP/HTTPS 场景。即使配置里已经应用了 country / city / state endpoint,ProxyStringSOCKS5 / ProxyURLSOCKS5 仍会强制改用 gate.decodo.com:7000。
支持的 targeting 级别
| 级别 |
示例 |
端点 |
| 国家 |
Country: "us" |
us.decodo.com |
| 城市 |
City: "new_york" |
city.decodo.com |
| 美国州 |
State: "us_california" |
state.decodo.com |
支持的端点详情见 Decodo 文档。
Sticky Session Pool
pool, err := decodo.NewPool(decodo.PoolOptions{
Config: decodo.Config{
Auth: auth,
Session: decodo.Session{
Type: decodo.SessionTypeSticky,
DurationMinutes: 30,
},
},
FailureThreshold: 3,
})
if err != nil {
return err
}
lease, err := pool.Get("account-1")
if err != nil {
return err
}
proxy := lease.ProxyURL
随机端口分配
启用 RandomPort 可以在 sticky port range 内随机选择端口,降低被检测风险:
pool, err := decodo.NewPool(decodo.PoolOptions{
Config: decodo.Config{
Auth: auth,
EndpointSpec: caEndpoint, // ca.decodo.com:20001-29999
Session: decodo.Session{
Type: decodo.SessionTypeSticky,
DurationMinutes: 30,
},
},
RandomPort: true,
Rand: rand.New(rand.NewSource(time.Now().UnixNano())),
FailureThreshold: 3,
})
强制换 IP
if err := pool.Rotate("account-1"); err != nil {
return err
}
失败驱动轮换
if err := pool.ReportFailure("account-1", decodo.FailureCause{
StatusCode: 429,
}); err != nil {
return err
}
username 和 password 填法
username
填 Decodo dashboard 里的原始 proxy user,不要填 user- 前缀:
my-proxy-user ✓ 正确
user-my-proxy-user ✗ 错误
NewAuth() / Auth.Validate() 会校验 username,只允许:
像空格、% 转义残留、@、控制字符、中文或其他非 ASCII 字符都会直接返回错误,避免等到代理认证阶段才暴露成 407 Proxy Authentication Required。
password
填 原始密码,不要做任何拼接。
Dedicated Endpoint
支持 Decodo dedicated endpoint 配置:
caEndpoint, err := decodo.NewEndpointSpec("ca.decodo.com", 20000, decodo.PortRange{
Start: 20001,
End: 29999,
})
if err != nil {
return err
}
cfg := decodo.Config{
Auth: auth,
EndpointSpec: caEndpoint,
}
选择规则:
- rotating session:自动使用
RotatingPort
- sticky session:自动使用
StickyPortRange.Start
- sticky pool:在范围内为不同 key 分配可用 sticky port
examples 目录
examples/nethttp-basic:标准库 net/http 接入
examples/pool-basic:sticky session pool 的获取与失败轮换
examples/httpcloak-proxy-string:为 httpcloak 生成可直接 SetProxy(...) 的字符串
examples/dedicated-endpoint:使用 Decodo dedicated endpoint
examples/random-port:随机端口分配和端点预设示例
开发检查
task test
task lint
task check
测试覆盖率
| Package |
Coverage |
pkg/decodo |
84.4% |
pkg/decodo/adapter/httpcloak |
84.0% |
pkg/decodo/adapter/nethttp |
86.4% |