vod

package
v0.0.54 Latest Latest
Warning

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

Go to latest
Published: May 4, 2026 License: MIT Imports: 9 Imported by: 0

Documentation

Overview

Package vod implements the VOD mount registry.

A VOD mount maps a logical name to a host filesystem directory. The system does not maintain a file index — file lookups (resolve a URL to an absolute path) and listings (enumerate files for the UI) are answered live against the host filesystem.

Ingest URLs reference files via file://<mount>/<relative/path>; only files inside a registered mount can be played. Bare host paths and absolute file:// URLs are rejected — the mount layer is the single point of policy.

Index

Constants

This section is empty.

Variables

View Source
var ErrMountNotFound = errors.New("vod: mount not found")

ErrMountNotFound is returned when a URL references a mount that has not been registered.

View Source
var ErrNotFileURL = errors.New("vod: not a file:// url")

ErrNotFileURL is returned when Resolve is called with a URL whose scheme is not file://.

View Source
var ErrPathEscapesMount = errors.New("vod: path escapes mount root")

ErrPathEscapesMount is returned when a resolved path falls outside its mount's storage root. This protects against ../ traversal in user-supplied URLs.

Functions

func IsVideoFile

func IsVideoFile(name string) bool

IsVideoFile reports whether name has a known video extension.

Types

type FileEntry

type FileEntry struct {
	Name      string `json:"name"`
	Path      string `json:"path"` // path relative to the mount root, with forward slashes
	Size      int64  `json:"size"`
	IsDir     bool   `json:"is_dir"`
	ModTime   int64  `json:"mod_time_unix"`
	PlayURL   string `json:"play_url,omitempty"`
	IngestURL string `json:"ingest_url,omitempty"`
}

FileEntry describes a single entry returned by ListFiles. Size is zero for directories. Empty for directories:

  • PlayURL: HTTP path the browser hits to stream the file (Range-aware).
  • IngestURL: the file:// URL that an ingestor stream input accepts.

type Registry

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

Registry holds the active mount table and answers Resolve / ListFiles queries. It is safe for concurrent use.

func NewRegistry

func NewRegistry() *Registry

NewRegistry returns an empty Registry.

func (*Registry) ListFiles

func (r *Registry) ListFiles(name domain.VODName, subPath string) ([]FileEntry, error)

ListFiles enumerates the contents of subPath inside mount name. subPath is interpreted with the same rules as Resolve (must stay inside the mount root). Pass "" or "/" to list the mount root.

Only directories and files with a known video extension are returned — sidecar files (subtitles, JSON metadata, dotfiles…) are hidden because the ingestor cannot play them. Each video file carries a PlayURL the client can hand back to the ingestor as-is.

Listing is non-recursive: one directory level at a time, sorted by name. Returns ErrMountNotFound when the mount is unknown, ErrPathEscapesMount when subPath tries to traverse outside the mount, or a wrapped os error when the underlying filesystem read fails.

func (*Registry) Names

func (r *Registry) Names() []domain.VODName

Names returns a sorted snapshot of the registered mount names. For diagnostics.

func (*Registry) Resolve

func (r *Registry) Resolve(rawURL string) (path string, loop bool, err error)

Resolve maps a file:// URL to an absolute filesystem path inside a mount.

Accepts URLs of the form:

file://<mount>/path/to/file.mp4[?loop=true|false]

Loop default is TRUE — file:// inputs replay from the beginning when they reach EOF, treating the file as a continuous stream source. Operators who want one-shot playback must opt out with `?loop=false`. Rationale: in a streaming server, a file is almost always used as a fallback / standby / test source where unattended end-of-file means the stream is silently dead, which is rarely intended.

Rejects bare paths, file:///absolute paths, and URLs whose host is not a registered mount. Also rejects resolved paths that escape the mount root (lexical check after Clean — symlink walks are intentionally not followed, since admins control both the mount table and the storage tree).

func (*Registry) ResolvePath

func (r *Registry) ResolvePath(name domain.VODName, subPath string) (string, error)

ResolvePath maps (mount name + relative subPath) to an absolute filesystem path inside the mount, applying the same traversal protection as Resolve. Used by the HTTP raw-file handler that serves files directly to browsers.

func (*Registry) Storage

func (r *Registry) Storage(name domain.VODName) (string, bool)

Storage returns the absolute storage path registered for name, or false if the mount is not registered.

func (*Registry) Sync

func (r *Registry) Sync(mounts []*domain.VODMount)

Sync replaces the mount table with the given list. Invalid entries (empty name, non-absolute storage) are skipped silently — validation belongs to the API layer; here we just refuse to install a broken mount that would later fail to resolve anyway.

Jump to

Keyboard shortcuts

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