proxyhive

package module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 4, 2026 License: MIT Imports: 15 Imported by: 0

README

proxyhive

Go proxy pool manager with health checking, latency scoring, rotation strategies, geo-targeting, and sticky sessions.

Feed it a list of proxies and it handles the rest — background health checks, EWMA latency tracking, automatic backoff on failures, and smart rotation via Power-of-Two-Choices, round-robin, least-latency, or random selection.

Features

  • Multiple protocols — HTTP CONNECT, SOCKS5, SOCKS4
  • Rotation strategies — P2C (default), round-robin, random, least-latency
  • Health checking — background checks with configurable interval, EWMA latency tracking
  • Automatic backoff — exponential backoff on failures, automatic recovery
  • Geo-filtering — filter by country, city, ASN
  • Sticky sessions — pin a key to a specific proxy for a TTL
  • http.RoundTripper — drop-in transport for http.Client
  • DialContext — compatible with net.Dialer for raw connections

Install

go get github.com/divinedev111/proxyhive

Quick Start

package main

import (
    "fmt"
    "log"

    "github.com/divinedev111/proxyhive"
)

func main() {
    pool := proxyhive.New(
        proxyhive.WithStrategy(proxyhive.P2C()),
        proxyhive.WithHealthCheckURL("https://httpbin.org/ip"),
    )
    defer pool.Close()

    pool.Add("http://proxy1.example.com:8080", proxyhive.InCountry("US"))
    pool.Add("socks5://user:pass@proxy2.example.com:1080", proxyhive.InCountry("DE"))

    proxy, err := pool.Get(proxyhive.WithCountry("US"))
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("Selected: %s (%s)\n", proxy.Addr(), proxy.Protocol)
}

Usage

As an HTTP Transport
pool := proxyhive.New()
pool.Add("http://proxy1:8080")
pool.Add("http://proxy2:8080")

client := &http.Client{
    Transport: pool.RoundTripper(),
}

resp, err := client.Get("https://example.com")
With Geo-Filtering
proxy, err := pool.Get(
    proxyhive.WithCountry("US", "CA"),
    proxyhive.WithMaxLatency(500 * time.Millisecond),
)
With Sticky Sessions

Pin requests to the same proxy by key:

transport := pool.RoundTripper(
    proxyhive.WithCountry("US"),
    proxyhive.Sticky("session-abc", 10*time.Minute),
)

client := &http.Client{Transport: transport}
// All requests use the same proxy for 10 minutes
As a Dialer
dialer := pool.NewDialer(proxyhive.WithProtocol(proxyhive.SOCKS5))

conn, err := dialer.DialContext(ctx, "tcp", "example.com:443")
Pool Stats
stats := pool.Stats()
fmt.Printf("Total: %d, Alive: %d, Dead: %d\n", stats.Total, stats.Alive, stats.Dead)
fmt.Printf("Avg latency: %v\n", stats.AvgLatency)
fmt.Printf("Countries: %v\n", stats.Countries)

Configuration

pool := proxyhive.New(
    proxyhive.WithStrategy(proxyhive.LeastLatency()),   // rotation strategy
    proxyhive.WithHealthCheck(30*time.Second, 10*time.Second), // interval, timeout
    proxyhive.WithHealthCheckURL("https://httpbin.org/ip"),     // health check target
    proxyhive.WithEWMADecay(0.3),                       // latency smoothing factor
    proxyhive.WithMaxBackoff(time.Hour),                 // max backoff for dead proxies
)
Strategies
Strategy Description
P2C() Power of Two Choices — pick 2 random, use the faster one. Default.
RoundRobin() Cycle through proxies sequentially
Random() Uniform random selection
LeastLatency() Always pick the proxy with lowest EWMA latency
Proxy Options
pool.Add("http://proxy:8080",
    proxyhive.InCountry("US"),
    proxyhive.InCity("New York"),
    proxyhive.WithASNTag("AS13335"),
)

Architecture

