pac

package
v1.0.124 Latest Latest
Warning

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

Go to latest
Published: Jul 18, 2026 License: MIT Imports: 11 Imported by: 0

Documentation

Overview

Package pac is the PAC (proxy auto-config) engine: the persisted PAC configuration store and the FindProxyForURL generator. Extracted from package main per ADR-0002; the HTTP handlers, route registration, and the pacStore singleton stay in main (pac.go shim). The former pacDefaultProxyPort package global is now a Store field (SetDefaultPort), set once by the startup slice.

Index

Constants

View Source
const (
	MaxExclusionEntries = 10000
	// MaxEntryLen matches the DNS name length bound (RFC 1035).
	MaxEntryLen = 253
	// MaxArtifactBytes is the hard compiled-output budget. Chromium rejects
	// PAC scripts over 1 MiB at fetch time, so a config that compiles past
	// that is undeliverable and must be rejected, not served.
	MaxArtifactBytes = 1 << 20
	// WarnArtifactBytes is the advisory compiled-output budget.
	WarnArtifactBytes = 512 << 10
)

Validation limits. MaxExclusionEntries mirrors the cluster snapshot cap (maxSnapPACExclusions in controlplane_snapshot.go) so a config that validates here can always ride a ConfigSnapshot.

View Source
const (
	IssueEmptyEntry       = "empty_entry"
	IssueControlChars     = "control_chars"
	IssueEntryTooLong     = "entry_too_long"
	IssueTooManyEntries   = "too_many_exclusions"
	IssueInvalidCIDR      = "invalid_cidr"
	IssueInvalidWildcard  = "invalid_wildcard"
	IssueInvalidHost      = "invalid_host"
	IssueInvalidPort      = "invalid_port"
	IssueInvalidProxyHost = "invalid_proxy_host"
	IssueDuplicateEntry   = "duplicate_entry"
	IssueHostFallback     = "proxy_host_fallback"
	IssueCIDRNormalized   = "cidr_normalized"
	IssueOutputTooLarge   = "output_too_large"
	IssueOutputLarge      = "output_large"
)

ValidationIssue codes. Stable strings — they are part of the admin API response shape.

View Source
const CompilerVersion = "1"

CompilerVersion identifies the PAC generator's output contract. Bump on any change that alters generated bytes for an unchanged config.

Variables

This section is empty.

Functions

func ValidateConfig added in v1.0.122

func ValidateConfig(c Config) (Normalized, []ValidationIssue)

ValidateConfig strictly validates and normalizes c. The returned issue list is non-empty exactly when the config must be rejected; warnings that do not reject (dedupe, host-fallback advisory) are on the returned Normalized.

Types

type Artifact added in v1.0.122

type Artifact struct {
	// JS is the generated FindProxyForURL script.
	JS string
	// Digest is the SHA-256 hex of JS — the HTTP ETag source. It covers the
	// ACTUAL bytes served, including a request-Host-derived proxy host when
	// the fallback is active.
	Digest string
	// Fingerprint is the SHA-256 hex of the canonical normalized config,
	// independent of the request-derived fallback host.
	Fingerprint string
	// CompilerVersion is the generator contract version.
	CompilerVersion string
	// GeneratedAt is when this artifact was built (metadata only; never
	// hashed, so it cannot break determinism).
	GeneratedAt time.Time
	// Warnings carries normalization warnings (dropped legacy junk, dedupes,
	// host-fallback advisory).
	Warnings []ValidationIssue
	// ProxyChain is the effective directive chain, e.g. ["PROXY p:8080"] or
	// ["DIRECT"] in the degenerate no-host case.
	ProxyChain []string
	// HostFallback is true when the proxy hostname was derived from the
	// request's Host header rather than configuration. Fallback-mode
	// responses vary per request host and must not be shared-cached.
	HostFallback bool
}

Artifact is one compiled PAC file plus its provenance metadata. JS, Fingerprint, Digest, and CompilerVersion are deterministic for a given (config, fallback host) input; GeneratedAt and Warnings are operational metadata excluded from both hashes.

func CompileConfig added in v1.0.122

func CompileConfig(c Config, fallbackAddr string, defaultPort int) Artifact

CompileConfig validates (leniently) and compiles c. fallbackAddr is the request-derived "host[:port]" used when c.ProxyHost is empty; defaultPort is the startup-resolved proxy listener port used when c.ProxyPort is zero.

type Config

type Config struct {
	// ProxyHost is the hostname or IP of this proxy, e.g. "proxy.corp.com".
	// If empty the /proxy.pac endpoint uses the hostname from the request's
	// Host header (stripping the port, which belongs to the UI — not the proxy).
	ProxyHost string `json:"proxyHost"`
	// ProxyPort is the port the proxy server listens on.
	// If zero it falls back to the runtime proxy port set at startup.
	ProxyPort int `json:"proxyPort"`
	// Exclusions is the list of host patterns that should bypass the proxy.
	// Supports bare domains ("corp.local"), wildcard prefixes ("*.corp.local"),
	// and IP CIDR ranges ("192.168.0.0/16").
	Exclusions []string `json:"exclusions"`
}

Config is the persisted PAC configuration.

type ExclusionKind added in v1.0.122

type ExclusionKind int

ExclusionKind classifies a normalized exclusion entry.

