Honey is an http cache and proxy.
In the event of a cache miss, It multiplexes requests to the same URL into a single request, and once the response has been received, writes it to all requesters, and adds it to the cache.
It will set an Etag on responses, and respond with an HTTP 304 Not Modified in the event that the If-None-Match
header matches the Etag.
If will not cache responses that contain the no-store
Cache-Control directive
It will always fetch fresh resources if the no-cache
Cache-Control directive, or if Pragma: no-cache, is set in the request
backend, err := url.Parse("https://www.example.com")
if err != nil {
panic(err)
}
cacher := cache.NewDefaultCacher()
// adding site_lang_id cookie to the default
// cacher will allow it through the cache
cacher.AddAllowedCookie("site_lang_id")
fetcher := fetch.Fetch(cacher, fetch.Forwarder(cacher), backend)
http.ListenAndServe(":8080", fetcher)
-
Handle
stale-if-error
- Add unit tests
- Configurable Site-wide (whether to respect it if present, or whether to always act as if this header were present)
- Configurable Per route
- Send cached response with a
Warning
header if the backend gives an error after clearing the cache.
-
Implement configuration via TOML file (honey.toml?)
-
Come up with a way to mark certain routes/files as
immutable
-
Web UI to configure / clear cache and view metrics
-
Minify html, js, css before cacheing
- Implement it
- Make this configurable (whether to do it, site wide and per route)
-
Canonicalize popular JavaScript libraries that can be replaced with ones hosted for free by a JavaScript library hosting service
- Implement it
- Make this configurable (whether to do it, site wide and per route)
-
Use http/2 push to push assets if request doesn't have an If-None-Match header
- Implement it
- Make this configurable (whether to do it, site wide and per route)
-
Rewrite static assets to cookieless subdomain
-
Combine all google-font requests into a single one
-
Implement other cache backends
-
In Memory
-
File
-
Memcached
-
Redis
-
BoltDB
-
Brotli compress if requester supports it
-
Implement it
-
Make this configurable (whether to do it, site wide and per route)
-
-
Implement offline cache
- Implement it
- Make this configurable (whether to do it, site wide and per route)
-
Automatically fix mixed-content https issues
- Implement it
- Make this configurable (whether to do it, site wide and per route)
-
Prevent hotlinking of images
- Implement it
- Make this configurable (whether to do it, site wide and per route)
-
Letsencypt SSL termination
-
Set
Last-Modified
header on response to the cached time if it is not already on the backend response.- Configurable Site-wide
- Configurable Per route
-
Handle
If-Modified-Since
andIf-Unmodified-Since
-
If cache miss, but after refresh Etag matches, send 304 Response
-
Handle
only-if-cached
Cache-Control directive -
Validate response or send to backend if
must-revalidate
orproxy-revalidate
Cache-Control directive- Configurable Site-wide whether to respect must-revalidate directive, or only if from list of IPs, or some sort of authentication mechanism
- Configurable Per route
-
Add the
public
Cache-Control directive unlessprivate
is received from backend.- Configurable Site-wide
- Configurable Per route
-
Add
Expires
header to responses if not in response from backend.- Configurable Cache TTL
- Configurable whether to overwrite backend Expires
- Configure whether to serve stale content while refreshing, or multiplex requests into a single request and serve new content to all of them
- Configurable Site-wide
- Configurable Per route
-
Add ability to configure which headers to include in the Request hash (e.g. Accept-Language)
- Configurable Site-wide
- Configurable Per route
-
If cache miss, but after refresh Validate matches, send 304 Response
-
Check
Vary
header from response and handle properly -
Handle
stale-while-revalidate
- Configurable Site-wide (whether to respect it)
- Configurable Per route
-
After fetching a route with multiplexer, check vary headers, bucket queued requests based on the header, and do a fetch for each variant.