forward

package
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Nov 12, 2026 License: Apache-2.0 Imports: 30 Imported by: 0

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

View Source
const (
	// MaxProfiles bounds the TLS profiles of one operator file.
	MaxProfiles = 32
)
View Source
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

View Source
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.

View Source
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

func CheckKeyFile(path string) error

CheckKeyFile refuses a key file whose mode lets the group or others read it, on systems where the mode means that.

func ExchangeFailure

func ExchangeFailure(err error, connected, clientGone bool) error

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

func FailureReason(err error) string

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

func ForwardFailure(err error) (int, string)

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) Has added in v0.2.0

func (n *Network) Has(id string) bool

Has reports whether a TLS profile with that ID is loaded.

func (*Network) Profiles added in v0.2.0

func (n *Network) Profiles() []ProfileInfo

Profiles describes the loaded profiles, by ID.

func (*Network) Public added in v0.2.0

func (n *Network) Public() bool

Public reports whether upstreams may use public addresses.

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.

Jump to

Keyboard shortcuts

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