htpack/README.md

72 lines
2.8 KiB
Markdown

# HTTP resource pack server
[![GoDoc](https://img.shields.io/static/v1?label=godoc&message=reference&color=blue)](https://pkg.go.dev/src.lwithers.me.uk/go/htpack)
A common scenario is that you have a set of static resources that you want to
serve up quickly via HTTP (for example: stylesheets, WASM).
This package provides a `net/http`-compatible `http.Handler` to do so, with
support for:
- compression
- gzip
- brotli
- does not yet support Transfer-Encoding, only Accept-Encoding/Content-Encoding
- etags
- ranges
The workflow is as follows:
- (optional) build YAML file describing files to serve
- run htpacker tool to produce a single .htpack file
- create `htpack.Handler` pointing at .htpack file
The handler can easily be combined with middleware (`http.StripPrefix` etc.).
## Range handling notes
Too many bugs have been found with range handling and composite ranges, so the
handler only accepts a single range within the limits of the file. Anything
else will be ignored.
The interaction between range handling and compression also seems a little
ill-defined; as we have pre-compressed data, however, we can consistently
serve the exact same byte data for compressed files.
## Angular-style single-page application handling
If you wish to support an angular.js-style single page application, in which
a Javascript application uses the browser's history API to create a set of
virtual paths ("routes"), it is necessary to somehow intercept HTTP 404 errors
being returned from the handler and instead return an HTTP 200 with an HTML
document.
This can be achieved with a number of methods.
The simplest method is to tell `packserver` itself which resource to use
instead of returning an HTTP 404. Use the command line argument
`--fallback-404 /index.html` (or whichever named resource). The filename must
match a packed resource, so it will be preceded with a `/`. It must exist in
all packfiles being served.
If you have an nginx instance reverse proxying in front of `htpack`, then you
can use a couple of extra directives. This is very flexible as it lets you
override the resource for different routes. For example:
# prevent page loaded at "http://server.example/my-application" from
# requesting resources at "/*" when it should request them at
# "/my-application/*" instead
location = /my-application {
return 308 /my-application/;
}
location /my-application/ {
proxy_to http://htpack-addr:8080/;
proxy_intercept_errors on;
error_page 404 =200 /my-application/;
}
If you are using the handler as a library, then you may call
`handler.SetNotFound(filename)` to select a resource to return (with HTTP 200)
if a request is made for a resource that is not found. The filename must match
a packed resource, so it will be preceded with a `/` (for example it may be
`"/index.html"`).