hashfs

package module
v0.2.2 Latest Latest
Warning

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

Go to latest
Published: Feb 19, 2024 License: MIT Imports: 12 Imported by: 30

README

hashfs

Implementation of io/fs.FS that appends SHA256 hashes to filenames to allow for aggressive HTTP caching.

For example, given a file path of scripts/main.js, the hashfs.FS filesystem will provide the server with a hashname of scripts/main-b633a..d628.js (the hash is truncated for brevity in the example). When this file path is requested by the client, the server can verify the hash and return the contents with an aggressive Cache-Control header. The client will cache this file for up to a year and does not need to re-request it in the future.

Note that this library requires Go 1.16 or higher.

Usage

To use hashfs, first wrap your embed.FS in a hashfs.FS filesystem:

//go:embed scripts stylesheets images
var embedFS embed.FS

var fsys = hashfs.NewFS(embedFS)

Then attach a hashfs.FileServer() to your router:

http.Handle("/assets/", http.StripPrefix("/assets/", hashfs.FileServer(fsys)))

Next, your html templating library can obtain the hashname of your file using the hashfs.FS.HashName() method:

func renderHTML(w io.Writer) {
	fmt.Fprintf(w, `<html>`)
	fmt.Fprintf(w, `<script src="/assets/%s"></script>`, fsys.HashName("scripts/main.js"))
	fmt.Fprintf(w, `</html>`)
}

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func FileServer

func FileServer(fsys fs.FS) http.Handler

FileServer returns an http.Handler for serving FS files. It provides a simplified implementation of http.FileServer which is used to aggressively cache files on the client since the file hash is in the filename.

Because FileServer is focused on small known path files, several features of http.FileServer have been removed including canonicalizing directories, defaulting index.html pages, precondition checks, & content range headers.

func FormatName

func FormatName(filename, hash string) string

FormatName returns a hash name that inserts hash before the filename's extension. If no extension exists on filename then the hash is appended. Returns blank string the original filename if hash is blank. Returns a blank string if the filename is blank.

func ParseName

func ParseName(filename string) (base, hash string)

ParseName splits formatted hash filename into its base & hash components.

Types

type FS

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

FS represents an fs.FS file system that can optionally use content addressable hashes in the filename. This allows the caller to aggressively cache the data since the filename will change if the data changes.

func NewFS

func NewFS(fsys fs.FS) *FS

func (*FS) HashName

func (fsys *FS) HashName(name string) string

HashName returns the hash name for a path, if exists. Otherwise returns the original path.

func (*FS) Open

func (fsys *FS) Open(name string) (fs.File, error)

Open returns a reference to the named file. If name is a hash name then the underlying file is used.

func (*FS) ParseName added in v0.2.1

func (fsys *FS) ParseName(filename string) (base, hash string)

ParseName splits formatted hash filename into its base & hash components.

Jump to

Keyboard shortcuts

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