72 lines
2.8 KiB
Markdown
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"`).
|