reverseproxy

package
v2.1.0-unotech Latest Latest
Warning

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

Go to latest
Published: Apr 12, 2020 License: Apache-2.0 Imports: 35 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type ActiveHealthChecks

type ActiveHealthChecks struct {
	// The URI path to use for health checks.
	Path string `json:"path,omitempty"`

	// The port to use (if different from the upstream's dial
	// address) for health checks.
	Port int `json:"port,omitempty"`

	// HTTP headers to set on health check requests.
	Headers http.Header `json:"headers,omitempty"`

	// How frequently to perform active health checks (default 30s).
	Interval caddy.Duration `json:"interval,omitempty"`

	// How long to wait for a response from a backend before
	// considering it unhealthy (default 5s).
	Timeout caddy.Duration `json:"timeout,omitempty"`

	// The maximum response body to download from the backend
	// during a health check.
	MaxSize int64 `json:"max_size,omitempty"`

	// The HTTP status code to expect from a healthy backend.
	ExpectStatus int `json:"expect_status,omitempty"`

	// A regular expression against which to match the response
	// body of a healthy backend.
	ExpectBody string `json:"expect_body,omitempty"`
	// contains filtered or unexported fields
}

ActiveHealthChecks holds configuration related to active health checks (that is, health checks which occur in a background goroutine independently).

type CircuitBreaker

type CircuitBreaker interface {
	OK() bool
	RecordMetric(statusCode int, latency time.Duration)
}

CircuitBreaker is a type that can act as an early-warning system for the health checker when backends are getting overloaded.

type Config

type Config struct {
	// The threshold over sliding window that would trip the circuit breaker
	Threshold float64 `json:"threshold"`
	// Possible values: latency, error_ratio, and status_ratio. It
	// defaults to latency.
	Factor string `json:"factor"`
	// How long to wait after the circuit is tripped before allowing operations to resume.
	// The default is 5s.
	TripTime string `json:"trip_time"`
}

Config represents the configuration of a circuit breaker.

type DialError

type DialError struct {
	// contains filtered or unexported fields
}

DialError is an error that specifically occurs in a call to Dial or DialContext.

type DialInfo

type DialInfo struct {
	// Upstream is the Upstream associated with
	// this DialInfo. It may be nil.
	Upstream *Upstream

	// The network to use. This should be one of
	// the values that is accepted by net.Dial:
	// https://golang.org/pkg/net/#Dial
	Network string

	// The address to dial. Follows the same
	// semantics and rules as net.Dial.
	Address string

	// Host and Port are components of Address.
	Host, Port string
}

