Documentation
¶
Overview ¶
Package forward sends an admitted request to the one upstream it is bound to, through the standard library's reverse proxy, and names what a failed exchange means for the gateway's answer.
A binding is attached only with Bind, after every control has passed; the proxy reads it with BoundDial and dials nothing else: no header, query or host name a client sends can choose a destination, and a missing or non-loopback binding is sent nowhere. Every request uses a new connection, so a failed one is never silently resent. The package imports only compile. The request pipeline calls it; nothing else forwards.
Index ¶
- Constants
- Variables
- func Bind(ctx context.Context, d compile.Destination) context.Context
- func Bound(ctx context.Context) (compile.Destination, bool)
- func CheckKeyFile(path string) error
- func ExchangeFailure(err error, connected, clientGone bool) error
- func FailureReason(err error) string
- func ForwardFailure(err error) (int, string)
- func LoadCertificate(certificateFile, keyFile string) (*tls.Certificate, error)
- func NewUpstreamProxy(timeouts UpstreamTimeouts, pool PoolSettings, network func() *Network, ...) (*upstreamProxy, error)
- type Network
- type PoolSettings
- type ProfileInfo
- type ProfileSettings
- type UpstreamTimeouts
Constants ¶
const (
// MaxProfiles bounds the TLS profiles of one operator file.
MaxProfiles = 32
)
const MaxResponseHeaderBytes = 64 << 10
MaxResponseHeaderBytes bounds the response header an upstream may send; a longer one fails the exchange. Envoy's default for HTTP/1 response headers is 80 KiB, NGINX's proxy_buffer_size 4 or 8 KiB.
Variables ¶
var ( ErrNoUpstream = errors.New("no upstream for the request") ErrUpstreamTimeout = errors.New("upstream timed out") )
Forwarding failures that decide the gateway's own answer; any other error means the upstream could not be reached or failed.
var (
ErrResponseStalled = errors.New("upstream response stalled")
)
Functions ¶
func Bind ¶
Bind returns ctx carrying the destination the compiled rule chose: the one upstream the request may reach and the path it is forwarded with. It is the only way to attach a binding.
func Bound ¶
func Bound(ctx context.Context) (compile.Destination, bool)
Bound returns the destination ctx is bound to, if a binding is attached.
func CheckKeyFile ¶ added in v0.2.0
CheckKeyFile refuses a key file whose mode lets the group or others read it, on systems where the mode means that.
func ExchangeFailure ¶
ExchangeFailure classifies an exchange that failed before any response by what is known about delivery and, for the gateway's answer, whether the upstream timed out.
func FailureReason ¶
FailureReason states what is known about the delivery of a request whose forwarding failed before any response: "not_sent" when it never reached the upstream, or why not when the gateway refused the connection ("destination_refused": an address no setting allows; "certificate_invalid"; "tls_handshake_failed"; "upstream_ejected": the endpoint failed to connect repeatedly and is ejected for a while), "outcome_unknown" when the upstream may have acted on it, and "client_cancelled" when the client went away after it was handed to an upstream connection, which leaves the outcome unknown too. A forwarder that cannot tell gives no reason.
func ForwardFailure ¶
ForwardFailure maps a forwarding failure to the gateway's answer: 504 when the upstream timed out, 503 when no upstream could be used, and 502 otherwise.
func LoadCertificate ¶ added in v0.2.0
func LoadCertificate(certificateFile, keyFile string) (*tls.Certificate, error)
LoadCertificate reads a certificate chain (leaf first) and its private key from absolute paths: the key a PKCS #8 RSA key of at least 2,048 bits or an ECDSA P-256 key, in a file the group and others cannot read on Unix. The returned certificate's Leaf is parsed.
func NewUpstreamProxy ¶
func NewUpstreamProxy(timeouts UpstreamTimeouts, pool PoolSettings, network func() *Network, logger *slog.Logger) (*upstreamProxy, error)
NewUpstreamProxy returns the proxy whose exchanges are bounded by timeouts. Every timeout must be positive: a zero would leave its phase unbounded. pool bounds the idle connections kept. network returns the current upstream network settings at each connection. The reverse proxy's own warnings, such as a failed response body read, go to logger.
Types ¶
type Network ¶ added in v0.2.0
type Network struct {
// contains filtered or unexported fields
}
Network is a loaded, immutable set of upstream network settings. It satisfies compile.Network.
func LoadNetwork ¶ added in v0.2.0
func LoadNetwork(public bool, settings []ProfileSettings, sessionLifetime time.Duration) (*Network, error)
LoadNetwork reads every profile's files. It fails on the first profile that is invalid, naming it; it never returns a partial set. TLS sessions to upstreams are resumed for at most sessionLifetime; 0 turns resumption off.
func (*Network) Profiles ¶ added in v0.2.0
func (n *Network) Profiles() []ProfileInfo
Profiles describes the loaded profiles, by ID.
type PoolSettings ¶ added in v0.2.0
type PoolSettings struct {
// MaxIdle is the most idle connections kept per endpoint; 0 sends every
// request on a new connection closed after its response.
MaxIdle int
// IdleTimeout closes a connection idle this long. It must stay below the
// upstream server's own idle timeout, so the gateway, not the upstream,
// ends an idle connection.
IdleTimeout time.Duration
// EjectAfter is how many consecutive connection failures eject an
// endpoint, so requests to it fail at once for a while; 0 never ejects.
EjectAfter int
}
PoolSettings bound the idle connections kept to upstreams.
type ProfileInfo ¶ added in v0.2.0
type ProfileInfo struct {
ID string `json:"id"`
CAPinned bool `json:"ca_pinned"`
ClientCertificate bool `json:"client_certificate"`
ExpiresAt *time.Time `json:"client_certificate_expires_at"`
}
ProfileInfo describes a loaded profile without its file paths or keys.
type ProfileSettings ¶ added in v0.2.0
type ProfileSettings struct {
ID string `json:"id"`
CAFile string `json:"ca_file"`
ClientCertificateFile string `json:"client_certificate_file"`
ClientKeyFile string `json:"client_key_file"`
}
ProfileSettings is one TLS profile of the operator file.
type UpstreamTimeouts ¶
type UpstreamTimeouts struct {
// Dial bounds establishing the connection.
Dial time.Duration
// ResponseHeader bounds the wait for the response header once the
// request has been written, and each wait for the upstream to take more
// of the request while it is written.
ResponseHeader time.Duration
// ReadIdle bounds each wait for more of the response body: a body that
// sends nothing for this long ends the exchange.
ReadIdle time.Duration
}
UpstreamTimeouts bounds the phases of one exchange with an upstream.