config

package
v2.0.2 Latest Latest
Warning

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

Go to latest
Published: Aug 5, 2026 License: MIT Imports: 25 Imported by: 0

Documentation

Overview

Package config is the configuration vocabulary of the commands: which hash function to use, which output format, and how much of a document to leave out.

It's a leaf package, so the hashing command and the proxy share it without one importing the other.

Index

Constants

View Source
const EnvPrefix = "GQLHASH_PROXY_"

EnvPrefix is what the environment form of a proxy flag starts with, see EnvName.

View Source
const ProxyCommand = "gqlhash-proxy"

ProxyCommand is the command that serves the proxy, named by the hasher where a caller reaches for it as a subcommand.

Variables

View Source
var (
	SupportedHashFunctions = names(hashFunctions,
		func(i int) (string, bool) { return hashFunctions[i].name, true })
	SupportedProxyHashFunctions = names(hashFunctions,
		func(i int) (string, bool) {
			return hashFunctions[i].name, hashFunctions[i].proxySafe
		})
	SupportedOutputFormats = names(outputFormats,
		func(i int) (string, bool) { return outputFormats[i].name, true })
	SupportedIgnoreModes = names(ignoreModes,
		func(i int) (string, bool) { return ignoreModes[i].name, true })
)

The values a flag takes, in table order. They read as one line of help, so the punctuation here is the help text.

Functions

func EnvName

func EnvName(flag string) string

EnvName is the environment variable that stands for the flag named flag.

Only the proxy reads these: it's a long-running service configured by a deployment, where the hashing command is invoked per document and a variable silently changing -hash would change what a pipeline produces.

func HashName

func HashName(f HashFunction) string

HashName returns the flag value that names f, or "" for the zero value.

func IgnoreName

func IgnoreName(i gqlhash.Ignore) string

IgnoreName returns the flag value that names i.

func NewHasher

func NewHasher(f HashFunction) (hash.Hash, bool)

NewHasher returns a new hasher for f, and false if f names none.

The second return keeps an unknown function from surfacing later: a nil hash.Hash fails at the first Reset, on the request path, with nothing left pointing at the configuration that was wrong.

func ParseIgnore

func ParseIgnore(s string) (gqlhash.Ignore, bool)

ParseIgnore returns the ignore mode s names, and false if it names none. Unlike ParseFormat and ParseHashFunction it needs the second return: the zero value of gqlhash.Ignore is the valid IgnoreNothing.

func TLSClientConfig

func TLSClientConfig(ca *x509.CertPool) *tls.Config

TLSClientConfig is what an https upstream's certificate is checked against, and nil where that's the host's trust store. The certificate is verified either way: nothing here turns that off, and the name is checked too, see TestUpstreamTLSHostname.

RootCAs is the only field set, so the two configs differ in one thing and everything else is what crypto/tls defaults to. No version floor of its own: Go raises those over time, and one pinned here would hold the proxy at the floor of the release it was written against.

func TLSServerConfig

func TLSServerConfig(cert *tls.Certificate) *tls.Config

TLSServerConfig is what the data plane serves with, and nil where it serves plaintext. Only the certificate is set: the protocol versions and cipher suites are what crypto/tls defaults to, the same reasoning as TLSClientConfig.

Types

type Format

type Format int8
const (
	FormatHex Format
	FormatBase32
	FormatBase64
	FormatBase64URL
)

func ParseFormat

func ParseFormat(s string) Format

ParseFormat returns the output format s names, and 0 for every name that is none of them.

type HashFunction

type HashFunction int8
const (
	HashFunctionSHA1 HashFunction
	HashFunctionSHA2
	HashFunctionSHA3
	HashFunctionMD5
	HashFunctionBLAKE2B
	HashFunctionBLAKE2S
	HashFunctionBLAKE3
	HashFunctionFNV
	HashFunctionFNV1A
	HashFunctionXXH64
	HashFunctionCRC32
	HashFunctionCRC64
)

func ParseHashFunction

func ParseHashFunction(s string) HashFunction

ParseHashFunction returns the hash function s names, and 0 for every name that is none of them.

func ParseProxyHashFunction

func ParseProxyHashFunction(s string) HashFunction

ParseProxyHashFunction is ParseHashFunction restricted to the functions an allowlist may rely on. It returns 0 for every other name.

type Hasher

type Hasher struct {
	// File is the document to read, or empty for stdin.
	File string

	// Format is the encoding of the hash, Hash the function it's made with and
	// Ignore what to leave out of it.
	Format Format
	Hash   HashFunction
	Ignore gqlhash.Ignore

	// DepthLimit is how deeply a document may nest before it's refused,
	// see [gqlhash.Options]. Always the limit in force: a flag below 1 is the
	// default here already, see [depthLimit].
	DepthLimit int

	// CmdPrintVersion means the caller prints the version and returns instead
	// of hashing.
	CmdPrintVersion bool
}

func ParseHasher