DialInfo contains information needed to dial a connection to an upstream host. This information may be different than that which is represented in a URL (for example, unix sockets don't have a host that can be represented in a URL, but they certainly have a network name and address).

func GetDialInfo

func GetDialInfo(ctx context.Context) (DialInfo, bool)

GetDialInfo gets the upstream dialing info out of the context, and returns true if there was a valid value; false otherwise.

func (DialInfo) String

func (di DialInfo) String() string

String returns the Caddy network address form by joining the network and address with a forward slash.

type FirstSelection

type FirstSelection struct{}

FirstSelection is a policy that selects the first available host.

func (FirstSelection) CaddyModule

func (FirstSelection) CaddyModule() caddy.ModuleInfo

CaddyModule returns the Caddy module information.

func (FirstSelection) Select

func (FirstSelection) Select(pool UpstreamPool, _ *http.Request) *Upstream

Select returns an available host, if any.

type HTTPTransport

type HTTPTransport struct {
	TLS                   *TLSConfig     `json:"tls,omitempty"`
	KeepAlive             *KeepAlive     `json:"keep_alive,omitempty"`
	Compression           *bool          `json:"compression,omitempty"`
	MaxConnsPerHost       int            `json:"max_conns_per_host,omitempty"`
	DialTimeout           caddy.Duration `json:"dial_timeout,omitempty"`
	FallbackDelay         caddy.Duration `json:"dial_fallback_delay,omitempty"`
	ResponseHeaderTimeout caddy.Duration `json:"response_header_timeout,omitempty"`
	ExpectContinueTimeout caddy.Duration `json:"expect_continue_timeout,omitempty"`
	MaxResponseHeaderSize int64          `json:"max_response_header_size,omitempty"`
	WriteBufferSize       int            `json:"write_buffer_size,omitempty"`
	ReadBufferSize        int            `json:"read_buffer_size,omitempty"`
	Versions              []string       `json:"versions,omitempty"`

	Transport *http.Transport `json:"-"`
}

HTTPTransport is essentially a configuration wrapper for http.Transport. It defines a JSON structure useful when configuring the HTTP transport for Caddy's reverse proxy. It builds its http.Transport at Provision.

func (HTTPTransport) CaddyModule

func (HTTPTransport) CaddyModule() caddy.ModuleInfo

CaddyModule returns the Caddy module information.

func (HTTPTransport) Cleanup

func (h HTTPTransport) Cleanup() error

Cleanup implements caddy.CleanerUpper and closes any idle connections.

func (*HTTPTransport) Provision

func (h *HTTPTransport) Provision(_ caddy.Context) error

Provision sets up h.Transport with a *http.Transport that is ready to use.

func (*HTTPTransport) RoundTrip

func (h *HTTPTransport) RoundTrip(req *http.Request) (*http.Response, error)

RoundTrip implements http.RoundTripper.

func (*HTTPTransport) UnmarshalCaddyfile

func (h *HTTPTransport) UnmarshalCaddyfile(d *caddyfile.Dispenser) error

UnmarshalCaddyfile deserializes Caddyfile tokens into h.

transport http {
    read_buffer  <size>
    write_buffer <size>
    dial_timeout <duration>
    tls_client_auth <cert_file> <key_file>
    tls_insecure_skip_verify
    tls_timeout <duration>
    tls_trusted_ca_certs <cert_files...>
    keepalive [off|<duration>]
    keepalive_idle_conns <max_count>
}

type Handler

type Handler struct {
	// Configures the method of transport for the proxy. A transport
	// is what performs the actual "round trip" to the backend.
	// The default transport is plaintext HTTP.
	TransportRaw json.RawMessage `json:"transport,omitempty" caddy:"namespace=http.reverse_proxy.transport inline_key=protocol"`

	// A circuit breaker may be used to relieve pressure on a backend
	// that is beginning to exhibit symptoms of stress or latency.
	// By default, there is no circuit breaker.
	CBRaw json.RawMessage `json:"circuit_breaker,omitempty" caddy:"namespace=http.reverse_proxy.circuit_breakers inline_key=type"`

	// Load balancing distributes load/requests between backends.
	LoadBalancing *LoadBalancing `json:"load_balancing,omitempty"`

	// Health checks update the status of backends, whether they are
	// up or down. Down backends will not be proxied to.
	HealthChecks *HealthChecks `json:"health_checks,omitempty"`

	// Upstreams is the list of backends to proxy to.
	Upstreams UpstreamPool `json:"upstreams,omitempty"`

	// TODO: figure out good defaults and write docs for this
	// (see https://github.com/Unotechsoftware/caddy/issues/1460)
	FlushInterval caddy.Duration `json:"flush_interval,omitempty"`

	// Headers manipulates headers between Caddy and the backend.
	Headers *headers.Handler `json:"headers,omitempty"`

	// If true, the entire request body will be read and buffered
	// in memory before being proxied to the backend. This should
	// be avoided if at all possible for performance reasons.
	BufferRequests bool `json:"buffer_requests,omitempty"`

	Transport http.RoundTripper `json:"-"`
	CB        CircuitBreaker    `json:"-"`
	// contains filtered or unexported fields
}

Handler implements a highly configurable and production-ready reverse proxy.

Upon proxying, this module sets the following placeholders (which can be used both within and after this handler):

Placeholder | Description ------------|------------- `{http.reverse_proxy.upstream.address}` | The full address to the upstream as given in the config `{http.reverse_proxy.upstream.hostport}` | The host:port of the upstream `{http.reverse_proxy.upstream.host}` | The host of the upstream `{http.reverse_proxy.upstream.port}` | The port of the upstream `{http.reverse_proxy.upstream.requests}` | The approximate current number of requests to the upstream `{http.reverse_proxy.upstream.max_requests}` | The maximum approximate number of requests allowed to the upstream `{http.reverse_proxy.upstream.fails}` | The number of recent failed requests to the upstream

func (Handler) CaddyModule

func (Handler) CaddyModule() caddy.ModuleInfo

CaddyModule returns the Caddy module information.

func (*Handler) Cleanup

func (h *Handler) Cleanup() error

Cleanup cleans up the resources made by h during provisioning.

func (*Handler) Provision

func (h *Handler) Provision(ctx caddy.Context) error

Provision ensures that h is set up properly before use.

func (*Handler) ServeHTTP

func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request, next caddyhttp.Handler) error

func (*Handler) UnmarshalCaddyfile

func (h *Handler) UnmarshalCaddyfile(d *caddyfile.Dispenser) error

UnmarshalCaddyfile sets up the handler from Caddyfile tokens. Syntax:

reverse_proxy [<matcher>] [<upstreams...>] {
    # upstreams
    to <upstreams...>

    # load balancing
    lb_policy <name> [<options...>]
    lb_try_duration <duration>
    lb_try_interval <interval>

    # active health checking
    health_path <path>
    health_port <port>
    health_interval <interval>
    health_timeout <duration>
    health_status <status>
    health_body <regexp>

    # passive health checking
    max_fails <num>
    fail_duration <duration>
    max_conns <num>
    unhealthy_status <status>
    unhealthy_latency <duration>

    # streaming
    flush_interval <duration>

    # header manipulation
    header_up   [+|-]<field> [<value|regexp> [<replacement>]]
    header_down [+|-]<field> [<value|regexp> [<replacement>]]

    # round trip
    transport <name> {
        ...
    }
}

Proxy upstream addresses should be network dial addresses such as `host:port`, or a URL such as `scheme://host:port`. Scheme and port may be inferred from other parts of the address/URL; if either are missing, defaults to HTTP.

type HeaderHashSelection

type HeaderHashSelection struct {
	// The HTTP header field whose value is to be hashed and used for upstream selection.
	Field string `json:"field,omitempty"`
}

HeaderHashSelection is a policy that selects a host based on a given request header.

func (HeaderHashSelection) CaddyModule

func (HeaderHashSelection) CaddyModule() caddy.ModuleInfo

CaddyModule returns the Caddy module information.

func (HeaderHashSelection) Select

func (s HeaderHashSelection) Select(pool UpstreamPool, req *http.Request) *Upstream

Select returns an available host, if any.

type HealthChecks

type HealthChecks struct {
	// Active health checks run in the background on a timer. To
	// minimally enable active health checks, set either path or
	// port (or both).
	Active *ActiveHealthChecks `json:"active,omitempty"`

	// Passive health checks monitor proxied requests for errors or timeouts.
	// To minimally enable passive health checks, specify at least an empty
	// config object.
	Passive *PassiveHealthChecks `json:"passive,omitempty"`
}

HealthChecks configures active and passive health checks.

type Host

type Host interface {
	// NumRequests returns the number of requests
	// currently in process with the host.
	NumRequests() int

	// Fails returns the count of recent failures.
	Fails() int

	// Unhealthy returns true if the backend is unhealthy.
	Unhealthy() bool

	// CountRequest atomically counts the given number of
	// requests as currently in process with the host. The
	// count should not go below 0.
	CountRequest(int) error

	// CountFail atomically counts the given number of
	// failures with the host. The count should not go
	// below 0.
	CountFail(int) error

	// SetHealthy atomically marks the host as either
	// healthy (true) or unhealthy (false). If the given
	// status is the same, this should be a no-op and
	// return false. It returns true if the status was
	// changed; i.e. if it is now different from before.
	SetHealthy(bool) (bool, error)
}

Host represents a remote host which can be proxied to. Its methods must be safe for concurrent use.

type IPHashSelection

type IPHashSelection struct{}

IPHashSelection is a policy that selects a host based on hashing the remote IP of the request.

func (IPHashSelection) CaddyModule

func (IPHashSelection) CaddyModule() caddy.ModuleInfo

CaddyModule returns the Caddy module information.

func (IPHashSelection) Select

func (IPHashSelection) Select(pool UpstreamPool, req *http.Request) *Upstream

Select returns an available host, if any.

type KeepAlive

type KeepAlive struct {
	Enabled             *bool          `json:"enabled,omitempty"`
	ProbeInterval       caddy.Duration `json:"probe_interval,omitempty"`
	MaxIdleConns        int            `json:"max_idle_conns,omitempty"`
	MaxIdleConnsPerHost int            `json:"max_idle_conns_per_host,omitempty"`
	IdleConnTimeout     caddy.Duration `json:"idle_timeout,omitempty"` // how long should connections be kept alive when idle
}

KeepAlive holds configuration pertaining to HTTP Keep-Alive.

type LeastConnSelection

type LeastConnSelection struct{}

LeastConnSelection is a policy that selects the host with the least active requests. If multiple hosts have the same fewest number, one is chosen randomly. The term "conn" or "connection" is used in this policy name due to its similar meaning in other software, but our load balancer actually counts active requests rather than connections, since these days requests are multiplexed onto shared connections.

func (LeastConnSelection) CaddyModule

func (LeastConnSelection) CaddyModule() caddy.ModuleInfo

CaddyModule returns the Caddy module information.

func (LeastConnSelection) Select

Select selects the up host with the least number of connections in the pool. If more than one host has the same least number of connections, one of the hosts is chosen at random.

type LoadBalancing

type LoadBalancing struct {
	// A selection policy is how to choose an available backend.
	// The default policy is random selection.
	SelectionPolicyRaw json.RawMessage `json:"selection_policy,omitempty" caddy:"namespace=http.reverse_proxy.selection_policies inline_key=policy"`

	// How long to try selecting available backends for each request
	// if the next available host is down. By default, this retry is
	// disabled. Clients will wait for up to this long while the load
	// balancer tries to find an available upstream host.
	TryDuration caddy.Duration `json:"try_duration,omitempty"`

	// How long to wait between selecting the next host from the pool. Default
	// is 250ms. Only relevant when a request to an upstream host fails. Be
	// aware that setting this to 0 with a non-zero try_duration can cause the
	// CPU to spin if all backends are down and latency is very low.
	TryInterval caddy.Duration `json:"try_interval,omitempty"`

	// A list of matcher sets that restricts with which requests retries are
	// allowed. A request must match any of the given matcher sets in order
	// to be retried if the connection to the upstream succeeded but the
	// subsequent round-trip failed. If the connection to the upstream failed,
	// a retry is always allowed. If unspecified, only GET requests will be
	// allowed to be retried. Note that a retry is done with the next available
	// host according to the load balancing policy.
	RetryMatchRaw caddyhttp.RawMatcherSets `json:"retry_match,omitempty" caddy:"namespace=http.matchers"`

	SelectionPolicy Selector              `json:"-"`
	RetryMatch      caddyhttp.MatcherSets `json:"-"`
}

LoadBalancing has parameters related to load balancing.

type NTLMTransport

type NTLMTransport struct {
	*HTTPTransport
	// contains filtered or unexported fields
}

NTLMTransport proxies HTTP with NTLM authentication. It basically wraps HTTPTransport so that it is compatible with NTLM's HTTP-hostile requirements. Specifically, it will use HTTPTransport's single, default *http.Transport for all requests (unless the client's connection is already mapped to a different transport) until a request comes in with an Authorization header that has "NTLM" or "Negotiate"; when that happens, NTLMTransport maps the client's connection (by its address, req.RemoteAddr) to a new transport that is used only by that downstream conn. When the upstream connection is closed, the mapping is deleted. This preserves NTLM authentication contexts by ensuring that client connections use the same upstream connection. It does hurt performance a bit, but that's NTLM for you.

This transport also forces HTTP/1.1 and Keep-Alives in order for NTLM to succeed.

It is basically the same thing as [nginx's paid ntlm directive](https://nginx.org/en/docs/http/ngx_http_upstream_module.html#ntlm) (but is free in Caddy!).

func (NTLMTransport) CaddyModule

func (NTLMTransport) CaddyModule() caddy.ModuleInfo

CaddyModule returns the Caddy module information.

func (*NTLMTransport) Cleanup

func (n *NTLMTransport) Cleanup() error

Cleanup implements caddy.CleanerUpper and closes any idle connections.

func (*NTLMTransport) Provision

func (n *NTLMTransport) Provision(ctx caddy.Context) error

Provision sets up the transport module.

func (*NTLMTransport) RoundTrip

func (n *NTLMTransport) RoundTrip(req *http.Request) (*http.Response, error)

RoundTrip implements http.RoundTripper. It basically wraps the underlying HTTPTransport.Transport in a way that preserves NTLM context by mapping transports/connections. Note that this method does not call n.HTTPTransport.RoundTrip (our own method), but the underlying n.HTTPTransport.Transport.RoundTrip (standard library's method).

type PassiveHealthChecks

type PassiveHealthChecks struct {
	// How long to remember a failed request to a backend. A duration > 0
	// enables passive health checking. Default is 0.
	FailDuration caddy.Duration `json:"fail_duration,omitempty"`

	// The number of failed requests within the FailDuration window to
	// consider a backend as "down". Must be >= 1; default is 1. Requires
	// that FailDuration be > 0.
	MaxFails int `json:"max_fails,omitempty"`

	// Limits the number of simultaneous requests to a backend by
	// marking the backend as "down" if it has this many concurrent
	// requests or more.
	UnhealthyRequestCount int `json:"unhealthy_request_count,omitempty"`

	// Count the request as failed if the response comes back with
	// one of these status codes.
	UnhealthyStatus []int `json:"unhealthy_status,omitempty"`

	// Count the request as failed if the response takes at least this
	// long to receive.
	UnhealthyLatency caddy.Duration `json:"unhealthy_latency,omitempty"`
	// contains filtered or unexported fields
}

PassiveHealthChecks holds configuration related to passive health checks (that is, health checks which occur during the normal flow of request proxying).

type RandomChoiceSelection

type RandomChoiceSelection struct {
	// The size of the sub-pool created from the larger upstream pool. The default value
	// is 2 and the maximum at selection time is the size of the upstream pool.
	Choose int `json:"choose,omitempty"`
}

RandomChoiceSelection is a policy that selects two or more available hosts at random, then chooses the one with the least load.

func (RandomChoiceSelection) CaddyModule

func (RandomChoiceSelection) CaddyModule() caddy.ModuleInfo

CaddyModule returns the Caddy module information.

func (*RandomChoiceSelection) Provision

func (r *RandomChoiceSelection) Provision(ctx caddy.Context) error

Provision sets up r.

func (RandomChoiceSelection) Select

Select returns an available host, if any.

func (*RandomChoiceSelection) UnmarshalCaddyfile

func (r *RandomChoiceSelection) UnmarshalCaddyfile(d *caddyfile.Dispenser) error

UnmarshalCaddyfile sets up the module from Caddyfile tokens.

func (RandomChoiceSelection) Validate

func (r RandomChoiceSelection) Validate() error

Validate ensures that r's configuration is valid.

type RandomSelection

type RandomSelection struct{}

RandomSelection is a policy that selects an available host at random.

func (RandomSelection) CaddyModule

func (RandomSelection) CaddyModule() caddy.ModuleInfo

CaddyModule returns the Caddy module information.

func (RandomSelection) Select

func (r RandomSelection) Select(pool UpstreamPool, request *http.Request) *Upstream

Select returns an available host, if any.

type RoundRobinSelection

type RoundRobinSelection struct {
	// contains filtered or unexported fields
}

RoundRobinSelection is a policy that selects a host based on round-robin ordering.

func (RoundRobinSelection) CaddyModule

func (RoundRobinSelection) CaddyModule() caddy.ModuleInfo

CaddyModule returns the Caddy module information.

func (*RoundRobinSelection) Select

func (r *RoundRobinSelection) Select(pool UpstreamPool, _ *http.Request) *Upstream

Select returns an available host, if any.

type Selector

type Selector interface {
	Select(UpstreamPool, *http.Request) *Upstream
}

Selector selects an available upstream from the pool.

type TLSConfig

type TLSConfig struct {
	RootCAPool []string `json:"root_ca_pool,omitempty"`
	// Added to the same pool as above, but brought in from files
	RootCAPEMFiles []string `json:"root_ca_pem_files,omitempty"`
	// TODO: Should the client cert+key config use caddytls.CertificateLoader modules?
	ClientCertificateFile    string         `json:"client_certificate_file,omitempty"`
	ClientCertificateKeyFile string         `json:"client_certificate_key_file,omitempty"`
	InsecureSkipVerify       bool           `json:"insecure_skip_verify,omitempty"`
	HandshakeTimeout         caddy.Duration `json:"handshake_timeout,omitempty"`
	ServerName               string         `json:"server_name,omitempty"`
}

TLSConfig holds configuration related to the TLS configuration for the transport/client.

func (TLSConfig) MakeTLSClientConfig

func (t TLSConfig) MakeTLSClientConfig() (*tls.Config, error)

MakeTLSClientConfig returns a tls.Config usable by a client to a backend. If there is no custom TLS configuration, a nil config may be returned.

type URIHashSelection

type URIHashSelection struct{}

URIHashSelection is a policy that selects a host by hashing the request URI.

func (URIHashSelection) CaddyModule

func (URIHashSelection) CaddyModule() caddy.ModuleInfo

CaddyModule returns the Caddy module information.

func (URIHashSelection) Select

func (URIHashSelection) Select(pool UpstreamPool, req *http.Request) *Upstream

Select returns an available host, if any.

type Upstream

type Upstream struct {
	Host `json:"-"`

	// The [network address](/docs/json/apps/http/#servers/listen)
	// to dial to connect to the upstream. Must represent precisely
	// one socket (i.e. no port ranges). A valid network address
	// either has a host and port, or is a unix socket address.
	//
	// Placeholders may be used to make the upstream dynamic, but be
	// aware of the health check implications of this: a single
	// upstream that represents numerous (perhaps arbitrary) backends
	// can be considered down if one or enough of the arbitrary
	// backends is down. Also be aware of open proxy vulnerabilities.
	Dial string `json:"dial,omitempty"`

	// The maximum number of simultaneous requests to allow to
	// this upstream. If set, overrides the global passive health
	// check UnhealthyRequestCount value.
	MaxRequests int `json:"max_requests,omitempty"`
	// contains filtered or unexported fields
}

Upstream bridges this proxy's configuration to the state of the backend host it is correlated with.

func (*Upstream) Available

func (u *Upstream) Available() bool

Available returns true if the remote host is available to receive requests. This is the method that should be used by selection policies, etc. to determine if a backend should be able to be sent a request.

func (*Upstream) Full

func (u *Upstream) Full() bool

Full returns true if the remote host cannot receive more requests at this time.

func (*Upstream) Healthy

func (u *Upstream) Healthy() bool

Healthy returns true if the remote host is currently known to be healthy or "up". It consults the circuit breaker, if any.

type UpstreamPool

type UpstreamPool []*Upstream

UpstreamPool is a collection of upstreams.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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