nodesource

package
v0.3.5 Latest Latest
Warning

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

Go to latest
Published: Nov 7, 2026 License: GPL-3.0 Imports: 17 Imported by: 0

README

Private source byte transport

This package is an unwired primitive. Trusted composition supplies the fixed HTTPS endpoint, node certificate identity mapping, current grant authority and atomic exact-source acquisition. There are no provider URLs, paths or provider headers on this protocol. Only an opaque source credential goes in the dedicated header. The endpoint must remain private and must not be registered on the Plex surface.

Scope contains the complete placement fence (controller and worker identities and boot incarnations, session, generation), viewer and immutable revision. Authority.Verify must enforce current placement, viewer policy and revocation; there is no permissive implementation. HEAD/GET validate before acquisition. Byte copy revalidates at the configured cadence (maximum one second), including after reads that straddle that interval. Failed checks stop output. Already authorized bytes in HTTP/network buffers cannot be recalled. Expiry also bounds the request context locally. Hosts must keep clocks synchronized; this primitive makes no clock-skew allowance. A source ignoring context can delay request completion but cannot release its hold merely because the deadline elapsed.

Acquire must atomically enforce current scope and the exact source lifetime's sealing barrier while acquiring its hold. Verification before acquisition is not proof the lifetime is still open. It must return the exact captured source object, matching Scope and a bounded accounting-only Release callback, even on error if a hold was acquired. Context readers must register any producers that can outlive the call with the supplied core.ReadRetirement before starting them. This package does not adapt an uncooperative ReaderAt by spawning a goroutine.

The handler admits a bounded registry entry and installs ReadRetirement before Acquire. Every subsequent exit seals that tracker. Cancelled/disconnected reads and acquisition errors retain returned holds until all registered producers exit. Host lifecycle must call Reconcile periodically, during drain, and after expiry when no HTTP requests remain; it calls releases outside registry locks. Pending entries count against admission and are never evicted by time. The handler owns no goroutines. No grant registry is duplicated here; injected authority must bound its own grants, issuance and renewal retention. Configure HTTP server header/time and connection limits at the private listener too.

Reconcile/Pending report transport hold accounting, not source retirement proof. A request can still be between verification and admission. Source manager lifetime sealing/accounting and core.SourceRetirement remain final source cleanup proof; core.EncoderInputLease and encoder retirement remain separate. Release never calls MediaSource.Close. Neither HTTP completion nor network failure attests to remote producers stopping. Reader.Close/Done only cancel/drain local HTTP work.

The Go client uses verified chain/hostname TLS plus an explicit server identity binding, presents its client certificate, and binds each grant to its configured worker boot. No redirects, environment proxies or insecure TLS fallback are used. HEAD pins size and an ETag derived from complete Scope; each single range checks status, ETag, total size, exact range, length and EOF. Multipart is rejected. Single suffix/open-ended ranges and HEAD use standard Go HTTP semantics. A trusted resolver must guarantee immutable bytes for a revision; cryptographic content integrity is supplied by TLS, not by hashing the entire media file.

Renew takes a fresh grant from an injected authority, requires every Scope field unchanged, checks the same HEAD size/ETag and then swaps the underlying bearer. Existing requests keep their old deadline. The immutable remotetranscode Start.Grant must identify a stable source handle; it must NOT be conflated with this rotating bearer. Same source handle, revision, object and worker-local input lease must remain bound throughout renewal. There is no wire renewal endpoint.

Remaining integration belongs to host composition: authority/resolver, source manager hold/seal adapter, certificate rotation/revocation, lifecycle reconciliation and worker-local FFmpeg gateway with an EncoderInputLease. FFmpeg cannot inherit this Go client's mTLS credentials. The existing remotetranscode resolver requires private literal-IP HTTPS and cannot consume this Reader directly; that resolver and the later loopback gateway need an explicit trusted integration contract. No runtime routes, configuration defaults, Plex behavior or UI change here.

Documentation

Overview

Package nodesource transports exact source bytes on a private mTLS endpoint. It installs no routes and owns neither source Close nor encoder retirement.

Index

Constants

View Source
const CredentialHeader = "X-Ether-Source-Grant"
View Source
const Path = "/internal/source/v1/bytes"

Variables

This section is empty.

Functions

This section is empty.

Types

type Authority

type Authority interface {
	Verify(context.Context, Peer, string) (Grant, error)
}

