howdy/storage/local
Storage in a local folder, for development and for apps on one server. Each object is a file at its key under the folder, so the folder can be browsed, backed up or synced like any other.
let config =
local.new("storage")
|> local.serve(at: "/files", secret: env.get_or("STORAGE_SECRET", ""))
let files = local.adapter(config)
howdy.new()
|> howdy.controller(local.controller(config))
A folder cannot hold both an object a and an object a/b, as a
bucket can, so the second is refused. The content type and other
details of each object are kept beside it under .howdy-storage, which
keys may not start with.
Serving files
storage.url needs serve: it gives a URL under that path, signed with
the secret, which controller answers until it expires. Use a secret
of at least 32 random bytes, and the same on every node. Files are
served from the app’s own origin, so the controller sends them with
X-Content-Type-Options: nosniff and a sandboxing
Content-Security-Policy, and makes the browser download anything but
images, audio, video, PDFs and plain text rather than show it. An HTML
or SVG file someone uploaded cannot run script on your site.
Types
Values
pub fn adapter(config: Config) -> storage.Storage
pub fn controller(config: Config) -> controller.Builder(Nil)
A controller answering the URLs storage.url makes, mounted at the
prefix given to serve. An expired or altered URL gets a 403.
pub fn new(directory: String) -> Config
Storage in directory, relative to the working directory unless
absolute. It is created when the first object is stored.