proxykit

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: May 6, 2026 License: MIT Imports: 11 Imported by: 0

README

proxykit

Small, dependency-light Go library for outbound connections through HTTP/HTTPS CONNECT and SOCKS5 proxies, with optional system-proxy auto-detection and pluggable authentication.

Status: v0.1 complete. The public API is unstable until v1.0 — expect occasional renames during the v0.x line.

Features

Area Support
Transports HTTP CONNECT (TCP+TLS), SOCKS5, Direct
Authentication None, Basic, NTLM, Negotiate / Kerberos (Windows SSPI)
Auto-detection *_PROXY env vars (any platform), Windows WinINET (HKCU)
API Dialer (net.Dial-compatible), http.RoundTripper adapter
Platforms Windows, Linux, macOS — no cgo, fully static
Out of scope (v0.1)

PAC / WPAD, SOCKS4 / SOCKS4a, Digest auth, server-side SOCKS, TLS interception / MITM, connection pooling, retry / circuit breaker, macOS / BSD detection.

Roadmap
  • v0.2 — Linux detection (/etc/environment, GNOME GSettings, KDE kioslaverc); Linux/macOS Kerberos via jcmturner/gokrb5.
  • v0.3+ — community-driven (SOCKS5 user/pass options, WinHTTP detection, macOS detection on request).

Install

go get github.com/durck/proxykit

Quickstart

Direct dial — no proxy configured
import "github.com/durck/proxykit"

d := proxykit.NewDialer(proxykit.Config{})
conn, err := d.DialContext(ctx, "tcp", "example.com:443")
Explicit proxy
d := proxykit.NewDialer(proxykit.Config{
    Manual: "http://proxy.corp:8080",
})
conn, err := d.DialContext(ctx, "tcp", "example.com:443")
Auto-detect from env / WinINET
d := proxykit.NewDialer(proxykit.Config{AutoDetect: true})
conn, err := d.DialContext(ctx, "tcp", "example.com:443")

HTTP_PROXY, HTTPS_PROXY, NO_PROXY (and the lower-case spellings) are honoured everywhere; on Windows the manual ProxyServer in HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings is read as well.

Authenticated proxy
import (
    "github.com/durck/proxykit"
    "github.com/durck/proxykit/auth"
)

d := proxykit.NewDialer(proxykit.Config{
    Manual: "http://proxy.corp:8080",
    Auth: []auth.Authenticator{
        auth.Negotiate("http/PROXY.CORP.LOCAL"), // SSPI on Windows; ErrUnsupported elsewhere
        auth.NTLM("CORP", "alice", "secret"),
        auth.Basic("alice", "secret"),
    },
})

