staticserve

package module
v1.1.2 Latest Latest
Warning

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

Go to latest
Published: May 26, 2026 License: MIT Imports: 13 Imported by: 5

README

build coverage goreport Docs

staticserve

staticserve is a cache-busting HTTP handler for static files. It supports GET operations requesting the file with no encoding or gzip encoding.

Example

package main

import (
	"fmt"
	"log"
	"net/http"

	"github.com/linkdata/staticserve"
)

func main() {
	mux := http.NewServeMux()
	uri, err := staticserve.Handle("app.js", []byte("console.log('hello');"), mux.Handle)
	if err != nil {
		log.Fatal(err)
	}

	// Use this URI in your HTML templates, e.g. <script src="{{.ScriptURI}}"></script>.
	fmt.Printf("script URI: %s\n", uri)

	log.Fatal(http.ListenAndServe(":8080", mux))
}

Documentation

Index

Examples

Constants

This section is empty.

Variables

View Source
var HeaderAllow = []string{http.MethodGet + ", " + http.MethodHead}

HeaderAllow is the Allow header value sent with 405 Method Not Allowed responses to requests that use methods other than GET or HEAD.

View Source
var HeaderCacheControl = []string{"public, max-age=31536000, s-maxage=31536000, immutable"}

HeaderCacheControl is the Cache-Control header value sent with successful responses. Its default marks the asset as immutable for one year, which is safe because the served file name is cache-busted via a content hash.

View Source
var HeaderVary = []string{"Accept-Encoding"}

HeaderVary is the Vary header value sent with successful responses.

Functions

func EnsurePrefixSlash

func EnsurePrefixSlash(s string) string

EnsurePrefixSlash returns s with a leading slash.

func Handle

func Handle(fpath string, data []byte, handleFn HandleFunc) (uri string, err error)

Handle creates a new StaticServe for the fpath that returns the data given. Returns the URI of the resource.

Example
package main

import (
	"fmt"
	"net/http"
	"net/http/httptest"
	"strings"

	"github.com/linkdata/staticserve"
)

func main() {
	mux := http.NewServeMux()
	uri, err := staticserve.Handle("app.js", []byte("console.log('hello');"), mux.Handle)
	if err != nil {
		panic(err)
	}

	req := httptest.NewRequest(http.MethodGet, uri, nil)
	req.Header.Set("Accept-Encoding", "gzip")
	rr := httptest.NewRecorder()
	mux.ServeHTTP(rr, req)
	res := rr.Result()

	fmt.Println(res.StatusCode == http.StatusOK)
	fmt.Println(res.Header.Get("Content-Encoding"))
	fmt.Println(strings.HasPrefix(uri, "/app."))
	fmt.Println(strings.HasSuffix(uri, ".js"))
}
Output:
true
gzip
true
true

func HandleFS

func HandleFS(fsys fs.FS, handleFn HandleFunc, root string, filepaths ...string) (uris []string, err error)

HandleFS creates StaticServe handlers for the filepaths given. Returns the URI(s) of the resources. If an error occurs, the URI of the failed resource will be the empty string.

func MaybePanic

func MaybePanic(err error)

MaybePanic panics if err is non-nil. It is used by Must and MustNewFS to convert initialization errors into panics.

func NormalizeGET

func NormalizeGET(pattern string) string

NormalizeGET returns a method-aware ServeMux pattern.

If pattern already has a method prefix, it is returned unchanged. Otherwise GET is prepended and the path is made absolute.

func WalkDir

func WalkDir(fsys fs.FS, root string, fn func(filename string, ss *StaticServe) (err error)) (err error)

WalkDir walks the file tree rooted at root, calling fn for each file in the tree with the filename having root trimmed (e.g. "root/dir/file.ext" becomes "dir/file.ext").

Types

type HandleFunc

type HandleFunc = func(uri string, handler http.Handler)

HandleFunc matches the signature of http.ServeMux.Handle().

Handle and HandleFS pass method-aware patterns. Bare path patterns are normalized to GET.

type StaticServe

type StaticServe struct {
	Name        string // the cache-busting file name, e.g. "static/filename.1234567.js"
	ContentType string // Content-Type of the file, e.g. "application/javascript"
	Size        int64  // uncompressed length of the asset in bytes
	Gz          []byte // gzipped data, will be unpacked as needed
}

StaticServe is an http.Handler that serves a single asset under a cache-busted file name. The asset is held gzip-compressed in memory and served either as gzip (when the client advertises Accept-Encoding: gzip) or decompressed on the fly otherwise.

Instances are safe for concurrent use after construction and are intended to be created via New, NewFS, Must, or MustNewFS so that all fields are populated consistently.

func Must

func Must(filename string, data []byte) (ss *StaticServe)

Must calls New and panics on error.

func MustNewFS

func MustNewFS(fsys fs.FS, root string, fpaths ...string) (ssl []*StaticServe)

MustNewFS calls NewFS for each fpath relative to root and returns the resulting StaticServe values in order. It panics on the first error.

func New

func New(filename string, data []byte) (ss *StaticServe, err error)

New returns a StaticServe that serves the given data with a filename like 'filename.12345678.ext'. The filename must have the suffix ".gz" if the data is GZip compressed. The ".gz" suffix will not be part of the filename presented in this case.

func NewFS

func NewFS(fsys fs.FS, root, fpath string) (ss *StaticServe, err error)

NewFS reads the file at fpath from fsys and then calls New.

func (*StaticServe) ServeHTTP

func (ss *StaticServe) ServeHTTP(w http.ResponseWriter, r *http.Request)

ServeHTTP serves the asset for GET and HEAD requests.

When the client advertises Accept-Encoding: gzip the gzip-compressed bytes are served verbatim; otherwise the asset is decompressed on the fly. Content-Length always reflects the size of the body that would be returned by an equivalent GET, so HEAD responses are usable for size discovery.

Methods other than GET and HEAD receive 405 Method Not Allowed with an Allow header. If the stored gzip stream cannot be opened (which should not happen for instances created via New), 500 Internal Server Error is returned with no body.

Jump to

Keyboard shortcuts

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