Documentation
¶
Overview ¶
Package sites owns site naming, metadata and manifests stored in the blob store (SPEC §7.2, §9).
Index ¶
- Constants
- Variables
- func ChoosePreview(ogImage string, files []ManifestFile) string
- func ManifestKey(site string) string
- func MetaKey(site string) string
- func PreviewType(p string) string
- func ResolvePreviewRef(ref string) (string, bool)
- func SiteKey(site, path string) string
- func UploadKey(site, id, name string) string
- func ValidateName(name string, reserved []string) error
- type Manifest
- type ManifestFile
- type Meta
- type Page
- type Registry
- func (r *Registry) Config() *config.Config
- func (r *Registry) Delete(ctx context.Context, name string) error
- func (r *Registry) Exists(ctx context.Context, name string) (bool, error)
- func (r *Registry) FileDigest(ctx context.Context, site, path string) (*ManifestFile, error)
- func (r *Registry) Files(ctx context.Context, name string) ([]blob.ObjectInfo, error)
- func (r *Registry) Get(ctx context.Context, name string) (*Meta, error)
- func (r *Registry) GetManifest(ctx context.Context, name string) (*Manifest, error)
- func (r *Registry) GetMeta(ctx context.Context, name string) (*Meta, error)
- func (r *Registry) List(ctx context.Context) ([]Meta, error)
- func (r *Registry) PutManifest(ctx context.Context, m *Manifest) error
- func (r *Registry) PutMeta(ctx context.Context, m *Meta) error
- func (r *Registry) Refresh(ctx context.Context, name, actor string) (*Meta, error)
- func (r *Registry) Store() blob.Store
Constants ¶
const ( // TitleScanBytes is how much of an index.html is inspected for its // title, description and og:image. TitleScanBytes = 64 << 10 // IndexFile is the site-relative path whose <title> describes the site // (ExtractPage). IndexFile = "index.html" )
const ( SitesPrefix = "sites/" MetaPrefix = "_meta/sites/" ManifestPrefix = "_meta/manifests/" UploadsPrefix = "uploads/" )
Blob key prefixes (relative to the storage prefix).
const MaxPreviewBytes = 1 << 20
MaxPreviewBytes is the largest file that can be a preview.
const PreviewCSP = "sandbox; default-src 'none'; img-src data:; style-src 'unsafe-inline'"
PreviewCSP is the Content-Security-Policy of a served preview: an SVG on the hub's origin must never run script or load anything, and a navigation to it stays sandboxed.
Variables ¶
var ( // ErrNotFound: the site does not exist. ErrNotFound = errors.New("sites: not found") // ErrInvalidName: name fails the pattern or is reserved. ErrInvalidName = errors.New("sites: invalid site name") )
var ErrCorrupt = errors.New("sites: corrupt metadata")
ErrCorrupt is returned (wrapped) when a stored meta document or manifest cannot be decoded or exceeds its size bound. List and Get then fall back to metadata synthesized from the object listing, GetManifest to an empty manifest and Refresh rebuilds both; GetMeta reports it so that authorization checks can fail closed.
var PreviewNames = []string{
"preview.png", "preview.jpg", "preview.jpeg", "preview.webp",
"preview.avif", "preview.gif", "preview.svg",
}
PreviewNames are the root files tried, in order, when the og:image of index.html is missing or unusable.
var PreviewTypes = map[string]string{
"png": "image/png",
"jpg": "image/jpeg",
"jpeg": "image/jpeg",
"gif": "image/gif",
"webp": "image/webp",
"avif": "image/avif",
"svg": "image/svg+xml",
}
PreviewTypes maps the (lowercased) extensions a preview may have, without the dot, to the Content-Type it is served with.
Functions ¶
func ChoosePreview ¶ added in v0.3.0
func ChoosePreview(ogImage string, files []ManifestFile) string
ChoosePreview returns the preview of a site that holds files (its manifest entries after a write): ogImage, the og:image reference of its root index.html ("" when none), when it resolves to one of files with a PreviewTypes extension and at most MaxPreviewBytes; else the first of PreviewNames among files within that size; else "".
func ManifestKey ¶
ManifestKey returns the blob key of a site's manifest.
func PreviewType ¶ added in v0.3.0
PreviewType returns the Content-Type of a preview path by its extension, or "" when the extension is not one of PreviewTypes.
func ResolvePreviewRef ¶ added in v0.3.0
ResolvePreviewRef turns the og:image reference of a site's root index.html into a site path. It accepts only references to the site's own files: relative ("img/a.png", "./a.png") or site-root relative ("/a.png"), without a query or fragment. It refuses references that are empty or longer than 1024 bytes, have a URL scheme, start with "//" or contain "\", have an invalid percent escape, or decode to something with a control character, invalid UTF-8, or an empty, ".", ".." or dot-prefixed segment.
func ValidateName ¶
ValidateName checks a site name against the DNS-label pattern and the reserved list.
Types ¶
type Manifest ¶
type Manifest struct {
Site string `json:"site"`
UpdatedAt time.Time `json:"updated_at"`
Files []ManifestFile `json:"files"`
}
Manifest records the content hashes of the last API deploy/refresh.
type ManifestFile ¶
type ManifestFile struct {
Path string `json:"path"`
Size int64 `json:"size"`
SHA256 string `json:"sha256"`
ETag string `json:"etag"` // storage etag observed after upload
}
ManifestFile is one entry of a site manifest.
type Meta ¶
type Meta struct {
Name string `json:"name"`
URL string `json:"url"`
Title string `json:"title,omitempty"`
Description string `json:"description,omitempty"`
Preview string `json:"preview,omitempty"` // site path of the preview image (preview.go)
CreatedAt time.Time `json:"created_at"`
CreatedBy string `json:"created_by,omitempty"`
UpdatedAt time.Time `json:"updated_at"`
UpdatedBy string `json:"updated_by,omitempty"`
DeployID string `json:"deploy_id,omitempty"`
FileCount int `json:"file_count"`
Bytes int64 `json:"bytes"`
Owners []string `json:"owners"`
}
Meta is the public description of a site (SiteMeta in the spec).
type Page ¶ added in v0.3.0
type Page struct {
Title string // <title> text
Description string // <meta name="description"> content
// Image is the og:image reference, entity-decoded and trimmed but not
// resolved (ResolvePreviewRef, ChoosePreview).
Image string
}
Page is what a site's root index.html says about the site (SPEC §7.2).
func ExtractPage ¶ added in v0.3.0
ExtractPage returns the <title> text, the <meta name="description"> content and the og:image reference of an HTML document (best effort; only the first 64 KiB are considered). The og:image is the content of the first <meta> whose property attribute, or without one its name attribute, is "og:image" (ASCII case-insensitive, trimmed).
The scan is tolerant of malformed markup: comments and the contents of script/style/svg/template elements are skipped, entities are decoded and whitespace is collapsed. Title and description are capped at a sensible length.
type Registry ¶
type Registry struct {
// contains filtered or unexported fields
}
Registry reads and writes site metadata in the blob store.
func NewRegistry ¶
NewRegistry returns a registry over store.
func (*Registry) Delete ¶
Delete removes a site's files, uploads, meta and manifest. The meta document goes last so an interrupted delete can be retried.
func (*Registry) Exists ¶
Exists reports whether any object exists under sites/<name>/ or a meta file exists.
func (*Registry) FileDigest ¶
FileDigest returns the manifest entry of the object currently stored for path in site: its size, SHA-256 and etag, where the digest is always that of the bytes the etag identifies. It uses a digest the storage service verified itself when the store reports one (blob.DigestReporter, e.g. S3 objects uploaded with x-amz-checksum-sha256) and otherwise reads and hashes the object. A missing object yields an error wrapping blob.ErrNotFound.
func (*Registry) Files ¶
Files lists the objects of a site with keys made site-relative (no "sites/<name>/" prefix). "Directory marker" objects (keys ending in "/") are omitted.
func (*Registry) Get ¶
Get returns a site's metadata or ErrNotFound. For sites synced directly to storage without a meta file, a Meta is synthesized from the object listing.
func (*Registry) GetManifest ¶
GetManifest returns the manifest, or an empty manifest when none exists. A corrupt manifest is treated as missing: it only caches digests, so the next deploy re-uploads every file once and writes a fresh one.
func (*Registry) GetMeta ¶
GetMeta returns the stored meta document of a site, without synthesizing one from the object listing. It returns ErrNotFound when none exists and an error matching ErrCorrupt when it cannot be decoded.
func (*Registry) List ¶
List returns all sites: meta files ∪ first-level prefixes under sites/, sorted by UpdatedAt descending (then name).
func (*Registry) PutManifest ¶
PutManifest writes a site's manifest.
func (*Registry) Refresh ¶
Refresh rebuilds the manifest (sha256 of every file) and meta from storage after a direct sync; actor becomes UpdatedBy (and CreatedBy/owner if new).
CreatedAt, CreatedBy and Owners of an existing meta document are kept. When the site is new and sites.ownership is "owner", a non-anonymous actor becomes its first owner.
Directories
¶
| Path | Synopsis |
|---|---|
|
Package sitestest provides test helpers for code built on the sites registry and the deploy gateway: an in-memory blob.Store with optional presigned uploads served by an http.Handler.
|
Package sitestest provides test helpers for code built on the sites registry and the deploy gateway: an in-memory blob.Store with optional presigned uploads served by an http.Handler. |