Authenticators are tried in order against schemes the proxy advertises in Proxy-Authenticate. Userinfo embedded in the proxy URL (http://user:pass@proxy:8080) is automatically converted into a Basic authenticator and prepended to the chain.

As an http.RoundTripper
client := &http.Client{
    Transport: proxykit.NewHTTPTransport(proxykit.Config{
        Manual:  "http://proxy.corp:8080",
        Timeout: 30 * time.Second,
    }),
}
resp, err := client.Get("https://example.com")

Examples

Runnable demos live under examples/:

Run them with go run:

go run ./examples/basic --proxy http://proxy:8080 example.com:443
HTTPS_PROXY=http://proxy:8080 go run ./examples/autodetect example.com:443
go run ./examples/http_client --auto https://example.com

proxytest CLI

cmd/proxytest is a diagnostic CLI bundled with the module:

go install github.com/durck/proxykit/cmd/proxytest@latest

proxytest detect
# URL                                       FROM        USER
# http://proxy.corp:8080                    env
# socks5://socks.corp:1080                  wininet

proxytest dial example.com:443                            # direct
proxytest dial --auto example.com:443                     # detect.All
proxytest dial --proxy http://proxy:8080 example.com:443  # explicit

Architecture

  • proxykit (root) — public API (Config, Dialer, NewDialer, NewHTTPTransport, ParseProxyURL).
  • proxykit/transport — concrete dialers: Direct, Connect (HTTP CONNECT), SOCKS5. Each implements the Dialer shape directly and is composable.
  • proxykit/authAuthenticator interface plus Basic, None, NTLM, Negotiate (Windows SSPI; errors.ErrUnsupported elsewhere).
  • proxykit/detectDetector framework, EnvDetector (always), WinINETDetector (Windows-only).

License

MIT.

Documentation

Overview

Package proxykit provides a small, dependency-light client for outbound connections through HTTP CONNECT and SOCKS5 proxies, with optional system-proxy auto-detection and pluggable authentication (Basic, NTLM, Negotiate/SSPI on Windows).

The package exposes a Dialer that satisfies the standard net.Dial signature, plus an http.RoundTripper adapter for use with http.Client.

Quickstart

cfg := proxykit.Config{Manual: "http://proxy:8080"}
d := proxykit.NewDialer(cfg)
conn, err := d.DialContext(ctx, "tcp", "example.com:443")

See the examples directory for more usage patterns.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func NewHTTPTransport

func NewHTTPTransport(cfg Config) http.RoundTripper

NewHTTPTransport returns an http.RoundTripper that dials through the proxy chain configured by cfg. It is a thin wrapper over http.Transport with DialContext set to the result of NewDialer; callers who need additional knobs (TLS config, idle pool sizing, HTTP/2 toggle) should construct their own *http.Transport using NewDialer directly.

func ParseProxyURL

func ParseProxyURL(s string) (*url.URL, error)

ParseProxyURL parses a proxy address into a *url.URL.

It accepts URLs with scheme http, https, socks, or socks5, plus bare "host:port" or "host" (treated as http on the default port).

The returned URL always has Host populated with an explicit port. Default ports per scheme: http=80, https=443, socks/socks5=1080.

Unsupported schemes (socks4, socks4a, ftp, ...) and empty input return an error.

Types

type Config

type Config struct {
	// Manual is an explicit proxy URL such as "http://proxy:8080" or
	// "socks5://1.2.3.4:1080". When set, it takes precedence over
	// AutoDetect. Empty means no manual override.
	Manual string

	// AutoDetect enables system proxy detection (environment variables,
	// Windows WinINET registry). Consulted only if Manual is empty.
	AutoDetect bool

	// Auth is the ordered list of Authenticators tried on HTTP 407
	// from a CONNECT proxy. The transport matches each Authenticator's
	// Scheme against the proxy-advertised Proxy-Authenticate values.
	Auth []auth.Authenticator

	// Timeout bounds a single dial attempt to the proxy or destination.
	// Zero means no timeout.
	Timeout time.Duration

	// OnLog, when non-nil, receives diagnostic messages. The level is
	// one of "debug", "info", "warn", "error".
	OnLog func(level, msg string)
}

Config configures a proxy Dialer or HTTP transport.

type Dialer

type Dialer interface {
	DialContext(ctx context.Context, network, address string) (net.Conn, error)
}

Dialer establishes outbound TCP connections, optionally through a proxy. The DialContext signature matches net.Dialer.DialContext so the result drops into http.Transport unchanged.

func NewDialer

func NewDialer(cfg Config) Dialer

NewDialer returns a Dialer wired according to cfg.

Resolution order:

  1. cfg.Manual (when non-empty) is tried first.
  2. cfg.AutoDetect runs every registered detector (env vars, WinINET on Windows) and appends each candidate.

For each resolved proxy URL a transport is selected by scheme (http/https → CONNECT, socks/socks5 → SOCKS5). Userinfo embedded in the URL is converted into either an auth.Basic prepended to cfg.Auth (CONNECT proxies) or RFC 1929 SOCKS authentication.

When several candidates resolve, dial attempts walk the chain in order and return the first success — preserving the precedence model in reverse_ssh. With no usable proxy the Dialer falls back to a direct net.Dialer with cfg.Timeout.

Directories

Path Synopsis
Package auth provides Authenticator implementations for HTTP CONNECT proxy authentication.
Package auth provides Authenticator implementations for HTTP CONNECT proxy authentication.
cmd
proxytest command
Command proxytest is a diagnostic CLI for proxykit.
Command proxytest is a diagnostic CLI for proxykit.
Package detect discovers system proxy configurations from one or more sources (environment variables, the Windows WinINET registry, etc.) and exposes them as a uniform list of [Candidate]s.
Package detect discovers system proxy configurations from one or more sources (environment variables, the Windows WinINET registry, etc.) and exposes them as a uniform list of [Candidate]s.
examples
autodetect command
Command autodetect dials through a system-detected proxy.
Command autodetect dials through a system-detected proxy.
basic command
Command basic dials a destination through an explicit proxy URL.
Command basic dials a destination through an explicit proxy URL.
http_client command
Command http_client demonstrates plugging proxykit into the stdlib http.Client as a custom transport.
Command http_client demonstrates plugging proxykit into the stdlib http.Client as a custom transport.
Package transport contains concrete dial implementations selected by the top-level [proxykit.Dialer].
Package transport contains concrete dial implementations selected by the top-level [proxykit.Dialer].

Jump to

Keyboard shortcuts

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