outbound

package
v1.142.0 Latest Latest
Warning

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

Go to latest
Published: Oct 9, 2026 License: Apache-2.0 Imports: 16 Imported by: 0

Documentation

Overview

Package outbound is the one transport chain every HTTP client the platform builds is made from (#1895). A request sent through it carries the platform's User-Agent, a client span that continues the caller's trace and the W3C traceparent that lets the upstream continue it, and is counted and timed under http_client_requests_total{kind, connection, status_class}; a destination the egress guard refused is counted under egress_blocked_total{reason} and logged once with the host sanitized.

A client is built with NewClient, or an existing RoundTripper is wrapped with Transport when the client is someone else's to build (the oauth2 library's token client, a websocket dialer). Nothing else in the tree constructs an http.Client or reaches http.DefaultClient; the Semgrep rule go-outbound-client refuses the shapes that would.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func FollowRedirects

func FollowRedirects(_ *http.Request, via []*http.Request) error

FollowRedirects is the redirect policy of a client that follows them, as a client with no policy would: for a discovery document, an identity provider, a logo, a renderer. A client that carries a credential or a guarded destination keeps the default and refuses.

func Metrics

func Metrics() *observability.Metrics

Metrics is the recorder the chain records through by default, for a retry loop that counts beside the requests it issues (upstream_retries_total) and holds no handle of its own. Nil, and nil-safe, until the observability layer installs one.

func NewClient

func NewClient(o Options) *http.Client

NewClient builds a client over the chain.

func RecordBlocked

func RecordBlocked(ctx context.Context, kind Kind, host, class string)

RecordBlocked counts and logs an egress refusal a caller found before any request was sent: a URL whose host a preflight check refused. The chain records the ones its dial refuses itself.

func SetDefaultMetrics

func SetDefaultMetrics(m *observability.Metrics)

SetDefaultMetrics installs the recorder every chain records through unless its Options name another. Nil-safe; a disabled recorder is a nil *Metrics and records nothing.

func Transport

func Transport(base http.RoundTripper, o Options) http.RoundTripper

Transport is the chain over base: the recorder outermost, the User-Agent, and the otelhttp transport that opens the client span and injects the trace context, over base. o.Base is ignored; base is what is given.

Types

type Chain

type Chain struct {
	Base       http.RoundTripper
	Kind       Kind
	Connection string
}

Chain is what Wraps reports of a client's transport: the transport the chain was built over and the kind and connection it records under.

func Wraps

func Wraps(rt http.RoundTripper) (Chain, bool)

Wraps reports whether rt is this package's chain, and what it carries, for a test that asserts on the client a package built.

type Kind

type Kind string

Kind is what an outbound call is for: the kind label, a closed set.

const (
	KindAPI          Kind = "api"          // an API gateway connection's upstream
	KindGraphQL      Kind = "graphql"      // a GraphQL connection's endpoint
	KindMCP          Kind = "mcp"          // an MCP gateway connection's upstream server
	KindUtil         Kind = "util"         // the util connection's public fetch
	KindOAuth        Kind = "oauth"        // a token endpoint: client credentials, code exchange, refresh
	KindOIDC         Kind = "oidc"         // OIDC discovery and JWKS
	KindEmbedding    Kind = "embedding"    // the embedding provider
	KindNotification Kind = "notification" // a notification channel's webhook
	KindSpecFetch    Kind = "spec_fetch"   // an OpenAPI document fetched for a catalog
	KindPromQL       Kind = "promql"       // the PromQL proxy's Prometheus
	KindRenderer     Kind = "renderer"     // the headless renderer's DevTools endpoint
	KindDataHub      Kind = "datahub"      // the knowledge layer's DataHub REST writes
	KindBranding     Kind = "branding"     // the portal's logo fetch
)

The kinds. A new client names one of these; the metric's cardinality is their count.

type Options

type Options struct {
	// Kind is what the calls are for. Required.
	Kind Kind
	// Connection is the operator's connection name, or empty for a kind
	// that has none.
	Connection string
	// Base is the transport the chain is built over: a connection's TLS and
	// dial settings, an egress guard, an in-process handler. Nil is a fresh
	// http.Transport with Go's defaults, never the process-wide one, so a
	// client has its own connection pool.
	Base http.RoundTripper
	// Timeout is the client's whole-request bound; zero leaves the request
	// to its context.
	Timeout time.Duration
	// CheckRedirect is the client's redirect policy; nil refuses redirects,
	// which is what a credential-bearing or SSRF-guarded call wants.
	CheckRedirect func(req *http.Request, via []*http.Request) error
	// NoPropagation leaves the traceparent and tracestate headers off the
	// request: a connection's trace_propagation key, for an upstream that
	// rejects unknown headers or must not see the deployment's trace ids.
	NoPropagation bool
	// Metrics overrides the recorder the observability layer installed
	// (SetDefaultMetrics). Nil records through the default.
	Metrics *observability.Metrics
}

Options is what a client is built with.

Jump to

Keyboard shortcuts

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