const (
	// KindDomain matches the exact host and all subdomains (legacy bare-domain
	// semantics: host === "x" || dnsDomainIs(host, ".x")).
	KindDomain ExclusionKind = iota
	// KindWildcard matches subdomains only ("*.x" → dnsDomainIs(host, ".x")).
	KindWildcard
	// KindHostLiteral matches one IP literal exactly (host === "x").
	KindHostLiteral
	// KindCIDR matches when the resolved IP falls in an IPv4 network.
	KindCIDR
)

Exclusion kinds, in compiler emission group order.

type Normalized added in v1.0.122

type Normalized struct {
	// ProxyHost is the validated proxy hostname/IP, or "" when the request
	// Host header fallback is in effect.
	ProxyHost string
	// ProxyPort is the configured port (0 = auto: startup default, then 8080).
	ProxyPort int
	// Exclusions preserves configured order with duplicates removed.
	Exclusions []NormalizedExclusion
	// Warnings collects non-fatal normalization notes (dropped entries in
	// lenient mode, dedupes, host-fallback advisory).
	Warnings []ValidationIssue
}

Normalized is the canonical, validated form of a Config. It is the single input shape the compiler consumes.

func NormalizeLenient added in v1.0.122

func NormalizeLenient(c Config) Normalized

NormalizeLenient normalizes c tolerantly: malformed entries are dropped and recorded as warnings, never errors. Replay-path safe.

type NormalizedExclusion added in v1.0.122

type NormalizedExclusion struct {
	Kind ExclusionKind
	// Host is the lowercased, IDNA-punycoded, trailing-dot-stripped hostname
	// (KindDomain/KindWildcard, without the "*." prefix) or the IP literal
	// text (KindHostLiteral).
	Host string
	// CIDRIP/CIDRMask/CIDRPrefix carry the parsed IPv4 network (KindCIDR).
	// CIDRIP is the masked network base address.
	CIDRIP     string
	CIDRMask   string
	CIDRPrefix int
	// Raw is the entry as configured (trimmed), for error reporting.
	Raw string
}

NormalizedExclusion is one exclusion entry in canonical form.

func (NormalizedExclusion) Canonical added in v1.0.122

func (e NormalizedExclusion) Canonical() string

Canonical returns the canonical config-file text for the entry — the form persisted after a strictly validated mutation.

type State

type State struct {
	Cfg         Config
	Path        string
	DefaultPort int
	ModTime     time.Time
}

State is a full snapshot of a Store for test isolation (Snapshot/Restore).

type Store

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

Store persists Config to a JSON file.

func (*Store) Compile added in v1.0.122

func (s *Store) Compile(proxyAddr string) Artifact

Compile builds the PAC artifact for the current config. proxyAddr is the request-derived "host[:port]" used only when Config.ProxyHost is empty (the port part is discarded — /proxy.pac is served from the UI or proxy listener, whose port is not necessarily the proxy port clients must use).

func (*Store) DefaultPort

func (s *Store) DefaultPort() int

DefaultPort returns the startup-time fallback proxy port (0 if unset).

func (*Store) GeneratePAC

func (s *Store) GeneratePAC(proxyAddr string) string

GeneratePAC builds the PAC JavaScript (compatibility wrapper over Compile).

func (*Store) Get

func (s *Store) Get() Config

Get returns a snapshot of the current config.

func (*Store) Load

func (s *Store) Load(path string) error

Load reads config from the JSON file; a missing file is a no-op.

func (*Store) LoadMigrate added in v1.0.122

func (s *Store) LoadMigrate(path, legacyPath string) (migrated bool, err error)

LoadMigrate loads from path, one-way migrating from legacyPath when path does not exist yet but legacyPath does: the legacy file is loaded, the store is re-pointed at path, and the config is persisted there. The legacy file is left in place (frozen; a downgraded binary reads it stale — see docs/operator/pac-traffic-steering.md).

func (*Store) ModTime added in v1.0.122

func (s *Store) ModTime() time.Time

ModTime reports when the config last changed (zero before any load/set).

func (*Store) Restore

func (s *Store) Restore(st State)

Restore resets the store to a previously captured State (test support).

func (*Store) Set

func (s *Store) Set(c Config) error

Set replaces the config and persists it. Set is deliberately TOLERANT of entry content (no validation): its callers include config-version rollback and cluster snapshot apply, which replay historical data and discard errors. Strict validation lives at the admin API boundary (ValidateConfig).

func (*Store) SetDefaultPort

func (s *Store) SetDefaultPort(port int)

SetDefaultPort records the runtime proxy listening port used as the fallback when Config.ProxyPort is zero. Called once by the startup slice.

func (*Store) Snapshot

func (s *Store) Snapshot() State

Snapshot returns the store's full state. Test support: pair with Restore so tests that mutate the process-wide store stay hermetic under -shuffle.

type ValidationIssue added in v1.0.122

type ValidationIssue struct {
	// Field names the config field: "proxyHost", "proxyPort", "exclusions".
	Field string `json:"field"`
	// Entry is the offending exclusion entry, when applicable.
	Entry string `json:"entry,omitempty"`
	// Code is a stable machine-readable issue code (Issue* constants).
	Code string `json:"code"`
	// Message is the human-readable explanation.
	Message string `json:"message"`
}

ValidationIssue is one actionable validation error or warning.

Jump to

Keyboard shortcuts

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