func ParseHasher(
	name string, args []string, stderr io.Writer,
) (cfg Hasher, exitCode int, run bool)

ParseHasher reads the flags of the gqlhash command. run is false when the caller is done and must return exitCode, which covers -help, a bad flag and a bad value alike. name is the command as invoked.

type Proxy

type Proxy struct {
	// AllowlistDir is the directory the allowed documents are read from.
	AllowlistDir string

	// HashFunc is one of the collision-resistant functions,
	// see [SupportedProxyHashFunctions].
	HashFunc HashFunction

	// Ignore is what to leave out of the hash of a document.
	Ignore gqlhash.Ignore

	// DepthLimit is how deeply a document may nest before it's refused,
	// see [gqlhash.Options]. Always the limit in force: a flag below 1 is the
	// default here already, see [depthLimit].
	DepthLimit int

	// OpaqueErrors answers every rejection with 403 and no detail.
	// TrustForwarded keeps the X-Forwarded-* headers a request arrives with,
	// which only a proxy behind a trusted load balancer may do.
	OpaqueErrors   bool
	TrustForwarded bool

	Server   ProxyServer
	Upstream ProxyUpstream
	Control  ProxyControl
	Log      ProxyLog

	// CmdPrintVersion means the caller prints the version and returns instead
	// of serving.
	CmdPrintVersion bool
}

Proxy is what the proxy command was asked to do.

func ParseProxy

func ParseProxy(
	name string, args []string, stderr io.Writer,
) (cfg Proxy, exitCode int, run bool)

ParseProxy reads the flags of the proxy command.

run is false when the caller is done and must return exitCode. name is the command as invoked.

func ParseProxyFor

func ParseProxyFor(
	http1Only bool, name string, args []string, stderr io.Writer,
) (cfg Proxy, exitCode int, run bool)

ParseProxyFor is ParseProxy for a binary that serves HTTP/1.1 only, which refuses -upstream.http2 rather than accepting the flag and serving something else. That's gqlhash-proxy-fhttp; net/http has no such restriction.

type ProxyControl

type ProxyControl struct {
	// Address is never empty: there is no way to run without this server.
	Address string

	// Token is the bearer token a request to a changing endpoint must carry,
	// empty for no check. From the environment alone, never a flag.
	Token string
}

ProxyControl is the server that answers the metrics and the endpoints that change what the proxy does.

type ProxyLog

type ProxyLog struct {
	// Level is left as given: the command owns the logger and parses it,
	// so neither this package nor the hashing command needs that dependency.
	Level string

	// JSON writes JSON instead of readable text. Requests logs every forwarded
	// request at debug level.
	JSON     bool
	Requests bool
}

ProxyLog is how the proxy writes its log.

type ProxyServer

type ProxyServer struct {
	Listen string

	// MaxBody is the largest request body to accept, in bytes, and MaxBatch how
	// many documents one of them may carry as a batch, every one of which has to
	// be allowed. 0 takes no batch at all, see -server.max-batch.
	MaxBody  int64
	MaxBatch int

	// ShutdownTimeout is how long the requests in flight are waited for on the way out.
	ShutdownTimeout time.Duration

	ReadHeaderTimeout time.Duration
	ReadTimeout       time.Duration
	WriteTimeout      time.Duration
	IdleTimeout       time.Duration

	// TLSCert is the certificate the proxy serves with, read from
	// -server.tls.cert and -server.tls.key, and nil where it serves plaintext.
	//
	// The key pair and not the file names: loading it is a start failure,
	// so a proxy that can't serve what it was configured to serve doesn't bind first
	// and fail every handshake after.
	TLSCert *tls.Certificate
}

ProxyServer is the listener that takes the traffic. Its timeouts bound what a client can hold open; a zero value leaves that one off.

type ProxyUpstream

type ProxyUpstream struct {
	URL *url.URL

	// Timeout is how long a request to it may take.
	Timeout time.Duration

	// MaxIdleConnsPerHost caps connection reuse: there's one upstream,
	// so every forwarded request draws from that one pool.
	// MaxIdleConns is the ceiling over it, 0 for none.
	MaxIdleConnsPerHost int
	MaxIdleConns        int

	// MaxConnLifetime retires an upstream connection once it's this old, 0 to
	// keep it as long as the upstream will. It lets a pool follow an upstream
	// that moves: a name resolving to several backends is balanced per connection,
	// so one that never turns over never reaches a new backend.
	MaxConnLifetime time.Duration

	// HTTP2 allows h2 to an https upstream, which multiplexes onto one connection
	// and makes the pool sizes matter little.
	HTTP2 bool

	// TLSCA holds the certificates that may sign an https upstream's,
	// read from -upstream.tls.ca. Empty takes the host's trust store.
	//
	// Certificates and not a file name: reading it is a start failure,
	// so an unreadable file doesn't surface as an upstream that can't be reached.
	TLSCA *x509.CertPool
}

ProxyUpstream is the GraphQL API a request is forwarded to.

Jump to

Keyboard shortcuts

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