roadrunner_etag (roadrunner v0.10.4)

View Source

Conditional request middleware for dynamic responses (RFC 9110 §13.1.2).

For a GET or HEAD answered with a buffered 200, it derives a weak ETag from the response body (or keeps one the handler already set) and answers a matching If-None-Match with a bodyless 304 Not Modified, so a client that revalidates doesn't download the body again.

Add it to a listener's middlewares (or a map-form route's middlewares). It takes no config:

roadrunner:start_listener(my_api, #{
    port => 8080,
    routes => Routes,
    middlewares => [roadrunner_compress, roadrunner_etag]
}).

List it after roadrunner_compress, as above. The first entry runs outermost, so roadrunner_etag then sees the uncompressed body, and a 304 skips the compression work.

Weak validators

The ETag is weak (W/"...") because a later step may re-encode the body, for example roadrunner_compress gzipping it, so the bytes on the wire are not guaranteed to stay identical. If-None-Match uses weak comparison (RFC 9110 §8.8.3.2): the W/ prefix is ignored on either side, so a client that echoes the tag in either form still revalidates. * matches any current representation.

Scope

Only a buffered 200 for GET or HEAD is handled. Other statuses and methods, and {stream, ...}, {loop, ...}, {sendfile, ...}, and {websocket, ...} responses, pass through unchanged. Computing the ETag reads the whole body once per response, so use it on read-heavy endpoints where skipping the body on revalidation is worth the hash.

Summary

Functions