Local Filesystem
objstore.NewLocalStorage stores files on disk under a base path, and can
serve them through a BaseURL you point at your own file-serving handler.
config := objstore.LocalConfig{
BasePath: "./storage",
BaseURL: "https://example.com/files",
CreateDirs: true,
FilePermissions: 0644,
DirPermissions: 0755,
}
store, err := objstore.NewLocalStorage(config)
// Or with builder pattern
store, err := objstore.NewLocalStorage(
objstore.DefaultLocalConfig().
WithBasePath("/var/uploads").
WithBaseURL("https://cdn.example.com"),
)
Local storage has no storage server of its own, so SignedURL
produces HMAC-signed URLs that your application verifies — see
Signed URLs on the local and memory backends.
Conditional writes
WithOverwrite(false) opens the file with O_EXCL, so a create-only write is
atomic even across processes. WithIfMatch is atomic only against other Puts
through the same LocalStorage. It is not atomic against other processes or
against Copy, Move, and Delete. The local ETag is derived from the
file's modification time and size, and every Put moves the modification time
forward so that a rewrite always gets a new ETag. An overwriting Put writes to
a temporary file and renames it into place, so a failed upload leaves the
previous version intact. The replacement keeps the
old file's permissions. While a write is in progress, its temporary file
(.objstore-tmp-<uuid>) is hidden from List. See
Conditional Writes.