Documentation
¶
Index ¶
- Constants
- Variables
- func AddProblem(manifest *Manifest, pathName, format string, args ...any) error
- func ApplyHeaderRules(manifest *Manifest, url *url.URL) (headers http.Header, err error)
- func ApplyTarPatch(manifest *Manifest, reader io.Reader, parents CreateParentsMode) error
- func AuditEventProcessor(command string, args []string) (http.Handler, error)
- func AuditRecordJSON(record *AuditRecord, scope AuditRecordScope) []byte
- func AuthorizeBranch(branch string, auth *Authorization) error
- func AuthorizeRepository(repoURL string, auth *Authorization) error
- func CheckForbiddenDomain(r *http.Request) error
- func CollectHeadersFile(manifest *Manifest) string
- func CollectRedirectsFile(manifest *Manifest) string
- func CollectTar(context context.Context, writer io.Writer, manifest *Manifest, ...) (err error)
- func CompareManifest(left *Manifest, right *Manifest) bool
- func CompressFiles(ctx context.Context, manifest *Manifest)
- func DetectContentType(manifest *Manifest)
- func EncodeAuditRecord(record *AuditRecord) (data []byte)
- func EncodeManifest(manifest *Manifest) (data []byte)
- func EnsureLeadingDirectories(manifest *Manifest)
- func ExpandSymlinks(manifest *Manifest, inPath string) (string, error)
- func ExtractAuditRecord(ctx context.Context, id AuditID, record *AuditRecord, dest string) error
- func FileLock(file *os.File) error
- func FileUnlock(file *os.File) error
- func FiniObservability()
- func GetHost(r *http.Request) (string, error)
- func GetProblemReport(manifest *Manifest) []string
- func GetProjectName(r *http.Request) (string, error)
- func InitObservability()
- func Is3xxHTTPStatus(status int) bool
- func IsAllowedCustomHeader(header string) bool
- func IsManifestEmpty(manifest *Manifest) bool
- func IsUnauthorized(err error) bool
- func IsValidProjectName(name string) bool
- func LintRedirects(manifest *Manifest)
- func Main()
- func ManifestJSON(manifest *Manifest) []byte
- func ObserveData(ctx context.Context, data ...any)
- func ObserveError(err error)
- func ObserveFunction(ctx context.Context, funcName string, data ...any) (interface{ ... }, context.Context)
- func ObserveHTTPHandler(handler http.Handler) http.Handler
- func OnReload(handler func())
- func PrepareManifest(ctx context.Context, manifest *Manifest) error
- func PrintConfigEnvVars()
- func ProcessHeadersFile(manifest *Manifest) error
- func ProcessRedirectsFile(manifest *Manifest) error
- func ReadAtMost(reader io.Reader, count int64, err error) io.Reader
- func RunMigration(ctx context.Context, name string) error
- func ServeCaddy(w http.ResponseWriter, r *http.Request)
- func ServePages(w http.ResponseWriter, r *http.Request)
- func TraceGarbage(ctx context.Context) error
- func WaitForInterrupt()
- func WithPrincipal(ctx context.Context) context.Context
- type AuditConfig
- type AuditEvent
- type AuditID
- type AuditRecord
- func (record *AuditRecord) DescribePrincipal() string
- func (record *AuditRecord) DescribeResource() string
- func (*AuditRecord) Descriptor() ([]byte, []int)deprecated
- func (record *AuditRecord) GetAuditID() AuditID
- func (x *AuditRecord) GetDomain() string
- func (x *AuditRecord) GetEvent() AuditEvent
- func (x *AuditRecord) GetId() int64
- func (x *AuditRecord) GetManifest() *Manifest
- func (x *AuditRecord) GetPrincipal() *Principal
- func (x *AuditRecord) GetProject() string
- func (x *AuditRecord) GetTimestamp() *timestamppb.Timestamp
- func (*AuditRecord) ProtoMessage()
- func (x *AuditRecord) ProtoReflect() protoreflect.Message
- func (x *AuditRecord) Reset()
- func (x *AuditRecord) String() string
- type AuditRecordScope
- type AuthError
- type Authorization
- type Backend
- type BackendFeature
- type BlobMetadata
- type BoundedReader
- type CacheConfig
- type CachedBlob
- type CachedManifest
- type Config
- type CreateParentsMode
- type Duration
- type Entry
- func (*Entry) Descriptor() ([]byte, []int)deprecated
- func (x *Entry) GetCompressedSize() int64
- func (x *Entry) GetContentType() string
- func (x *Entry) GetData() []byte
- func (x *Entry) GetGitHash() string
- func (x *Entry) GetOriginalSize() int64
- func (x *Entry) GetTransform() Transform
- func (x *Entry) GetType() Type
- func (*Entry) ProtoMessage()
- func (x *Entry) ProtoReflect() protoreflect.Message
- func (x *Entry) Reset()
- func (x *Entry) String() string
- type FSBackend
- func (fs *FSBackend) AppendAuditLog(ctx context.Context, id AuditID, record *AuditRecord) error
- func (fs *FSBackend) Backend() Backend
- func (fs *FSBackend) CheckDomain(ctx context.Context, domain string) (bool, error)
- func (fs *FSBackend) CommitManifest(ctx context.Context, name string, manifest *Manifest, ...) error
- func (fs *FSBackend) CreateDomain(ctx context.Context, domain string) error
- func (fs *FSBackend) DeleteBlob(ctx context.Context, name string) error
- func (fs *FSBackend) DeleteManifest(ctx context.Context, name string, opts ModifyManifestOptions) error
- func (fs *FSBackend) EnableFeature(ctx context.Context, feature BackendFeature) error
- func (fs *FSBackend) EnumerateBlobs(ctx context.Context) iter.Seq2[BlobMetadata, error]
- func (fs *FSBackend) EnumerateManifests(ctx context.Context) iter.Seq2[ManifestMetadata, error]
- func (fs *FSBackend) FreezeDomain(ctx context.Context, domain string) error
- func (fs *FSBackend) GetBlob(ctx context.Context, name string) (reader io.ReadSeeker, metadata BlobMetadata, err error)
- func (fs *FSBackend) GetManifest(ctx context.Context, name string, opts GetManifestOptions) (manifest *Manifest, metadata ManifestMetadata, err error)
- func (fs *FSBackend) HasAtomicCAS(ctx context.Context) bool
- func (fs *FSBackend) HasFeature(ctx context.Context, feature BackendFeature) bool
- func (fs *FSBackend) PutBlob(ctx context.Context, name string, data []byte) error
- func (fs *FSBackend) QueryAuditLog(ctx context.Context, id AuditID) (*AuditRecord, error)
- func (fs *FSBackend) SearchAuditLog(ctx context.Context, opts SearchAuditLogOptions) iter.Seq2[AuditID, error]
- func (fs *FSBackend) StageManifest(ctx context.Context, manifest *Manifest) error
- func (fs *FSBackend) UnfreezeDomain(ctx context.Context, domain string) error
- type FSConfig
- type FallbackConfig
- type Flusher
- type GetManifestOptions
- type HTTPContentTypes
- type HTTPEncodings
- type Header
- type HeaderRule
- type LimitsConfig
- type Manifest
- func DecodeManifest(data []byte) (manifest *Manifest, err error)
- func ExtractGzip(ctx context.Context, reader io.Reader, ...) (*Manifest, error)
- func ExtractTar(ctx context.Context, reader io.Reader, oldManifest *Manifest) (*Manifest, error)
- func ExtractZip(ctx context.Context, reader io.Reader, oldManifest *Manifest) (*Manifest, error)
- func ExtractZstd(ctx context.Context, reader io.Reader, ...) (*Manifest, error)
- func FetchRepository(ctx context.Context, repoURL string, branch string, oldManifest *Manifest) (*Manifest, error)
- func NewManifest() *Manifest
- func StoreManifest(ctx context.Context, name string, manifest *Manifest, ...) (*Manifest, error)
- func (*Manifest) Descriptor() ([]byte, []int)deprecated
- func (x *Manifest) GetBranch() string
- func (x *Manifest) GetCommit() string
- func (x *Manifest) GetCompressedSize() int64
- func (x *Manifest) GetContents() map[string]*Entry
- func (x *Manifest) GetHeaders() []*HeaderRule
- func (x *Manifest) GetOriginalSize() int64
- func (x *Manifest) GetProblems() []*Problem
- func (x *Manifest) GetRedirects() []*RedirectRule
- func (x *Manifest) GetRepoUrl() string
- func (x *Manifest) GetStoredSize() int64
- func (*Manifest) ProtoMessage()
- func (x *Manifest) ProtoReflect() protoreflect.Message
- func (x *Manifest) Reset()
- func (x *Manifest) String() string
- type ManifestMetadata
- type ModifyManifestOptions
- type ObservabilityConfig
- type Principal
- type Problem
- type RedirectKind
- type RedirectRule
- func (*RedirectRule) Descriptor() ([]byte, []int)deprecated
- func (x *RedirectRule) GetForce() bool
- func (x *RedirectRule) GetFrom() string
- func (x *RedirectRule) GetStatus() uint32
- func (x *RedirectRule) GetTo() string
- func (*RedirectRule) ProtoMessage()
- func (x *RedirectRule) ProtoReflect() protoreflect.Message
- func (x *RedirectRule) Reset()
- func (x *RedirectRule) String() string
- type S3Backend
- func (s3 *S3Backend) AppendAuditLog(ctx context.Context, id AuditID, record *AuditRecord) error
- func (s3 *S3Backend) Backend() Backend
- func (s3 *S3Backend) CheckDomain(ctx context.Context, domain string) (exists bool, err error)
- func (s3 *S3Backend) CommitManifest(ctx context.Context, name string, manifest *Manifest, ...) error
- func (s3 *S3Backend) CreateDomain(ctx context.Context, domain string) error
- func (s3 *S3Backend) DeleteBlob(ctx context.Context, name string) error
- func (s3 *S3Backend) DeleteManifest(ctx context.Context, name string, opts ModifyManifestOptions) error
- func (s3 *S3Backend) EnableFeature(ctx context.Context, feature BackendFeature) error
- func (s3 *S3Backend) EnumerateBlobs(ctx context.Context) iter.Seq2[BlobMetadata, error]
- func (s3 *S3Backend) EnumerateManifests(ctx context.Context) iter.Seq2[ManifestMetadata, error]
- func (s3 *S3Backend) FreezeDomain(ctx context.Context, domain string) error
- func (s3 *S3Backend) GetBlob(ctx context.Context, name string) (reader io.ReadSeeker, metadata BlobMetadata, err error)
- func (s3 *S3Backend) GetManifest(ctx context.Context, name string, opts GetManifestOptions) (manifest *Manifest, metadata ManifestMetadata, err error)
- func (s3 *S3Backend) HasAtomicCAS(ctx context.Context) bool
- func (s3 *S3Backend) HasFeature(ctx context.Context, feature BackendFeature) bool
- func (s3 *S3Backend) PutBlob(ctx context.Context, name string, data []byte) error
- func (s3 *S3Backend) QueryAuditLog(ctx context.Context, id AuditID) (*AuditRecord, error)
- func (s3 *S3Backend) SearchAuditLog(ctx context.Context, opts SearchAuditLogOptions) iter.Seq2[AuditID, error]
- func (s3 *S3Backend) StageManifest(ctx context.Context, manifest *Manifest) error
- func (s3 *S3Backend) UnfreezeDomain(ctx context.Context, domain string) error
- type S3Config
- type SearchAuditLogOptions
- type SearchAuditLogResult
- type ServerConfig
- type StorageConfig
- type Transform
- type Type
- type URL
- type UnresolvedRefError
- type UpdateOutcome
- type UpdateResult
- func PartialUpdateFromArchive(ctx context.Context, webRoot string, contentType string, reader io.Reader, ...) (result UpdateResult)
- func Update(ctx context.Context, webRoot string, oldManifest, newManifest *Manifest, ...) UpdateResult
- func UpdateFromArchive(ctx context.Context, webRoot string, contentType string, reader io.Reader) (result UpdateResult)
- func UpdateFromRepository(ctx context.Context, webRoot string, repoURL string, branch string) (result UpdateResult)
- type WildcardConfig
- type WildcardPattern
Constants ¶
const BlobReferencePrefix = "/git/blobs/"
const HeadersFileName string = "_headers"
const RedirectsFileName string = "_redirects"
Variables ¶
var ( Type_name = map[int32]string{ 0: "InvalidEntry", 1: "Directory", 2: "InlineFile", 3: "ExternalFile", 4: "Symlink", } Type_value = map[string]int32{ "InvalidEntry": 0, "Directory": 1, "InlineFile": 2, "ExternalFile": 3, "Symlink": 4, } )
Enum value maps for Type.
var ( Transform_name = map[int32]string{ 0: "Identity", 1: "Zstd", } Transform_value = map[string]int32{ "Identity": 0, "Zstd": 1, } )
Enum value maps for Transform.
var ( AuditEvent_name = map[int32]string{ 0: "InvalidEvent", 1: "CommitManifest", 2: "DeleteManifest", 3: "FreezeDomain", 4: "UnfreezeDomain", } AuditEvent_value = map[string]int32{ "InvalidEvent": 0, "CommitManifest": 1, "DeleteManifest": 2, "FreezeDomain": 3, "UnfreezeDomain": 4, } )
Enum value maps for AuditEvent.
var ErrArchiveTooLarge = errors.New("archive too large")
var ErrDomainFrozen = errors.New("domain administratively frozen")
var ErrHeaderNotAllowed = errors.New("custom header not allowed")
var ErrMalformedPatch = errors.New("malformed patch")
var ErrManifestTooLarge = errors.New("manifest too large")
var ErrObjectNotFound = errors.New("not found")
var ErrPreconditionFailed = errors.New("precondition failed")
var ErrRepositoryTooLarge = errors.New("repository too large")
var ErrSiteTooLarge = errors.New("site too large")
var ErrSymlinkLoop = errors.New("symbolic link loop")
var ErrWriteConflict = errors.New("write conflict")
var File_schema_proto protoreflect.FileDescriptor
var PrincipalKey = principalKey{}
Functions ¶
func ApplyHeaderRules ¶
func ApplyTarPatch ¶
func ApplyTarPatch(manifest *Manifest, reader io.Reader, parents CreateParentsMode) error
Mutates `manifest` according to a tar stream and the following rules:
- A character device with major 0 and minor 0 is a "whiteout marker". When placed at a given path, this path and its entire subtree (if any) are removed from the manifest.
- When a directory is placed at a given path, this path and its entire subtree (if any) are removed from the manifest and replaced with the contents of the directory.
func AuditEventProcessor ¶
func AuditRecordJSON ¶
func AuditRecordJSON(record *AuditRecord, scope AuditRecordScope) []byte
func AuthorizeBranch ¶
func AuthorizeBranch(branch string, auth *Authorization) error
The purpose of `allowRepoURLs` is to make sure that only authorized content is deployed to the site despite the fact that the non-shared-secret authorization methods allow anyone to impersonate the legitimate webhook sender. (If switching to another repository URL would be catastrophic, then so would be switching to a different branch.)
func AuthorizeRepository ¶
func AuthorizeRepository(repoURL string, auth *Authorization) error
func CheckForbiddenDomain ¶
func CollectHeadersFile ¶
func CollectRedirectsFile ¶
func CollectTar ¶
func CollectTar( context context.Context, writer io.Writer, manifest *Manifest, metadata ManifestMetadata, ) ( err error, )
Inverse of `ExtractTar`.
func CompareManifest ¶
Returns `true` if `left` and `right` contain the same files with the same types and data.
func CompressFiles ¶
Compress contents of inline files.
func DetectContentType ¶
func DetectContentType(manifest *Manifest)
Sniff content type using the same algorithm as `http.ServeContent`.
func EncodeAuditRecord ¶
func EncodeAuditRecord(record *AuditRecord) (data []byte)
func EncodeManifest ¶
func EnsureLeadingDirectories ¶ added in v0.4.0
func EnsureLeadingDirectories(manifest *Manifest)
EnsureLeadingDirectories adds directory entries for any parent directories that are implicitly referenced by files in the manifest but don't have explicit directory entries. (This can be the case if an archive is created via globs rather than including a whole directory.)
func ExtractAuditRecord ¶
This function receives `id` and `record` separately because the record itself may have its ID missing or mismatched. While this is very unlikely, using the actual primary key as the filename is more robust.
func FileUnlock ¶
func FiniObservability ¶
func FiniObservability()
func GetProblemReport ¶
func InitObservability ¶
func InitObservability()
func Is3xxHTTPStatus ¶
func IsAllowedCustomHeader ¶
func IsManifestEmpty ¶
func IsUnauthorized ¶
func IsValidProjectName ¶ added in v0.4.0
func LintRedirects ¶ added in v0.3.0
func LintRedirects(manifest *Manifest)
func ManifestJSON ¶
func ObserveData ¶
func ObserveError ¶
func ObserveError(err error)
func ObserveFunction ¶
func PrepareManifest ¶
Apply post-processing steps to the manifest. At the moment, there isn't a good way to report errors except to log them on the terminal. (Perhaps in the future they could be exposed at `.git-pages/status.txt`?)
func PrintConfigEnvVars ¶
func PrintConfigEnvVars()
func ProcessHeadersFile ¶
Parses redirects file and injects rules into the manifest.
func ProcessRedirectsFile ¶
Parses redirects file and injects rules into the manifest.
func ServeCaddy ¶
func ServeCaddy(w http.ResponseWriter, r *http.Request)
func ServePages ¶
func ServePages(w http.ResponseWriter, r *http.Request)
func TraceGarbage ¶ added in v0.3.0
func WaitForInterrupt ¶
func WaitForInterrupt()
Types ¶
type AuditConfig ¶
type AuditConfig struct {
// Globally unique machine identifier (0 to 63 inclusive).
NodeID int `toml:"node-id"`
// Whether audit reports should be stored whenever an audit event occurs.
Collect bool `toml:"collect"`
// If not empty, includes the principal's IP address in audit reports, with the value specifying
// the source of the IP address. If the value is "X-Forwarded-For", the last item of the
// corresponding header field (assumed to be comma-separated) is used. If the value is
// "RemoteAddr", the connecting host's address is used. Any other value is disallowed.
IncludeIPs string `toml:"include-ip"`
// Endpoint to notify with a `GET /<notify-url>?<id>` whenever an audit event occurs.
NotifyURL *URL `toml:"notify-url"`
}
type AuditEvent ¶
type AuditEvent int32
const ( // Invalid event. AuditEvent_InvalidEvent AuditEvent = 0 // A manifest was committed (a site was created or updated). AuditEvent_CommitManifest AuditEvent = 1 // A manifest was deleted (a site was deleted). AuditEvent_DeleteManifest AuditEvent = 2 // A domain was frozen. AuditEvent_FreezeDomain AuditEvent = 3 // A domain was thawed. AuditEvent_UnfreezeDomain AuditEvent = 4 )
func (AuditEvent) Descriptor ¶
func (AuditEvent) Descriptor() protoreflect.EnumDescriptor
func (AuditEvent) Enum ¶
func (x AuditEvent) Enum() *AuditEvent
func (AuditEvent) EnumDescriptor
deprecated
func (AuditEvent) EnumDescriptor() ([]byte, []int)
Deprecated: Use AuditEvent.Descriptor instead.
func (AuditEvent) Number ¶
func (x AuditEvent) Number() protoreflect.EnumNumber
func (AuditEvent) String ¶
func (x AuditEvent) String() string
func (AuditEvent) Type ¶
func (AuditEvent) Type() protoreflect.EnumType
type AuditID ¶
type AuditID int64
func GenerateAuditID ¶
func GenerateAuditID() AuditID
func ParseAuditID ¶
type AuditRecord ¶
type AuditRecord struct {
// Audit event metadata.
Id *int64 `protobuf:"varint,1,opt,name=id" json:"id,omitempty"`
Timestamp *timestamppb.Timestamp `protobuf:"bytes,2,opt,name=timestamp" json:"timestamp,omitempty"`
Event *AuditEvent `protobuf:"varint,3,opt,name=event,enum=AuditEvent" json:"event,omitempty"`
Principal *Principal `protobuf:"bytes,4,opt,name=principal" json:"principal,omitempty"`
// Affected resource.
Domain *string `protobuf:"bytes,10,opt,name=domain" json:"domain,omitempty"`
Project *string `protobuf:"bytes,11,opt,name=project" json:"project,omitempty"` // only for `*Manifest` events
// Snapshot of site manifest.
Manifest *Manifest `protobuf:"bytes,12,opt,name=manifest" json:"manifest,omitempty"` // only for `*Manifest` events
// contains filtered or unexported fields
}
func DecodeAuditRecord ¶
func DecodeAuditRecord(data []byte) (record *AuditRecord, err error)
func (*AuditRecord) DescribePrincipal ¶
func (record *AuditRecord) DescribePrincipal() string
func (*AuditRecord) DescribeResource ¶
func (record *AuditRecord) DescribeResource() string
func (*AuditRecord) Descriptor
deprecated
func (*AuditRecord) Descriptor() ([]byte, []int)
Deprecated: Use AuditRecord.ProtoReflect.Descriptor instead.
func (*AuditRecord) GetAuditID ¶
func (record *AuditRecord) GetAuditID() AuditID
func (*AuditRecord) GetDomain ¶
func (x *AuditRecord) GetDomain() string
func (*AuditRecord) GetEvent ¶
func (x *AuditRecord) GetEvent() AuditEvent
func (*AuditRecord) GetId ¶
func (x *AuditRecord) GetId() int64
func (*AuditRecord) GetManifest ¶
func (x *AuditRecord) GetManifest() *Manifest
func (*AuditRecord) GetPrincipal ¶
func (x *AuditRecord) GetPrincipal() *Principal
func (*AuditRecord) GetProject ¶
func (x *AuditRecord) GetProject() string
func (*AuditRecord) GetTimestamp ¶
func (x *AuditRecord) GetTimestamp() *timestamppb.Timestamp
func (*AuditRecord) ProtoMessage ¶
func (*AuditRecord) ProtoMessage()
func (*AuditRecord) ProtoReflect ¶
func (x *AuditRecord) ProtoReflect() protoreflect.Message
func (*AuditRecord) Reset ¶
func (x *AuditRecord) Reset()
func (*AuditRecord) String ¶
func (x *AuditRecord) String() string
type AuditRecordScope ¶
type AuditRecordScope int
const ( AuditRecordComplete AuditRecordScope = iota AuditRecordNoManifest )
type Authorization ¶
type Authorization struct {
// contains filtered or unexported fields
}
func AuthorizeMetadataRetrieval ¶
func AuthorizeMetadataRetrieval(r *http.Request) (*Authorization, error)
Checks whether an operation that enables enumerating site contents is allowed.
func AuthorizeUpdateFromArchive ¶
func AuthorizeUpdateFromArchive(r *http.Request) (*Authorization, error)
func AuthorizeUpdateFromRepository ¶
func AuthorizeUpdateFromRepository(r *http.Request) (*Authorization, error)
Returns `repoURLs, err` where if `err == nil` then the request is authorized to clone from any repository URL included in `repoURLs` (by case-insensitive comparison), or any URL at all if `repoURLs == nil`.
type Backend ¶
type Backend interface {
// Returns true if the feature has been enabled for this store, false otherwise.
HasFeature(ctx context.Context, feature BackendFeature) bool
// Enables the feature for this store.
EnableFeature(ctx context.Context, feature BackendFeature) error
// Retrieve a blob. Returns `reader, size, mtime, err`.
GetBlob(ctx context.Context, name string) (
reader io.ReadSeeker, metadata BlobMetadata, err error,
)
// Store a blob. If a blob called `name` already exists, this function returns `nil` without
// regards to the old or new contents. It is expected that blobs are content-addressed, i.e.
// the `name` contains a cryptographic hash of `data`, but the backend is ignorant of this.
PutBlob(ctx context.Context, name string, data []byte) error
// Delete a blob. This is an unconditional operation that can break integrity of manifests.
DeleteBlob(ctx context.Context, name string) error
// Iterate through all blobs. Whether blobs that are newly added during iteration will appear
// in the results is unspecified.
EnumerateBlobs(ctx context.Context) iter.Seq2[BlobMetadata, error]
// Retrieve a manifest.
GetManifest(ctx context.Context, name string, opts GetManifestOptions) (
manifest *Manifest, metadata ManifestMetadata, err error,
)
// Stage a manifest. This operation stores a new version of a manifest, locking any blobs
// referenced from it in place (for garbage collection purposes) but without any other side
// effects.
StageManifest(ctx context.Context, manifest *Manifest) error
// Whether a compare-and-swap operation on a manifest is truly race-free, or only best-effort
// atomic with a small but non-zero window where two requests may race where the one committing
// first will have its update lost. (Plain swap operations are always guaranteed to be atomic.)
HasAtomicCAS(ctx context.Context) bool
// Commit a manifest. This is an atomic operation; `GetManifest` calls will return either
// the old version or the new version of the manifest, never anything else.
CommitManifest(ctx context.Context, name string, manifest *Manifest, opts ModifyManifestOptions) error
// Delete a manifest.
DeleteManifest(ctx context.Context, name string, opts ModifyManifestOptions) error
// Iterate through all manifests. Whether manifests that are newly added during iteration
// will appear in the results is unspecified.
EnumerateManifests(ctx context.Context) iter.Seq2[ManifestMetadata, error]
// Check whether a domain has any deployments.
CheckDomain(ctx context.Context, domain string) (found bool, err error)
// Create a domain. This allows us to start serving content for the domain.
CreateDomain(ctx context.Context, domain string) error
// Freeze a domain. This allows a site to be administratively locked, e.g. if it
// is discovered serving abusive content.
FreezeDomain(ctx context.Context, domain string) error
// Thaw a domain. This removes the previously placed administrative lock (if any).
UnfreezeDomain(ctx context.Context, domain string) error
// Append a record to the audit log.
AppendAuditLog(ctx context.Context, id AuditID, record *AuditRecord) error
// Retrieve a single record from the audit log.
QueryAuditLog(ctx context.Context, id AuditID) (record *AuditRecord, err error)
// Retrieve records from the audit log by time range.
SearchAuditLog(ctx context.Context, opts SearchAuditLogOptions) iter.Seq2[AuditID, error]
}
func CreateBackend ¶
func CreateBackend(ctx context.Context, config *StorageConfig) (backend Backend, err error)
func NewAuditedBackend ¶
func NewObservedBackend ¶
type BackendFeature ¶
type BackendFeature string
const (
FeatureCheckDomainMarker BackendFeature = "check-domain-marker"
)
type BlobMetadata ¶ added in v0.3.0
type BoundedReader ¶
type BoundedReader struct {
// contains filtered or unexported fields
}
type CacheConfig ¶
type CachedBlob ¶
type CachedBlob struct {
// contains filtered or unexported fields
}
Blobs can be safely cached indefinitely. They only need to be evicted to preserve memory.
func (*CachedBlob) Weight ¶
func (c *CachedBlob) Weight() uint32
type CachedManifest ¶
type CachedManifest struct {
// contains filtered or unexported fields
}
Manifests can only be cached for a short time to avoid serving stale content. Browser page loads cause a large burst of manifest accesses that are essential for serving `304 No Content` responses and these need to be handled very quickly, so both hits and misses are cached.
func (*CachedManifest) Weight ¶
func (c *CachedManifest) Weight() uint32
type Config ¶
type Config struct {
Insecure bool `toml:"-" env:"insecure"`
Features []string `toml:"features"`
LogFormat string `toml:"log-format" default:"text"`
Server ServerConfig `toml:"server"`
Wildcard []WildcardConfig `toml:"wildcard"`
Fallback FallbackConfig `toml:"fallback"`
Storage StorageConfig `toml:"storage"`
Limits LimitsConfig `toml:"limits"`
Audit AuditConfig `toml:"audit"`
Observability ObservabilityConfig `toml:"observability"`
}
type CreateParentsMode ¶
type CreateParentsMode int
const ( RequireParents CreateParentsMode = iota CreateParents )
type Duration ¶
For an unknown reason, the standard `time.Duration` type doesn't implement the standard `encoding.{TextMarshaler,TextUnmarshaler}` interfaces.
func (*Duration) MarshalText ¶
func (*Duration) UnmarshalText ¶
type Entry ¶
type Entry struct {
Type *Type `protobuf:"varint,1,opt,name=type,enum=Type" json:"type,omitempty"`
// Only present for `type == InlineFile` and `type == ExternalFile`.
// For transformed entries, refers to the pre-transformation (decompressed) size; otherwise
// equal to `compressed_size`.
OriginalSize *int64 `protobuf:"varint,7,opt,name=original_size,json=originalSize" json:"original_size,omitempty"`
// Only present for `type == InlineFile` and `type == ExternalFile`.
// For transformed entries, refers to the post-transformation (compressed) size; otherwise
// equal to `original_size`.
CompressedSize *int64 `protobuf:"varint,2,opt,name=compressed_size,json=compressedSize" json:"compressed_size,omitempty"`
// Meaning depends on `type`:
// - If `type == InlineFile`, contains file data.
// - If `type == ExternalFile`, contains blob name (an otherwise unspecified
// cryptographically secure content hash).
// - If `type == Symlink`, contains link target.
// - Otherwise not present.
Data []byte `protobuf:"bytes,3,opt,name=data" json:"data,omitempty"`
// Only present for `type == InlineFile` and `type == ExternalFile` that
// have been transformed.
Transform *Transform `protobuf:"varint,4,opt,name=transform,enum=Transform" json:"transform,omitempty"`
// Only present for `type == InlineFile` and `type == ExternalFile`.
// Currently, optional (not present on certain legacy manifests).
ContentType *string `protobuf:"bytes,5,opt,name=content_type,json=contentType" json:"content_type,omitempty"`
// May be present for `type == InlineFile` and `type == ExternalFile`.
// Used to reduce the amount of work being done during git checkouts.
// The type of hash used is determined by the length:
// - 40 bytes: SHA1DC (as hex)
// - 64 bytes: SHA256 (as hex)
GitHash *string `protobuf:"bytes,6,opt,name=git_hash,json=gitHash" json:"git_hash,omitempty"`
// contains filtered or unexported fields
}
func AddDirectory ¶
func NewManifestEntry ¶
func (*Entry) Descriptor
deprecated
func (*Entry) GetCompressedSize ¶
func (*Entry) GetContentType ¶
func (*Entry) GetGitHash ¶
func (*Entry) GetOriginalSize ¶
func (*Entry) GetTransform ¶
func (*Entry) ProtoMessage ¶
func (*Entry) ProtoMessage()
func (*Entry) ProtoReflect ¶
func (x *Entry) ProtoReflect() protoreflect.Message
type FSBackend ¶
type FSBackend struct {
// contains filtered or unexported fields
}
func (*FSBackend) AppendAuditLog ¶
func (*FSBackend) CheckDomain ¶
func (*FSBackend) CommitManifest ¶
func (*FSBackend) CreateDomain ¶
func (*FSBackend) DeleteBlob ¶
func (*FSBackend) DeleteManifest ¶
func (*FSBackend) EnableFeature ¶
func (fs *FSBackend) EnableFeature(ctx context.Context, feature BackendFeature) error
func (*FSBackend) EnumerateBlobs ¶ added in v0.3.0
func (*FSBackend) EnumerateManifests ¶ added in v0.3.0
func (*FSBackend) FreezeDomain ¶
func (*FSBackend) GetBlob ¶
func (fs *FSBackend) GetBlob( ctx context.Context, name string, ) ( reader io.ReadSeeker, metadata BlobMetadata, err error, )
func (*FSBackend) GetManifest ¶
func (fs *FSBackend) GetManifest( ctx context.Context, name string, opts GetManifestOptions, ) ( manifest *Manifest, metadata ManifestMetadata, err error, )
func (*FSBackend) HasFeature ¶
func (fs *FSBackend) HasFeature(ctx context.Context, feature BackendFeature) bool
func (*FSBackend) QueryAuditLog ¶
func (*FSBackend) SearchAuditLog ¶
func (*FSBackend) StageManifest ¶
type FallbackConfig ¶
type GetManifestOptions ¶
type GetManifestOptions struct {
// If true and the manifest is past the cache `MaxAge`, `GetManifest` blocks and returns
// a fresh object instead of revalidating in background and returning a stale object.
BypassCache bool
}
type HTTPContentTypes ¶ added in v0.3.0
type HTTPContentTypes struct {
// contains filtered or unexported fields
}
func ParseAcceptHeader ¶ added in v0.3.0
func ParseAcceptHeader(headerValue string) (result HTTPContentTypes)
func (*HTTPContentTypes) Negotiate ¶ added in v0.3.0
func (e *HTTPContentTypes) Negotiate(offers ...string) string
type HTTPEncodings ¶ added in v0.3.0
type HTTPEncodings struct {
// contains filtered or unexported fields
}
func ParseAcceptEncodingHeader ¶ added in v0.3.0
func ParseAcceptEncodingHeader(headerValue string) (result HTTPEncodings)
func (*HTTPEncodings) Negotiate ¶ added in v0.3.0
func (e *HTTPEncodings) Negotiate(offers ...string) string
Negotiate returns the most preferred encoding that is acceptable by the client, or an empty string if no encodings are acceptable.
type Header ¶
type Header struct {
Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
Values []string `protobuf:"bytes,2,rep,name=values" json:"values,omitempty"`
// contains filtered or unexported fields
}
See https://docs.netlify.com/manage/routing/headers/ for details.
func (*Header) Descriptor
deprecated
func (*Header) ProtoMessage ¶
func (*Header) ProtoMessage()
func (*Header) ProtoReflect ¶
func (x *Header) ProtoReflect() protoreflect.Message
type HeaderRule ¶
type HeaderRule struct {
Path *string `protobuf:"bytes,1,opt,name=path" json:"path,omitempty"`
HeaderMap []*Header `protobuf:"bytes,2,rep,name=header_map,json=headerMap" json:"header_map,omitempty"`
// contains filtered or unexported fields
}
func (*HeaderRule) Descriptor
deprecated
func (*HeaderRule) Descriptor() ([]byte, []int)
Deprecated: Use HeaderRule.ProtoReflect.Descriptor instead.
func (*HeaderRule) GetHeaderMap ¶
func (x *HeaderRule) GetHeaderMap() []*Header
func (*HeaderRule) GetPath ¶
func (x *HeaderRule) GetPath() string
func (*HeaderRule) ProtoMessage ¶
func (*HeaderRule) ProtoMessage()
func (*HeaderRule) ProtoReflect ¶
func (x *HeaderRule) ProtoReflect() protoreflect.Message
func (*HeaderRule) Reset ¶
func (x *HeaderRule) Reset()
func (*HeaderRule) String ¶
func (x *HeaderRule) String() string
type LimitsConfig ¶
type LimitsConfig struct {
// Maximum size of a single published site. Also used to limit the size of archive
// uploads and other similar overconsumption conditions.
MaxSiteSize datasize.ByteSize `toml:"max-site-size" default:"128M"`
// Maximum size of a single site manifest, computed over its binary Protobuf
// serialization.
MaxManifestSize datasize.ByteSize `toml:"max-manifest-size" default:"1M"`
// Maximum size of a file that will still be inlined into the site manifest.
MaxInlineFileSize datasize.ByteSize `toml:"max-inline-file-size" default:"256B"`
// Maximum size of a Git object that will be cached in memory during Git operations.
GitLargeObjectThreshold datasize.ByteSize `toml:"git-large-object-threshold" default:"1M"`
// Maximum number of symbolic link traversals before the path is considered unreachable.
MaxSymlinkDepth uint `toml:"max-symlink-depth" default:"16"`
// Maximum time that an update operation (PUT or POST request) could take before being
// interrupted.
UpdateTimeout Duration `toml:"update-timeout" default:"60s"`
// Soft limit on Go heap size, expressed as a fraction of total available RAM.
MaxHeapSizeRatio float64 `toml:"max-heap-size-ratio" default:"0.5"`
// List of domains unconditionally forbidden for uploads.
ForbiddenDomains []string `toml:"forbidden-domains" default:"[]"`
// List of allowed repository URL prefixes. Setting this option prohibits uploading archives.
AllowedRepositoryURLPrefixes []string `toml:"allowed-repository-url-prefixes" default:"[]"`
// List of allowed custom headers. Header name must be in the MIME canonical form,
// e.g. `Foo-Bar`. Setting this option permits including this custom header in `_headers`,
// unless it is fundamentally unsafe.
AllowedCustomHeaders []string `toml:"allowed-custom-headers" default:"[\"X-Clacks-Overhead\"]"`
}
type Manifest ¶
type Manifest struct {
// Source metadata.
RepoUrl *string `protobuf:"bytes,1,opt,name=repo_url,json=repoUrl" json:"repo_url,omitempty"`
Branch *string `protobuf:"bytes,2,opt,name=branch" json:"branch,omitempty"`
Commit *string `protobuf:"bytes,3,opt,name=commit" json:"commit,omitempty"`
// Site contents.
Contents map[string]*Entry `` /* 136-byte string literal not displayed */
OriginalSize *int64 `protobuf:"varint,10,opt,name=original_size,json=originalSize" json:"original_size,omitempty"` // sum of each `entry.original_size`
CompressedSize *int64 `protobuf:"varint,5,opt,name=compressed_size,json=compressedSize" json:"compressed_size,omitempty"` // sum of each `entry.compressed_size`
StoredSize *int64 `protobuf:"varint,8,opt,name=stored_size,json=storedSize" json:"stored_size,omitempty"` // sum of deduplicated `entry.compressed_size` for external files only
// Netlify-style `_redirects` and `_headers` rules.
Redirects []*RedirectRule `protobuf:"bytes,6,rep,name=redirects" json:"redirects,omitempty"`
Headers []*HeaderRule `protobuf:"bytes,9,rep,name=headers" json:"headers,omitempty"`
// Diagnostics for non-fatal errors.
Problems []*Problem `protobuf:"bytes,7,rep,name=problems" json:"problems,omitempty"`
// contains filtered or unexported fields
}
func DecodeManifest ¶
func ExtractGzip ¶
func ExtractTar ¶
func ExtractZip ¶
func ExtractZstd ¶
func FetchRepository ¶
func NewManifest ¶
func NewManifest() *Manifest
func StoreManifest ¶
func StoreManifest( ctx context.Context, name string, manifest *Manifest, opts ModifyManifestOptions, ) (*Manifest, error)
Uploads inline file data over certain size to the storage backend. Returns a copy of the manifest updated to refer to an external content-addressable store.
func (*Manifest) Descriptor
deprecated
func (*Manifest) GetCompressedSize ¶
func (*Manifest) GetContents ¶
func (*Manifest) GetHeaders ¶
func (x *Manifest) GetHeaders() []*HeaderRule
func (*Manifest) GetOriginalSize ¶
func (*Manifest) GetProblems ¶
func (*Manifest) GetRedirects ¶
func (x *Manifest) GetRedirects() []*RedirectRule
func (*Manifest) GetRepoUrl ¶
func (*Manifest) GetStoredSize ¶
func (*Manifest) ProtoMessage ¶
func (*Manifest) ProtoMessage()
func (*Manifest) ProtoReflect ¶
func (x *Manifest) ProtoReflect() protoreflect.Message
type ManifestMetadata ¶
type ModifyManifestOptions ¶
type ModifyManifestOptions struct {
// If non-zero, the request will only succeed if the manifest hasn't been changed since
// the given time. Whether this is racy or not is can be determined via `HasAtomicCAS()`.
IfUnmodifiedSince time.Time
// If non-empty, the request will only succeed if the manifest hasn't changed from
// the state corresponding to the ETag. Whether this is racy or not is can be determined
// via `HasAtomicCAS()`.
IfMatch string
}
type ObservabilityConfig ¶
type ObservabilityConfig struct {
// Minimum duration for an HTTP request transaction to be unconditionally sampled.
SlowResponseThreshold Duration `toml:"slow-response-threshold" default:"500ms"`
}
type Principal ¶
type Principal struct {
IpAddress *string `protobuf:"bytes,1,opt,name=ip_address,json=ipAddress" json:"ip_address,omitempty"`
CliAdmin *bool `protobuf:"varint,2,opt,name=cli_admin,json=cliAdmin" json:"cli_admin,omitempty"`
// contains filtered or unexported fields
}
func GetPrincipal ¶
func (*Principal) Descriptor
deprecated
func (*Principal) GetCliAdmin ¶
func (*Principal) GetIpAddress ¶
func (*Principal) ProtoMessage ¶
func (*Principal) ProtoMessage()
func (*Principal) ProtoReflect ¶
func (x *Principal) ProtoReflect() protoreflect.Message
type Problem ¶
type Problem struct {
Path *string `protobuf:"bytes,1,opt,name=path" json:"path,omitempty"`
Cause *string `protobuf:"bytes,2,opt,name=cause" json:"cause,omitempty"`
// contains filtered or unexported fields
}
func (*Problem) Descriptor
deprecated
func (*Problem) ProtoMessage ¶
func (*Problem) ProtoMessage()
func (*Problem) ProtoReflect ¶
func (x *Problem) ProtoReflect() protoreflect.Message
type RedirectKind ¶
type RedirectKind int
const ( RedirectAny RedirectKind = iota RedirectNormal RedirectForce )
type RedirectRule ¶
type RedirectRule struct {
From *string `protobuf:"bytes,1,opt,name=from" json:"from,omitempty"`
To *string `protobuf:"bytes,2,opt,name=to" json:"to,omitempty"`
Status *uint32 `protobuf:"varint,3,opt,name=status" json:"status,omitempty"`
Force *bool `protobuf:"varint,4,opt,name=force" json:"force,omitempty"`
// contains filtered or unexported fields
}
See https://docs.netlify.com/manage/routing/redirects/overview/ for details. Only a subset of the Netlify specification is representable here.
func ApplyRedirectRules ¶
func ApplyRedirectRules( manifest *Manifest, fromURL *url.URL, kind RedirectKind, ) ( rule *RedirectRule, toURL *url.URL, status int, )
func (*RedirectRule) Descriptor
deprecated
func (*RedirectRule) Descriptor() ([]byte, []int)
Deprecated: Use RedirectRule.ProtoReflect.Descriptor instead.
func (*RedirectRule) GetForce ¶
func (x *RedirectRule) GetForce() bool
func (*RedirectRule) GetFrom ¶
func (x *RedirectRule) GetFrom() string
func (*RedirectRule) GetStatus ¶
func (x *RedirectRule) GetStatus() uint32
func (*RedirectRule) GetTo ¶
func (x *RedirectRule) GetTo() string
func (*RedirectRule) ProtoMessage ¶
func (*RedirectRule) ProtoMessage()
func (*RedirectRule) ProtoReflect ¶
func (x *RedirectRule) ProtoReflect() protoreflect.Message
func (*RedirectRule) Reset ¶
func (x *RedirectRule) Reset()
func (*RedirectRule) String ¶
func (x *RedirectRule) String() string
type S3Backend ¶
type S3Backend struct {
// contains filtered or unexported fields
}
func (*S3Backend) AppendAuditLog ¶
func (*S3Backend) CheckDomain ¶
func (*S3Backend) CommitManifest ¶
func (*S3Backend) CreateDomain ¶
func (*S3Backend) DeleteBlob ¶
func (*S3Backend) DeleteManifest ¶
func (*S3Backend) EnableFeature ¶
func (s3 *S3Backend) EnableFeature(ctx context.Context, feature BackendFeature) error
func (*S3Backend) EnumerateBlobs ¶ added in v0.3.0
func (*S3Backend) EnumerateManifests ¶ added in v0.3.0
func (*S3Backend) FreezeDomain ¶
func (*S3Backend) GetBlob ¶
func (s3 *S3Backend) GetBlob( ctx context.Context, name string, ) ( reader io.ReadSeeker, metadata BlobMetadata, err error, )
func (*S3Backend) GetManifest ¶
func (s3 *S3Backend) GetManifest( ctx context.Context, name string, opts GetManifestOptions, ) ( manifest *Manifest, metadata ManifestMetadata, err error, )
func (*S3Backend) HasFeature ¶
func (s3 *S3Backend) HasFeature(ctx context.Context, feature BackendFeature) bool
func (*S3Backend) QueryAuditLog ¶
func (*S3Backend) SearchAuditLog ¶
func (*S3Backend) StageManifest ¶
type S3Config ¶
type S3Config struct {
Endpoint string `toml:"endpoint"`
Insecure bool `toml:"insecure"`
AccessKeyID string `toml:"access-key-id"`
SecretAccessKey string `toml:"secret-access-key"`
Region string `toml:"region"`
Bucket string `toml:"bucket"`
BlobCache CacheConfig `toml:"blob-cache" default:"{\"MaxSize\":\"256MB\"}"`
SiteCache CacheConfig `toml:"site-cache" default:"{\"MaxAge\":\"60s\",\"MaxStale\":\"1h\",\"MaxSize\":\"16MB\"}"`
}
type SearchAuditLogOptions ¶
type SearchAuditLogOptions struct {
// Inclusive lower bound on returned audit records, per their Snowflake ID (which may differ
// slightly from the embedded timestamp). If zero, audit records are returned since beginning
// of time.
Since time.Time
// Inclusive upper bound on returned audit records, per their Snowflake ID (which may differ
// slightly from the embedded timestamp). If zero, audit records are returned until the end
// of time.
Until time.Time
}
type SearchAuditLogResult ¶
type ServerConfig ¶
type StorageConfig ¶
type Transform ¶
type Transform int32
Transformation names should match HTTP `Accept-Encoding:` header.
func (Transform) Descriptor ¶
func (Transform) Descriptor() protoreflect.EnumDescriptor
func (Transform) EnumDescriptor
deprecated
func (Transform) Number ¶
func (x Transform) Number() protoreflect.EnumNumber
func (Transform) Type ¶
func (Transform) Type() protoreflect.EnumType
type Type ¶
type Type int32
const ( // Invalid entry. Type_InvalidEntry Type = 0 // Directory. Type_Directory Type = 1 // Inline file. `Blob.Data` contains file contents. Type_InlineFile Type = 2 // External file. `Blob.Data` contains object reference. Type_ExternalFile Type = 3 // Symlink. `Blob.Data` contains relative path. Type_Symlink Type = 4 )
func (Type) Descriptor ¶
func (Type) Descriptor() protoreflect.EnumDescriptor
func (Type) EnumDescriptor
deprecated
func (Type) Number ¶
func (x Type) Number() protoreflect.EnumNumber
func (Type) Type ¶
func (Type) Type() protoreflect.EnumType
type URL ¶
For a known but upsetting reason, the standard `url.URL` type doesn't implement the standard `encoding.{TextMarshaler,TextUnmarshaler}` interfaces.
func (*URL) MarshalText ¶
func (*URL) UnmarshalText ¶
type UnresolvedRefError ¶ added in v0.3.0
type UnresolvedRefError struct {
// contains filtered or unexported fields
}
func (UnresolvedRefError) Error ¶ added in v0.3.0
func (err UnresolvedRefError) Error() string
type UpdateOutcome ¶
type UpdateOutcome int
const ( UpdateError UpdateOutcome = iota UpdateTimeout UpdateCreated UpdateReplaced UpdateDeleted UpdateNoChange )
type UpdateResult ¶
type UpdateResult struct {
// contains filtered or unexported fields
}
func PartialUpdateFromArchive ¶
func PartialUpdateFromArchive( ctx context.Context, webRoot string, contentType string, reader io.Reader, parents CreateParentsMode, ) (result UpdateResult)
func Update ¶
func Update( ctx context.Context, webRoot string, oldManifest, newManifest *Manifest, opts ModifyManifestOptions, ) UpdateResult
func UpdateFromArchive ¶
func UpdateFromRepository ¶
type WildcardConfig ¶
type WildcardPattern ¶
type WildcardPattern struct {
Domain []string
CloneURL *fasttemplate.Template
IndexRepos []*fasttemplate.Template
IndexBranch string
Authorization bool
}
func TranslateWildcards ¶
func TranslateWildcards(configs []WildcardConfig) ([]*WildcardPattern, error)
func (*WildcardPattern) ApplyTemplate ¶
func (pattern *WildcardPattern) ApplyTemplate(userName string, projectName string) ([]string, string)
func (*WildcardPattern) GetHost ¶
func (pattern *WildcardPattern) GetHost() string