Something went wrong. Try again.
This repository has no description
Something went wrong. Try again.
3.4 kB · 89 lines
Go
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990// Package cdn defines the seam between streamplace and whatever CDN an// operator puts in front of the VOD blob store. Two capabilities are// provider-specific and everything else is not://// - Signer: how a blob URL in an HLS playlist gets signed so the CDN// only serves what this node handed out. Every CDN has its own// recipe (bunny is an HMAC in the query string, CloudFront is a// signed policy, Cloudflare is whatever your worker verifies).//// - LogSource: where the CDN's archived access logs live and how a// line decodes. Once the CDN serves segments, the node no longer// sees segment requests, so view counting depends on pulling them// back out of the CDN's logs (see pkg/viewlog RunIngest).//// Providers live in subpackages (pkg/cdn/bunny) and are selected by// --vod-cdn-provider via pkg/cdn/providers.FromConfig. The generic// --vod-cdn-url flag keeps working on its own as an unsigned, log-less// static CDN.package cdn
import ( "context" "net/url" "time")
// Signer produces the viewer-facing URL for a blob served by the CDN.type Signer interface { // SignURL returns the URL a player should fetch for u, valid until // expires. Implementations must not mutate u. Unsigned providers // return u.String(). SignURL(u *url.URL, expires time.Time) string}
// Static is the no-signature Signer: a plain CDN over a public bucket.type Static struct{}
func (Static) SignURL(u *url.URL, _ time.Time) string { return u.String() }
// Part is one immutable archived access-log file at the provider.type Part struct { // ID is the provider-unique, stable identity of the part (e.g. // its storage path). Ingest cursors key on it, so it must not // change between listings. ID string // Day is the UTC date the provider filed the part under. Events // inside are at or after this day's start; the ingester uses it // to skip parts older than its lookback. Day time.Time // Size is the compressed byte length, for logging. Size int64}
// Request is one CDN access-log record in provider-neutral shape.// Only the fields view counting needs are carried.type Request struct { // Time is when the edge served the request. Time time.Time // Status is the HTTP status the edge returned. Status int // BytesSent is the response body size the edge reports. Access // logs carry no Range header, so this is the only byte signal. BytesSent int64 // RemoteIP is the viewer's address, hashed by the ingester before // it's persisted. RemoteIP string // URL is what the viewer requested: a path plus query string, or // an absolute URL (providers differ; consumers must parse). URL string}
// LogSource lists and decodes a provider's archived access logs.type LogSource interface { // ListParts returns every part filed on or after `since`'s UTC // date. Parts already ingested are filtered by the caller. ListParts(ctx context.Context, since time.Time) ([]Part, error) // ReadPart streams the part's records to emit in file order. An // error from emit aborts the read and is returned. ReadPart(ctx context.Context, part Part, emit func(Request) error) error}
// Provider bundles what the configured CDN can do. Logs is nil when// the provider has no log source configured.type Provider struct { // Name is the --vod-cdn-provider value ("" for a plain static CDN). Name string Signer Signer Logs LogSource}