files

package
v0.0.12 Latest Latest
Warning

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

Go to latest
Published: Aug 27, 2026 License: MIT Imports: 6 Imported by: 0

Documentation

Rendered for js/wasm

Overview

Package files serves an object bucket over a route prefix.

It exists so that every module that accepts user uploads gets the same three guarantees without rewriting them: the stored type is the one deduced from the bytes, the key is minted by the server, and the size is checked before a single byte of the body is buffered.

Index

Constants

View Source
const Action = model.Create

Action is what uploading does: it CREATES an object under a key the server generates. It is not "write" — the action vocabulary is closed CRUD, and an invented verb is a permission nothing enforces.

View Source
const (
	// DefaultMaxSize is the largest upload accepted unless the caller says otherwise.
	DefaultMaxSize = 10 << 20 // 10 MiB

)
View Source
const Resource model.Resource = "files"

Resource is the permission an app must grant to let a caller upload. It is exported because the app is the one that decides WHO holds it: the library states the requirement, the consumer's Authorizer answers it.

Variables

This section is empty.

Functions

This section is empty.

Types

type Bucket

type Bucket interface {
	Put(key string, data []byte, contentType string) error
	Get(key string) (data []byte, contentType string, err error)
}

Bucket is the storage this package needs. r2.Bucket satisfies it.

type Store

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

Store registers the upload and serve handlers for one bucket under one prefix.

func New

func New(b Bucket, prefix string) (*Store, error)

New builds a Store on the safe defaults: raster images only, 10 MiB. prefix must end in "/" — it is matched by prefix, and the key is what hangs off it.

func (*Store) Allow

func (s *Store) Allow(a filetype.Allowlist) *Store

Allow narrows or widens the accepted types. Never add SVG or HTML: both carry JavaScript and, served from your own domain, execute in your origin.

func (*Store) MaxSize

func (s *Store) MaxSize(n int) *Store

MaxSize caps the upload size in bytes.

func (*Store) Mount

func (s *Store) Mount(r router.Router)

Mount registers both routes: uploading requires the files/Create permission, serving is public because an <img src> cannot send headers.

The upload is guarded on purpose. Do NOT make it public to "fix" a 403: a write-open bucket is a spam form. If uploads are rejected, the app has not told the router who the caller is (edge.Config.Authn) or who may write (edge.Config.Authorize).

func (*Store) PerOwner

func (s *Store) PerOwner() *Store

PerOwner keys the object by its uploader: ONE object per identity, replaced whenever that identity uploads again. The natural shape of an avatar, a profile photo, a signature.

The key is the caller's UserID and nothing else — no extension. The type is NOT lost: it was deduced from the bytes and travels in the object's metadata, which is exactly where serve() already reads it from. An extension would defeat the point: uploading a .png and then a .jpg would produce TWO keys, and the first would be orphaned forever.

It is only reachable on a guarded route (upload already Requires files/Create), so the identity is never empty by construction.

Jump to

Keyboard shortcuts

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