proxyhive.go      Pool constructor
pool.go           Pool with Add/Get/Remove/Stats and filtering
proxy.go          Proxy type with EWMA latency and backoff
strategy.go       Rotation strategies (P2C, RoundRobin, Random, LeastLatency)
health.go         Background health checker
transport.go      http.RoundTripper with sticky sessions
dialer.go         net.Dialer-compatible DialContext
geo.go            Geo/protocol/latency filters
parse.go          Proxy URL parser
options.go        Configuration options
dial/
  http.go         HTTP CONNECT dialer
  socks5.go       SOCKS5 dialer
  socks4.go       SOCKS4 dialer

License

MIT

Documentation

Overview

Package proxyhive manages proxy pools with health checking, rotation strategies, latency scoring, geo-filtering, and sticky sessions.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Dialer

type Dialer struct {
	// contains filtered or unexported fields
}

Dialer wraps a Pool to provide a DialContext compatible with net.Dialer.

func (*Dialer) DialContext

func (d *Dialer) DialContext(ctx context.Context, network, addr string) (net.Conn, error)

DialContext connects to the target address through a pool proxy.

type Filter

type Filter func(*Proxy) bool

Filter narrows proxy selection by returning true for matching proxies.

func Sticky

func Sticky(key string, ttl time.Duration) Filter

Sticky returns a special filter that enables sticky sessions. The given key maps to a specific proxy for the duration of ttl.

func WithASN

func WithASN(asns ...string) Filter

WithASN returns a filter that matches proxies with any of the given ASNs.

func WithAlive

func WithAlive() Filter

WithAlive returns a filter that matches only alive proxies. Applied by default.

func WithCity

func WithCity(cities ...string) Filter

WithCity returns a filter that matches proxies in any of the given cities (case-insensitive).

func WithCountry

func WithCountry(codes ...string) Filter

WithCountry returns a filter that matches proxies in any of the given countries (ISO 3166-1 alpha-2).

func WithMaxLatency

func WithMaxLatency(d time.Duration) Filter

WithMaxLatency returns a filter that excludes proxies with EWMA latency above d.

func WithProtocol

func WithProtocol(proto Protocol) Filter

WithProtocol returns a filter that matches proxies with the given protocol.

type HealthChecker

type HealthChecker struct {
	// contains filtered or unexported fields
}

HealthChecker runs background health checks against proxies in a pool.

type Option

type Option func(*poolConfig)

Option configures a Pool.

func WithEWMADecay

func WithEWMADecay(alpha float64) Option

WithEWMADecay sets the alpha factor for EWMA latency calculation.

func WithHealthCheck

func WithHealthCheck(interval, timeout time.Duration) Option

WithHealthCheck sets the interval and timeout for background health checks.

func WithHealthCheckURL

func WithHealthCheckURL(url string) Option

WithHealthCheckURL sets the URL used for health check validation.

func WithMaxBackoff

func WithMaxBackoff(d time.Duration) Option

WithMaxBackoff sets the maximum backoff duration for failed proxies.

func WithStrategy

func WithStrategy(s Strategy) Option

WithStrategy sets the proxy rotation strategy.

type Pool

type Pool struct {
	// contains filtered or unexported fields
}

Pool manages a set of proxies with health checking and rotation.

func New

func New(opts ...Option) *Pool

New creates a new proxy pool with the given options.

func (*Pool) Add

func (p *Pool) Add(rawURL string, opts ...ProxyOption) error

Add parses and adds a single proxy to the pool.

func (*Pool) AddMany

func (p *Pool) AddMany(rawURLs []string, opts ...ProxyOption) error

AddMany parses and adds multiple proxies to the pool.

func (*Pool) Alive

func (p *Pool) Alive() []*Proxy

Alive returns all proxies currently marked as alive.

func (*Pool) Close

func (p *Pool) Close()

Close stops the background health checker and releases resources.

func (*Pool) DialContext

func (p *Pool) DialContext(ctx context.Context, network, addr string) (net.Conn, error)

