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 ¶
- Variables
- func Bind(ctx context.Context, d compile.Destination) context.Context
- func Bound(ctx context.Context) (dial, path string, bound bool)
- func ExchangeFailure(err error, connected, clientGone bool) error
- func FailureReason(err error) string
- func ForwardFailure(err error) (int, string)
- func NewUpstreamProxy(timeouts UpstreamTimeouts, logger *slog.Logger) (*upstreamProxy, error)
- type UpstreamTimeouts
Constants ¶
This section is empty.
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 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, "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 NewUpstreamProxy ¶
func NewUpstreamProxy(timeouts UpstreamTimeouts, 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. The reverse proxy's own warnings, such as a failed response body read, go to logger.
Types ¶
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.
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.