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
- Variables
- func EnvName(flag string) string
- func HashName(f HashFunction) string
- func IgnoreName(i gqlhash.Ignore) string
- func NewHasher(f HashFunction) (hash.Hash, bool)
- func ParseIgnore(s string) (gqlhash.Ignore, bool)
- func TLSClientConfig(ca *x509.CertPool) *tls.Config
- func TLSServerConfig(cert *tls.Certificate) *tls.Config
- type Format
- type HashFunction
- type Hasher
- type Proxy
- type ProxyControl
- type ProxyLog
- type ProxyServer
- type ProxyUpstream
Constants ¶
const EnvPrefix = "GQLHASH_PROXY_"
EnvPrefix is what the environment form of a proxy flag starts with, see EnvName.
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
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.