Documentation
¶
Overview ¶
Package standalone models domains that are not owned by any app and proxy to a target the operator picks: a local port, an address, a URL, another app's port or a container.
Index ¶
Constants ¶
const ( MaxDialTimeoutSeconds = 120 MaxReadTimeoutSeconds = 3600 )
Limits on per-domain timeouts, in seconds.
const ( KindPort = "port" KindAddress = "address" KindURL = "url" KindApp = "app" KindContainer = "container" )
Target kinds.
const ( HostPreserve = "preserve" HostUpstream = "upstream" )
Host header modes.
const Scope = "_standalone"
Scope is the reserved {name} path segment the per-domain endpoints accept for standalone domains, so every per-domain feature works unchanged.
Variables ¶
var ( ErrBlocked = errors.New("standalone: target is not allowed") ErrLoop = errors.New("standalone: target points back at this server's own ingress") ErrConfirmationRequired = errors.New("standalone: target needs explicit confirmation") )
Errors a caller maps to distinct API responses.
var ErrInvalidTarget = errors.New("standalone: invalid target")
ErrInvalidTarget wraps every target parse failure.
Functions ¶
func CheckAddr ¶
CheckAddr refuses addresses no standalone domain may ever reach: cloud metadata, link-local, unspecified and multicast. Loopback and private are allowed on purpose.
func ValidHostname ¶
ValidHostname reports whether h is a syntactically valid DNS name.
Types ¶
type Assessment ¶
type Assessment struct {
Dial string `json:"dial,omitempty"`
Addresses []string `json:"addresses,omitempty"`
Internal bool `json:"internal"`
Loopback bool `json:"loopback"`
ControlPort *ControlPort `json:"control_port,omitempty"`
// NeedsConfirmation lists why the caller must confirm, empty when not.
NeedsConfirmation []string `json:"needs_confirmation,omitempty"`
}
Assessment says what saving a target means.
type ControlPort ¶
type ControlPort struct {
Port int `json:"port"`
Label string `json:"label"`
AlwaysBlock bool `json:"always_block,omitempty"`
}
ControlPort is one of this platform's own listeners on this server. AlwaysBlock ports (the ingress admin API) can never be a target; the rest need explicit confirmation.
type Env ¶
type Env struct {
Resolver Resolver
ControlPorts []ControlPort
// OwnAddresses are this server's public addresses, for loop detection.
OwnAddresses []string
// IngressPorts are the ports the ingress itself listens on (80, 443 or
// their overrides); a target on this server at one of them loops.
IngressPorts []int
}
Env is what Assess knows about this server.
type Options ¶
type Options struct {
UpstreamTLS bool
TLSSkipVerify bool
TLSServerName string
// HostHeader is "" (kind default), preserve, upstream, or a literal hostname.
HostHeader string
WebSocket bool
DialTimeoutSeconds int
ReadTimeoutSeconds int
StripPrefix string
}
Options shape how the ingress talks to the target.
func (Options) EffectiveHostMode ¶
EffectiveHostMode resolves "" to the target kind's default.
type Resolver ¶
type Resolver interface {
LookupNetIP(ctx context.Context, network, host string) ([]netip.Addr, error)
}
Resolver is the DNS surface Assess needs; *net.Resolver satisfies it.
type Target ¶
type Target struct {
Kind string
// Host is the address host for KindAddress, "127.0.0.1" for KindPort.
Host string
// Port is the dialed port, or the container port for app and container
// kinds (0 for an app means its main port).
Port int
URL *url.URL
App string
Container string
}
Target is a parsed, canonical proxy target.
func ParseTarget ¶
ParseTarget accepts "3000", ":3000", "127.0.0.1:3000", "localhost:3000", "host:port", "[v6]:port", "http(s)://host[:port][/base]", "app:NAME[:PORT]" and "container:NAME:PORT".
func (Target) DefaultHostMode ¶
DefaultHostMode is upstream for a URL, where the remote expects its own name, and preserve for everything on this server or network.
func (Target) Display ¶
Display is the human form of where traffic goes, e.g. "http://127.0.0.1:3000".