Help us shape the future of Go! Take the 2026 Go Developer Survey

cdn

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Oct 19, 2026 License: MIT Imports: 17 Imported by: 0

Documentation

Overview

Package cdn signs download URLs on a CDN in front of an object store (decision 0029). A blob store that has a CDN takes one of these signers in its Options and answers blob.ViaCDN with the signer's URL for the blob's object key, so the store is never wrapped and keeps its other interfaces.

Every signer issues URLs on time windows: a URL minted in a window expires when the window ends plus the TTL, so a URL lives at least the TTL and at most twice it, and every client in one window is handed the same URL for a blob when the signature is deterministic.

Index

Constants

View Source
const (
	HashSHA1   = "sha1"
	HashSHA256 = "sha256"
)

CloudFront hash algorithms for CloudFrontConfig.Hash.

View Source
const CloudCDNKeySize = 16

CloudCDNKeySize is the length of a Cloud CDN signing key: 128 bits.

View Source
const CloudFrontMaxSize int64 = 50_000_000_000

CloudFrontMaxSize is the largest GET response CloudFront caches: AWS lists "Maximum cacheable file size per HTTP GET response" as 50 GB. Artifactory answered a larger file requested through CloudFront with 400 until 7.104.5 (RTDEV-49674), so a redirect sends such a file to the object store instead. The decimal reading of 50 GB is the smaller one, so no file over the limit is sent to the edge whichever unit AWS means.

Variables

View Source
var ErrConfig = errors.New("cdn: invalid configuration")

ErrConfig reports an unusable CDN configuration.

Functions

func Expiry

func Expiry(now time.Time, ttl time.Duration) (time.Time, error)

Expiry is when a URL issued at now with ttl expires: the end of the current window plus ttl, where windows are ttl long and start on a multiple of ttl since the Unix epoch. Whole seconds, because every CDN expresses expiry in epoch seconds.

func ParseCloudCDNKey

func ParseCloudCDNKey(file []byte) ([]byte, error)

ParseCloudCDNKey decodes a Cloud CDN key file: base64url, with or without padding, around 16 raw bytes.

func ParseDomain

func ParseDomain(domain string) (*url.URL, error)

ParseDomain reads a CDN domain: a host such as "d111.cloudfront.net", which means https, or an http or https URL with no path, such as "http://localhost:8080" for a test edge.

func ParsePrivateKey

func ParsePrivateKey(pemBytes []byte) (crypto.Signer, error)

ParsePrivateKey reads a PEM RSA or ECDSA private key in any of the forms AWS and OpenSSL write: PKCS#1, SEC 1 or PKCS#8.

func SignCloudCDN

func SignCloudCDN(rawURL, keyName string, key []byte, expires time.Time) string

SignCloudCDN signs rawURL as Google's documented algorithm does: append Expires and KeyName, take the HMAC-SHA1 of the whole URL with the raw key, and append it as a padded base64url Signature. Any query the URL already has, such as the response overrides, is part of what is signed.

func Window

func Window(now time.Time, ttl time.Duration) (start, expiry time.Time, err error)

Window returns the window now falls in for ttl and the expiry of a URL issued in it, as Expiry does: windows are ttl long, start on a multiple of ttl since the Unix epoch, and a URL issued in one expires at its end plus ttl. A signer that fixes its start time to the window start, as an Azure SAS does, then issues the same URL for a blob throughout the window.

Types

type CloudCDN

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

CloudCDN signs URLs for a Cloud CDN backend bucket. It signs each URL whole rather than a URLPrefix: a prefix signature would open every blob under the prefix to whoever holds one URL.

Cloud CDN does not refuse unsigned requests; the bucket must be private, readable only by the cloud-cdn-fill service account, so that the origin refuses them (decision 0029).

func NewCloudCDN

func NewCloudCDN(c CloudCDNConfig) (*CloudCDN, error)

NewCloudCDN returns a Cloud CDN signer.

func (*CloudCDN) Covers

func (c *CloudCDN) Covers(storePrefix string) error

Covers checks the load balancer's path reaches every key under storePrefix.

func (*CloudCDN) Provider

func (*CloudCDN) Provider() string

Provider names the CDN.

func (*CloudCDN) Sign

func (c *CloudCDN) Sign(objectKey string, r Request) (string, error)

Sign returns a signed URL for objectKey.

type CloudCDNConfig

type CloudCDNConfig struct {
	// Domain is the load balancer host (see ParseDomain).
	Domain string
	// KeyName names the key on the backend bucket.
	KeyName string
	// Key is the key file's contents: 128 random bits, base64url, as
	// "gcloud compute backend-buckets add-signed-url-key" reads them.
	Key []byte
	// PathPrefix is the path inside the bucket that the load balancer maps
	// to its root; empty when it serves the bucket root.
	PathPrefix string
	// Now is the clock; nil means time.Now.
	Now func() time.Time
}