Verify checks current placement, viewer policy and source revocation. It must bind the opaque credential to the complete scope; a certificate is not a grant.

type Client

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

func NewClient

func NewClient(o ClientOptions) (*Client, error)

func (*Client) Close

func (c *Client) Close()

func (*Client) Open

func (c *Client) Open(ctx context.Context, g Grant) (*Reader, error)

Open pins the exact immutable revision, ETag and size via an authorized HEAD.

type ClientOptions

type ClientOptions struct {
	Endpoint      string
	TLS           *tls.Config
	BindServer    func(tls.ConnectionState) error
	RecheckServer func(context.Context, tls.ConnectionState) error
	Peer          Peer
	MaxLifetime   time.Duration
	Timeout       time.Duration
	Now           func() time.Time
}

ClientOptions is trusted composition, never a public request payload. Endpoint is one fixed HTTPS origin with Path. TLS performs ordinary Go chain/hostname verification BEFORE BindServer. Peer is this client's certificate boot identity. RecheckServer is required current per-operation trust, composed with Guard. Each operation uses fresh TLS; rebuild after rotation. Callbacks and opaque signer keys must remain immutable and callbacks must honor their context.

type Grant

type Grant struct {
	Scope      Scope
	Credential string
	Expires    time.Time
}

func (Grant) GoString

func (g Grant) GoString() string

func (Grant) String

func (g Grant) String() string

type Handler

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

func NewHandler

func NewHandler(o Options) (*Handler, error)

func (*Handler) Pending

func (h *Handler) Pending(scope Scope) int

Pending returns exact-scope hold count, including cancelled/expired requests. A zero count proves only that transport holds have been relinquished, never source Close, encoder retirement or durable placement retirement.

func (*Handler) Reconcile

func (h *Handler) Reconcile() int

Reconcile is called by the host lifecycle, including after drain/expiry and when no more requests arrive. It never treats elapsed time as retirement. Pending includes active, cancelled and disconnected requests with producers. No callbacks run under registry locks. There are no background goroutines.

func (*Handler) ServeHTTP

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

type Hold

type Hold struct {
	Scope   Scope
	Source  core.MediaSource
	Release func()
}

Hold must refer to the exact acquired source object. Release relinquishes only this hold; it is NOT evidence of successful MediaSource.Close/SourceRetirement. Acquire receives a core.ReadRetirement context and must register any producers before starting them, including producers left behind on an error return. Acquire MUST atomically check current scope and the exact source lifetime sealing barrier while taking its hold. Prior Verify is not admission: a retirement barrier can seal between verification and acquisition. An error may return a nonempty Hold, which is retained until its tracker drains. Release must be bounded, nonblocking accounting, and must not perform I/O.

type Options

type Options struct {
	WatchAuthority func(string, func()) func()
	Authority      Authority
	Peer           func(*x509.Certificate) (Peer, error)
	Acquire        func(context.Context, Scope) (Hold, error)
	Now            func() time.Time
	MaxRequests    int
	MaxLifetime    time.Duration
	Revalidate     time.Duration
}

type Peer

type Peer struct{ NodeID, Boot string }

type Reader

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

Reader is safe for concurrent ReaderAt calls. Close cancels local network work. Done proves only local HTTP requests exited; neither Close nor EOF nor Done attests remote producer, source or encoder retirement. Host lifecycle must reconcile source-node holds independently, even after grant expiry.

func (*Reader) Close

func (r *Reader) Close() error

func (*Reader) Done

func (r *Reader) Done() <-chan struct{}

func (*Reader) Name

func (r *Reader) Name() string

func (*Reader) ReadAt

func (r *Reader) ReadAt(b []byte, off int64) (int, error)

func (*Reader) ReadAtContext

func (r *Reader) ReadAtContext(ctx context.Context, b []byte, off int64) (int, error)

func (*Reader) ReleaseID

func (r *Reader) ReleaseID() string

func (*Reader) Renew

func (r *Reader) Renew(ctx context.Context, authority func(context.Context, Grant) (Grant, error)) error

Renew obtains fresh authority rather than extending a raw deadline. Every Scope field and the HEAD representation must remain identical. Existing reads retain their old deadline. Renewal cannot revive an expired grant.

func (*Reader) Size

func (r *Reader) Size() int64

type Scope

type Scope struct {
	SourceGeneration uint64
	Fence            placement.Fence
	Viewer           string
	Revision         string
}

Jump to

Keyboard shortcuts

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