Documentation
¶
Overview ¶
Package plex provides the HTTP client used to talk to a Plex Media Server, including retry semantics and the httpStatusError sentinel types used by callers to distinguish 4xx from 5xx responses.
Index ¶
Constants ¶
const MaxResponseBody = 10 << 20 // 10 MB
MaxResponseBody caps the bytes we read from a Plex HTTP response to prevent OOM on unexpected payloads. 10 MiB covers the largest realistic /status/sessions and /library responses with headroom.
const TestToken = "$fixture-test-token"
TestToken is the fixed credential value used by NewTestClientFromServer and by hand-rolled test fixtures. The leading "$" mimics an unexpanded environment-variable placeholder, which the repo secret-scan regex deliberately excludes (`[^"$]` at the first-char position). Tests only require that the X-Plex-Token header round-trips the same string.
Variables ¶
var ErrNotFound = errors.New("not found")
ErrNotFound is returned by Get/GetWithHeaders when the Plex server responds 404. Callers can classify it via errors.Is(err, ErrNotFound).
Functions ¶
This section is empty.
Types ¶
type Client ¶
type Client struct {
HTTPClient *http.Client
BaseURL *url.URL
Token string
// contains filtered or unexported fields
}
Client is the Plex HTTP client. Fields are exported so the internal composition root (package main, package server) can construct test fixtures and read configuration without accessor noise; the whole internal/* tree is a single trust boundary.
func NewClient ¶
NewClient parses serverURL and returns a Client configured with a safe default HTTP transport. When caCertPath is non-empty, the PEM file at that path is loaded into the TLS RootCAs pool — TLS verification stays ENABLED, pinned to that CA. This is the recommended setup for users running Plex with a self-signed certificate.
The transport is wrapped in an httpx retry round-tripper that retries 429/502/503/504 responses and transient transport errors with jittered exponential backoff, HONORING the Retry-After header on 429. Retry count and base delay are fixed at construction (see defaultMaxAttempts / defaultRetryBaseDelay); every Get on the returned Client benefits from this without a per-call retry loop.
When caCertPath is empty:
- For "https://hash.plex.direct:32400" URLs, Plex's public Let's Encrypt cert validates against the OS trust store. No env var needed.
- For "https://<self-signed-host>:32400" URLs, the connection will FAIL on cert verification. Set PLEX_CA_CERT_PATH to the server's CA cert.
- For "http://..." URLs, TLS isn't in play; this transport config is a no-op.
func NewTestClientFromServer ¶
NewTestClientFromServer constructs a *Client wired to the given httptest.Server, using the server's own HTTP client for proper TLS and transport handling. This is the canonical test helper for packages that spin up an httptest.Server.
func (*Client) Get ¶
Get fetches path and unmarshals the JSON body into result. Returns ErrNotFound for 404, *HTTPStatusError for other non-2xx. When the Client was built by NewClient, transient failures (429/502/503/504 + transport errors) are retried transparently by the retry transport, honoring Retry-After on 429.
func (*Client) GetContainerSize ¶
GetContainerSize fetches a library section with one item and reads the totalSize field from the JSON body. This is more reliable than the X-Plex-Container-Total-Size header, which doesn't work for type-filtered queries (e.g. ?type=4 for episodes).
func (*Client) GetWithHeaders ¶
func (c *Client) GetWithHeaders(ctx context.Context, path string, result any, extra map[string]string) error
GetWithHeaders is Get with additional request headers merged on top of the defaults (Accept, X-Plex-Token).
func (*Client) Retries ¶ added in v1.4.2
Retries returns the cumulative number of HTTP retry attempts the retry round-tripper has performed across all requests on this client; it is surfaced as the plex_http_retries_total metric. Returns 0 for clients not built by NewClient (e.g. test fixtures), which install no retry hook.
type HTTPStatusError ¶
HTTPStatusError is returned by Get for non-200, non-404 responses. Kept distinct from a bare error so callers can classify 4xx (do not retry) vs 5xx (retry) via errors.As / errors.AsType.
func (*HTTPStatusError) Error ¶
func (e *HTTPStatusError) Error() string