Skip to content

Repository files navigation

go-proxy-pool

CI Version Go Version License godoc

一个面向 Decodo residential proxy 的 Go pkg,负责:

  • 建模 Decodo user:pass backconnect 配置
  • 解析通用 ip:port:username:password 简单代理格式
  • 生成可直接用于 httpcloaknet/httpSOCKS5 的代理 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.comcity.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%

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages