Project

General

Profile

AbsoLUAtion » early-hints.lua

RFC 8297 An HTTP Status Code for Indicating Hints (103 Early Hints) - gstrauss, 2020-09-20 08:27

 
-- 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
(2-2/6)