Skip to content

Colduction/proxykit-go

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

proxykit-go

Go version Go Report Card License

A lightweight Go toolkit for working with HTTP/SOCKS proxies. It provides three packages that work independently or together:

Package Purpose
proxykit Core Proxy model with validation, getters, setters, and URL export
proxyparser Parse custom proxy-format strings into Proxy structs
proxypool Iterate over large proxy files without loading them into memory

Requirements

  • Go 1.26 or later

Install

go get -u github.com/colduction/proxykit-go

Proxy Model

The proxykit.Proxy struct holds a scheme, a host:port pair, and optional credentials.

Supported Schemes

Constant Value
proxykit.HTTP "http"
proxykit.HTTPS "https"
proxykit.SOCKS5 "socks5"
proxykit.SOCKS5H "socks5h"

Basic Usage

package main

import (
    "fmt"
    "github.com/colduction/proxykit-go"
)

func main() {
    p := &proxykit.Proxy{
        Scheme:   proxykit.HTTP,
        Host:     "example.com:8080",
        Username: "user",
        Password: "pass",
    }

    if p.IsValid() {
        fmt.Println(p.ExportURL().String())
        // Output: http://user:pass@example.com:8080
    }
}

Proxy Methods

Method Description
IsValid() bool Returns true if scheme, host, and credentials are all valid
IsZero() bool Returns true if the struct is its zero value
IsCredentialFilled() bool Returns true if a username has been set
ExportURL() *url.URL Returns the proxy as a *url.URL
Reset() Clears all fields back to their zero values
GetScheme() / SetScheme() Read or write the scheme
GetHost() / SetHost() Read or write the host
GetUsername() / SetUsername() Read or write the username (max 255 bytes)
GetPassword() / SetPassword() Read or write the password (max 255 bytes)

Standalone Validation Helpers

These package-level functions can be used without a Proxy instance:

proxykit.IsValidScheme("socks5")               // true
proxykit.IsValidHostnamePort("example.com:8080") // true
proxykit.IsValidCredentials("user", "pass")     // true
Function Description
IsValidScheme(s ProxyScheme) bool Checks that the scheme is one of the four supported values
IsValidHostnamePort(s string) bool Validates host:port — port must be 1–65535, host must be RFC 1123
IsValidCredentials(username, password string) bool A non-empty password requires a username; both must be ≤255 printable ASCII bytes

Proxy Parser

proxyparser.New compiles a format string into a reusable, goroutine-safe parser.

Format Verbs

Verb Captures
%t Scheme (e.g. http, socks5)
%h Hostname
%d Port
%u Username
%p Password
%% Literal % character

Any characters between verbs are treated as literal delimiters.

Strict vs Lenient Mode

Mode Behavior
strict = true Input must match the format exactly; any mismatch or trailing data returns an error
strict = false Missing credentials (%u, %p) and trailing characters are tolerated as long as the scheme and host are parsed successfully

Usage

package main

import (
    "fmt"
    "log"
    "github.com/colduction/proxykit-go/proxyparser"
)

func main() {
    // Standard format: scheme://host:port@username:password
    parser, err := proxyparser.New("%t://%h:%d@%u:%p", true)
    if err != nil {
        log.Fatal(err)
    }

    proxy, err := parser.Parse("http://example.com:8080@user:pass")
    if err != nil {
        log.Fatal(err)
    }

    fmt.Println(proxy.ExportURL().String())
    // Output: http://user:pass@example.com:8080
}

Custom delimiters work too:

// Format: (scheme)host:port:username:password
parser, err := proxyparser.New("(%t)%h:%d:%u:%p", false)
proxy, err := parser.Parse("(http)res-us.example.net:9999:admin:pass")

Parser Errors

Error Type Meaning
ErrInvalidFormatVerb Unknown verb character after %
ErrInvalidFormatEndStr Format string ends with a bare %
ErrMismatchDelim A literal delimiter in the format did not match at the given position
ErrSubseqDelimNotFound A following delimiter was expected but not found
ErrUnexpectedTrail Trailing characters in strict mode
ErrInvalidProxyFormat The parsed result is not a valid proxy
ErrHostNotParsed Host could not be extracted
ErrSchemeNotParsed Scheme could not be extracted

Proxy Pool

proxypool.New opens a proxy file and returns a ProxyPool that streams proxies without loading the whole file into RAM. It is safe for concurrent use from multiple goroutines.

Modes

Constant Behavior
proxypool.ModeSequential Returns proxies in file order; no sidecar index is built
proxypool.ModeShuffled Returns proxies in a random permuted order; builds a <file>.idx sidecar for O(1) seeks

Usage

package main

import (
    "fmt"
    "log"
    "github.com/colduction/proxykit-go/proxypool"
)

func main() {
    // ModeShuffled — random order, cycle forever
    pool, err := proxypool.New("proxies.txt", proxypool.ModeShuffled, true)
    if err != nil {
        log.Fatal(err)
    }
    defer pool.Close()

    for proxy, ok := pool.Next(); ok; proxy, ok = pool.Next() {
        fmt.Println(proxy)
    }
}

Pool Options

Parameter Type Description
path string Path to the newline-delimited proxy file
mode proxypool.Mode ModeSequential or ModeShuffled
reuse bool If true, iteration restarts from the beginning after the last proxy is returned

Sidecar Index (.idx)

When using ModeShuffled, a <path>.idx binary file is created next to the proxy file on the first run. Subsequent runs reuse it, making startup instant for large files. The index stores 8-byte offsets for every line, enabling O(1) random access.

ProxyPool Interface

type ProxyPool interface {
    Next() (string, bool)
    Close() error
}
  • Next() returns the next proxy string. The boolean is false when the pool is exhausted (and reuse is false).
  • Close() releases the open file handles and sidecar index.

Full Example

package main

import (
    "fmt"
    "log"

    "github.com/colduction/proxykit-go"
    "github.com/colduction/proxykit-go/proxyparser"
    "github.com/colduction/proxykit-go/proxypool"
)

func main() {
    // 1. Build a parser for a custom proxy format
    parser, err := proxyparser.New("%t://%h:%d@%u:%p", false)
    if err != nil {
        log.Fatal(err)
    }

    // 2. Parse a single proxy string
    proxy, err := parser.Parse("http://proxy.example.com:8080@alice:secret")
    if err != nil {
        log.Fatal(err)
    }
    if proxy.IsValid() {
        fmt.Println(proxy.ExportURL().String())
        // http://alice:secret@proxy.example.com:8080
    }

    // 3. Stream proxies from a file
    pool, err := proxypool.New("proxies.txt", proxypool.ModeSequential, false)
    if err != nil {
        log.Fatal(err)
    }
    defer pool.Close()

    for line, ok := pool.Next(); ok; line, ok = pool.Next() {
        p, err := parser.Parse(line)
        if err != nil || !p.IsValid() {
            continue
        }
        _ = proxykit.IsValidScheme(p.GetScheme())
        fmt.Println(p.ExportURL().String())
    }
}

License

See LICENSE for details.

About

Lightweight Go package for defining, parsing, and iterating proxy endpoints with validation helpers and file-backed pooling for large lists.

Topics

Resources

License

Stars

Watchers

Forks

Contributors

Languages