roadrunner_etag (roadrunner v0.12.1)
View SourceConditional 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, ...},
{send, ...}, 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
-spec call(roadrunner_req:request(), roadrunner_middleware:next(), roadrunner_middleware:state()) -> roadrunner_handler:result().