providerproxy

package
v0.1.1 Latest Latest
Warning

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

Go to latest
Published: Sep 16, 2026 License: GPL-3.0 Imports: 28 Imported by: 0

Documentation

Overview

Package providerproxy is a record/replay HTTP proxy for the metadata providers Emby and Jellyfin call out to.

embyfin-mcp rarely talks to TMDB, TheTVDB, OMDb or the image CDNs itself: it asks the media server to (identify, refresh, remote images), and the server - a .NET app in a container - makes those calls. That puts them out of reach of anything that hooks Go's http.RoundTripper, so go-vcr and friends cannot see them. The only layer that can is a proxy in front of the container.

.NET honours HTTPS_PROXY, and on Linux it trusts whatever SSL_CERT_FILE points at, so the container is started with both: the proxy address, and a CA certificate the proxy signs its per-host certificates with (Options.CA; scripts/testenv.sh mints it and mounts it into the container). In record mode the real providers are called once and the responses are written to cassettes; in replay mode - the default, and what CI uses - they are served from disk and no network is touched.

The one call embyfin-mcp makes itself, the TMDB runtime lookup behind audit_runtime, goes through the same proxy in the tests by giving the tmdb client an http.Client that trusts the CA and uses the proxy.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Drift

type Drift struct {
	Key           string
	StatusWas     int
	StatusIs      int
	FieldsAdded   []string
	FieldsRemoved []string
}

Drift is one recorded interaction whose live response no longer has the shape the cassette captured.

Only the shape is compared, never the values: which film TMDB ranks first this week is none of our business, but a field appearing, vanishing or changing type is exactly what breaks the server's decoding, and with it every identify and refresh the tools depend on.

func (Drift) String

func (d Drift) String() string

type Mode

type Mode int

Mode selects whether the proxy calls the real providers.

const (
	// Replay serves from the cassettes and never reaches the network. A
	// request with no recording is a loud failure, not an empty response.
	Replay Mode = iota
	// Record calls the real provider and writes what comes back.
	Record
	// Verify calls the real provider and compares the shape of what comes
	// back against the cassette, without writing. The recorded response is
	// still what gets served, so a test outcome never depends on what a
	// provider happened to return today - drift is reported separately.
	Verify
)

type Options

type Options struct {
	// Mode defaults to Replay.
	Mode Mode
	// CassetteDir holds one JSON file per provider host.
	CassetteDir string
	// Addr to listen on. Must be reachable from the container, so bind all
	// interfaces (e.g. "0.0.0.0:18080").
	Addr string
	// Logger receives replay misses and record notices; defaults to stderr.
	Logger *log.Logger
	// CACert and CAKey are PEM files holding the certificate authority the
	// proxy signs its per-host certificates with. When both are set the
	// files are loaded (created first if they do not exist), so the same
	// authority can be mounted into a container that was started before the
	// proxy. When empty an in-memory authority is minted for this process.
	CACert, CAKey string
	// RedactQuery names query parameters dropped from every request before
	// it is keyed and recorded: an API key such as TMDB's api_key changes
	// from one operator to the next and must not decide whether a cassette
	// matches, nor be committed with it.
	RedactQuery []string
	// RedactBodyFields names JSON fields whose string value is replaced in a
	// recorded response body. A provider's login answers with a bearer token
	// for the media server's own account, which is a credential the
	// repository must not carry; replay needs none of it, because the proxy
	// answers the calls that token would authorise.
	RedactBodyFields []string
	// IgnoreHosts are hosts this proxy answers 204 for and never records: the
	// media server talking to itself. Emby pings its own container address on
	// startup, which NO_PROXY cannot exclude because the address is only
	// known once the container is running, and which is no part of what these
	// cassettes are about.
	IgnoreHosts []string
}

Options configure a Proxy.

type Proxy

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

Proxy is a MITM HTTP proxy backed by cassettes.

func New

func New(opts Options) (*Proxy, error)

New starts a proxy and returns it. Close stops it and, in Record mode, flushes the cassettes.

func (*Proxy) Addr

func (p *Proxy) Addr() string

Addr is the address the proxy is listening on.

func (*Proxy) Close

func (p *Proxy) Close() error

Close stops the proxy, writing any newly recorded cassettes.

func (*Proxy) Drifts

func (p *Proxy) Drifts() []Drift

Drifts returns the shape changes seen so far, in a stable order. Empty in any mode but Verify.

func (*Proxy) Misses

func (p *Proxy) Misses() []string

Misses returns the requests that had no recording, so a replay run can fail with the list rather than leaving tests to pass on empty responses.

func (*Proxy) Port

func (p *Proxy) Port() int

Port is the port the proxy is listening on.

Jump to

Keyboard shortcuts

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