CloudCDNConfig configures a Cloud CDN signer.

type CloudFront

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

CloudFront signs canned-policy URLs for a CloudFront distribution. The distribution's cache policy must key on the path plus response-content-disposition and response-content-type only: never the signature parameters, or every URL would be a cache miss, and always the overrides, or one item would be served with another's filename.

func NewCloudFront

func NewCloudFront(c CloudFrontConfig) (*CloudFront, error)

NewCloudFront returns a CloudFront signer.

func (*CloudFront) Covers

func (c *CloudFront) Covers(storePrefix string) error

Covers checks the distribution's origin reaches every key under storePrefix.

func (*CloudFront) Provider

func (*CloudFront) Provider() string

Provider names the CDN.

func (*CloudFront) Sign

func (c *CloudFront) Sign(objectKey string, r Request) (string, error)

Sign returns a canned-policy signed URL for objectKey.

type CloudFrontConfig

type CloudFrontConfig struct {
	// Domain is the distribution host (see ParseDomain).
	Domain string
	// KeyPairID is the ID of the public key, in one of the distribution's
	// trusted key groups, that matches PrivateKey.
	KeyPairID string
	// PrivateKey is the PEM private key: RSA as PKCS#1 or PKCS#8, or ECDSA
	// as SEC 1 or PKCS#8.
	PrivateKey []byte
	// Hash is HashSHA1 (the default) or HashSHA256.
	Hash string
	// PathPrefix is the distribution origin's path inside the bucket; empty
	// when the origin is the bucket root.
	PathPrefix string
	// Now is the clock; nil means time.Now.
	Now func() time.Time
}

CloudFrontConfig configures a CloudFront signer.

type FrontDoor

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

FrontDoor places read SAS URLs on an Azure Front Door endpoint (decision 0029). Front Door checks no signature of its own: it forwards the request, query string included, to the storage origin, which checks the SAS. So FrontDoor signs nothing and is not a Signer: the azure store mints a window-aligned SAS with its own credentials, which may need a network call for a user delegation key, and FrontDoor moves it onto the endpoint.

The route must key its cache on the full query string (query_string_caching_behavior = UseQueryString), or a cached private blob is served to anyone who asks for its path, and must cap cache expiry at the SAS window, because Front Door keeps serving a cached object after its SAS has expired.

func NewFrontDoor

func NewFrontDoor(c FrontDoorConfig) (*FrontDoor, error)

NewFrontDoor returns a FrontDoor.

func (*FrontDoor) Covers

func (f *FrontDoor) Covers(storagePrefix string) error

Covers checks the endpoint reaches every blob under storagePrefix, the store's "<container>/<prefix>".

func (*FrontDoor) Provider

func (*FrontDoor) Provider() string

Provider names the CDN.

func (*FrontDoor) URL

func (f *FrontDoor) URL(storagePath, sasQuery string) (string, error)

URL returns the endpoint URL for the blob at storagePath, "<container>/<blob name>", carrying sasQuery, the SAS's encoded query string, unchanged: the origin checks the signature over the storage path, which the edge forwards as it is.

type FrontDoorConfig

type FrontDoorConfig struct {
	// Endpoint is the Front Door endpoint host, such as
	// "artifacts-abc123.z01.azurefd.net" (see ParseDomain).
	Endpoint string
	// PathPrefix is the route's origin path: the leading part of
	// "<container>/<blob name>" that the endpoint leaves out, for example the
	// container when the origin path is "/<container>". Empty when the
	// endpoint path is the whole storage path.
	PathPrefix string
}

FrontDoorConfig configures a FrontDoor.

type Request

type Request struct {
	// TTL is the least time the URL stays valid once handed out.
	TTL time.Duration
	// Filename and ContentType, when set, travel as response overrides the
	// CDN passes to the origin and keys its cache on.
	Filename    string
	ContentType string
}

Request describes one signed URL.

type Signer

type Signer interface {
	// Provider names the CDN for logs and errors, for example "cloudfront".
	Provider() string
	// Covers returns an error unless every object key under storePrefix
	// has a path on the CDN: a CDN whose origin is a folder of the bucket
	// reaches only the keys inside it.
	Covers(storePrefix string) error
	// Sign returns a URL for objectKey, the key under the bucket's root.
	Sign(objectKey string, r Request) (string, error)
}

Signer signs URLs for objects behind one CDN distribution.

Directories

Path Synopsis
Package cdntest is a fake CDN edge for tests (decision 0029).
Package cdntest is a fake CDN edge for tests (decision 0029).

Jump to

Keyboard shortcuts

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