|
-- early-hints.lua
|
|
--
|
|
-- Summary: sample script to send 103 Early Hints
|
|
--
|
|
--
|
|
-- Copyright (c) 2020, Glenn Strauss (gstrauss () gluelogic.com), incremental
|
|
-- All rights reserved.
|
|
--
|
|
-- License: 3-clause BSD
|
|
--
|
|
--
|
|
-- lighttpd.conf
|
|
-- server.modules += ("mod_magnet")
|
|
-- $HTTP["url"] =~ "^/" {
|
|
-- magnet.attract-raw-url-to = ( "/path/to/early-hints.lua" )
|
|
-- }
|
|
--
|
|
-- Note: lighttpd.conf was never intended to be a full programming language.
|
|
-- lua is available in lighttpd mod_lua to perform more precise, multi-step
|
|
-- processing and/or chaining of conditions.
|
|
|
|
-- RFC 8297 An HTTP Status Code for Indicating Hints (103 Early Hints)
|
|
-- https://tools.ietf.org/html/rfc8297
|
|
|
|
-- (optional) return if not *.html
|
|
-- (e.g. do not send early hints for images such as *.jpg)
|
|
--
|
|
if (not string.match(lighty.env["uri.path"], '.html$')) then return 0 end
|
|
|
|
-- (optional) return if HTTP/1.0 (does not support 1xx intermediate responses)
|
|
--if (lighty.env["request.protocol"] == "HTTP/1.0") then return 0 end
|
|
|
|
-- (optional) return if not HTTP/2
|
|
-- coarse heuristic: HTTP/2 clients are more likely to handle unexpected
|
|
-- 1xx intermediate responses than are HTTP/1.x clients. (YMMV)
|
|
-- HTTP protocol version is a coarse heuristic which would probably be better
|
|
-- if replaced with a User-Agent version parse of the User-Agent header.
|
|
-- note: string match "HTTP/2.0" as protocol name in lighttpd; not "HTTP/2"
|
|
--
|
|
if (not (lighty.env["request.protocol"] == "HTTP/2.0")) then return 0 end
|
|
|
|
-- (optional) return if User-Agent is not known to handle 1xx responses
|
|
--
|
|
-- Warning: backends which send 103 Early Hints should check User-Agent
|
|
-- before doing so since naive clients might not handle unexpected 1xx.
|
|
-- Some clients may take the 1xx response as the final response, expecting
|
|
-- only one response. Some clients might not properly handle 100 Continue
|
|
-- if the client did not send Expect: 100-continue with the request.
|
|
-- https://tools.ietf.org/html/rfc8297#section-3 Security Considerations
|
|
--
|
|
-- coarse heuristic: simple clients might omit User-Agent request header,
|
|
-- but popular web browsers typically provide User-Agent request header.
|
|
--
|
|
-- A better approach would be to parse User-Agent for versions and selectively
|
|
-- allow specific user agents and versions known to support 103 Early Hints.
|
|
-- (Such a listing is not provided or maintained in this example)
|
|
-- (XXX: such an approach could also be taken in a new lighttpd module in C)
|
|
--
|
|
local ua = lighty.request["User-Agent"]
|
|
if (ua == nil) then return 0 end
|
|
|
|
--
|
|
-- 103 Early Hints
|
|
--
|
|
|
|
local links =
|
|
{
|
|
'<http://server1.example.com>; rel="preconnect"',
|
|
'<http://server2.example.com>; rel="preconnect"'
|
|
}
|
|
|
|
lighty.header["Link"] = table.concat(links, ", ")
|
|
return 103
|