DialContext connects to the target address through a pool proxy.

func (*Pool) Get

func (p *Pool) Get(filters ...Filter) (*Proxy, error)

Get selects a proxy from the pool using the configured strategy. WithAlive is always applied. Additional filters narrow the candidates.

func (*Pool) NewDialer

func (p *Pool) NewDialer(filters ...Filter) *Dialer

NewDialer creates a Dialer that routes connections through the pool.

func (*Pool) Remove

func (p *Pool) Remove(rawURL string)

Remove removes a proxy by its raw URL string.

func (*Pool) RoundTripper

func (p *Pool) RoundTripper(filters ...Filter) http.RoundTripper

RoundTripper returns an http.RoundTripper that routes requests through the pool.

func (*Pool) Stats

func (p *Pool) Stats() PoolStats

Stats returns aggregate pool statistics.

type PoolStats

type PoolStats struct {
	Total      int
	Alive      int
	Dead       int
	AvgLatency time.Duration
	Protocols  map[Protocol]int
	Countries  map[string]int
}

PoolStats contains aggregate statistics about the pool.

type Protocol

type Protocol int

Protocol represents the proxy protocol type.

const (
	HTTP Protocol = iota
	SOCKS4
	SOCKS5
)

func (Protocol) String

func (p Protocol) String() string

type Proxy

type Proxy struct {
	URL      *url.URL
	Protocol Protocol

	Country string
	City    string
	ASN     string
	// contains filtered or unexported fields
}

Proxy represents a single proxy with metadata and health stats.

func ParseProxy

func ParseProxy(raw string) (*Proxy, error)

ParseProxy parses a raw proxy string into a Proxy. Supported formats: http://host:port, socks5://user:pass@host:port, socks4://host:port, or bare host:port (defaults to HTTP).

func ParseProxyList

func ParseProxyList(r io.Reader) ([]*Proxy, error)

ParseProxyList reads proxies from a reader, one per line. Empty lines and lines starting with # are skipped.

func (*Proxy) Addr

func (p *Proxy) Addr() string

Addr returns the host:port of the proxy.

func (*Proxy) Alive

func (p *Proxy) Alive() bool

Alive reports whether the proxy is currently considered healthy.

func (*Proxy) Backoff

func (p *Proxy) Backoff() time.Duration

Backoff returns the current backoff duration.

func (*Proxy) FailCount

func (p *Proxy) FailCount() int64

FailCount returns the total failed checks.

func (*Proxy) LastCheck

func (p *Proxy) LastCheck() time.Time

LastCheck returns the time of the last health check.

func (*Proxy) Latency

func (p *Proxy) Latency() time.Duration

Latency returns the current EWMA latency.

func (*Proxy) SuccessCount

func (p *Proxy) SuccessCount() int64

SuccessCount returns the total successful checks.

type ProxyOption

type ProxyOption func(*Proxy)

ProxyOption configures per-proxy metadata when adding.

func InCity

func InCity(city string) ProxyOption

InCity sets the proxy's city.

func InCountry

func InCountry(code string) ProxyOption

InCountry sets the proxy's country code.

func WithASNTag

func WithASNTag(asn string) ProxyOption

WithASNTag sets the proxy's ASN identifier.

type Strategy

type Strategy interface {
	Select(proxies []*Proxy) *Proxy
}

Strategy selects a proxy from a list of candidates.

func LeastLatency

func LeastLatency() Strategy

LeastLatency returns a strategy that always picks the lowest latency proxy. Warning: may cause thundering herd if many clients use the same pool.

func P2C

func P2C() Strategy

P2C returns a Power of Two Choices strategy. Picks 2 random proxies and returns the one with lower latency.

func Random

func Random() Strategy

Random returns a strategy that selects a proxy uniformly at random.

func RoundRobin

func RoundRobin() Strategy

RoundRobin returns a strategy that cycles through proxies sequentially.

Directories

Path Synopsis
examples
basic command
roundtripper command
sticky command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL