proxy

package
v1.4.0 Latest Latest
Warning

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

Go to latest
Published: May 31, 2026 License: MIT Imports: 14 Imported by: 0

Documentation

Index

Constants

View Source
const ShadowHeader = "X-Mroki-Mode"

ShadowHeader is the fixed header added to requests forwarded to the shadow service so downstream systems can distinguish shadow traffic from live traffic. The name is intentionally not configurable so consumers can rely on a stable convention. The live request path is never modified.

Variables

This section is empty.

Functions

func NewProxyResponseDiffer

func NewProxyResponseDiffer(opts ...diff.Option) *proxyResponseDiffer

Types

type CallbackFunc

type CallbackFunc func(req ProxyRequest, live, shadow ProxyResponse) error

type CheckFunc

type CheckFunc func(r *http.Request) bool

CheckFunc returns true if the request should be proxied to shadow

func MaxBodySizeCheck

func MaxBodySizeCheck(maxBytes int64) CheckFunc

MaxBodySizeCheck skips shadow for large or chunked bodies maxBytes <= 0 means unlimited (always returns true)

func SamplingRateCheck

func SamplingRateCheck(rate *SamplingRate) CheckFunc

SamplingRateCheck skips shadow based on sampling probability. rate == nil means always sample (always returns true). rate=1.0 and rate=0.0 use fast paths without RNG computation.

type Option

type Option func(*Proxy)

func WithCallbackFn

func WithCallbackFn(fn CallbackFunc) Option

func WithHTTPClient

func WithHTTPClient(client *http.Client) Option

WithHTTPClient allows setting a custom HTTP client

func WithLiveTimeout

func WithLiveTimeout(timeout time.Duration) Option

WithLiveTimeout sets the timeout for live requests

func WithLogger

func WithLogger(logger *slog.Logger) Option

WithLogger sets the logger for proxy operations

func WithShadowTimeout

func WithShadowTimeout(timeout time.Duration) Option

WithShadowTimeout sets the timeout for shadow requests

func WithShouldProxyToShadow

func WithShouldProxyToShadow(checks ...CheckFunc) Option

WithShouldProxyToShadow adds check functions to determine if shadow should be proxied Multiple checks can be provided - all must return true (AND logic) Can be called multiple times to add more checks

type Proxy

type Proxy struct {
	Live   *url.URL
	Shadow *url.URL
	// contains filtered or unexported fields
}

func NewProxy

func NewProxy(live, shadow *url.URL, opts ...Option) *Proxy

func (*Proxy) ServeHTTP

func (p *Proxy) ServeHTTP(w http.ResponseWriter, r *http.Request)

ServeHTTP implements the http.Handler interface for proxying requests.

Request Flow:

  1. Reads request body (needed to replay to both services)
  2. Launches live request with client context + timeout
  3. Launches shadow request (if sampled) with independent context + timeout
  4. Waits for live response and returns to client immediately
  5. Invokes callback with raw responses in background goroutine

Context Handling:

  • Live requests inherit the client's request context (r.Context()) This means if the client disconnects, live request is cancelled
  • Shadow requests use context.Background() as parent context This makes shadow independent of client connection state, ensuring complete response data collection even if client disconnects
  • Both contexts have their own timeout values for safety

Timeouts:

  • liveTimeout: Controls how long to wait for live service (blocks client)
  • shadowTimeout: Controls how long shadow service can run (doesn't block client)
  • Shadow timeout can be longer since it doesn't impact user experience

type ProxyRequest

type ProxyRequest struct {
	Method   string
	Path     string
	RawQuery string
	Headers  http.Header
	Body     []byte
}

ProxyRequest represents the original HTTP request being proxied

type ProxyResponse

type ProxyResponse struct {
	StatusCode int
	Response   *http.Response
	Body       []byte
	LatencyMs  int64
}

type SamplingRate

type SamplingRate float64

func NewSamplingRate

func NewSamplingRate(rate float64) (*SamplingRate, error)

func (SamplingRate) IsZero

func (s SamplingRate) IsZero() bool

IsZero checks if the sampling rate is zero.

func (SamplingRate) Sample

func (s SamplingRate) Sample() bool

Sample decides whether to sample based on the sampling rate. It returns true if the request should be sampled, false otherwise. Fast paths: rate=1.0 always returns true, rate=0.0 always returns false (no RNG).

func (SamplingRate) String

func (s SamplingRate) String() string

String returns the sampling rate as a formatted string.

Jump to

Keyboard shortcuts

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