feat: perform just one pass to replace pool mirrors

This commit is contained in:
Iain Learmonth 2025-05-04 15:34:48 +01:00
parent 99f7a5d635
commit 61d66a5d45
3 changed files with 28 additions and 30 deletions

View file

@ -1,3 +1,5 @@
local utils = require "utils"
local function matomo_tracking_code(site_id) local function matomo_tracking_code(site_id)
return [=[ return [=[
<!-- Matomo --> <!-- Matomo -->
@ -21,21 +23,14 @@ local function matomo_tracking_code(site_id)
]=] ]=]
end end
local function rewrite_body(body, eof) local function rewrite_body(body)
if not ngx.ctx.jasima_pool_map or ngx.ctx.jasima_config.rewrite_disable then -- Rewrite links for assets and outbound links to other mirrored sites
return body local pool_map = ngx.ctx.jasima_pool_map
if pool_map then
body = body:gsub("//([a-zA-Z0-9%.%-]+%.[a-zA-Z0-9]+)/", utils.get_mirror)
end end
for from, to in pairs(ngx.ctx.jasima_pool_map) do -- Add Matomo tracking code
if ngx.ctx.jasima_config.rewrite_case_insensitive then if ngx.ctx.jasima_config.matomo_site_id then
local pattern = ngx.re.escape(from)
body = ngx.re.gsub(body, pattern, to, "ijo")
else
-- We expect that str:match("^[%w%-%.]+$") ~= nil
local pattern = from:gsub("([%^%$%(%)%%%.%[%]%*%+%-%?])", "%%%1") -- escape Lua patterns
body = body:gsub(pattern, to)
end
end
if eof and ngx.ctx.jasima_config.matomo_site_id then
body = body:gsub("</body>", matomo_tracking_code(ngx.ctx.jasima_config.matomo_site_id)) body = body:gsub("</body>", matomo_tracking_code(ngx.ctx.jasima_config.matomo_site_id))
-- TODO: Ensure that tracking code was added when it's HTML, but only for HTML -- TODO: Ensure that tracking code was added when it's HTML, but only for HTML
end end
@ -65,13 +60,13 @@ if ngx.ctx.rewriting then
if #ngx.ctx.buffered > 5 * 1024 * 1024 and not eof then if #ngx.ctx.buffered > 5 * 1024 * 1024 and not eof then
-- Don't just consume memory forever -- Don't just consume memory forever
ngx.arg[1] = rewrite_body(ngx.ctx.buffered, eof) -- We still do our best ngx.arg[1] = rewrite_body(ngx.ctx.buffered) -- We still do our best
ngx.ctx.rewriting = false ngx.ctx.rewriting = false
return return
end end
if eof then if eof then
ngx.arg[1] = rewrite_body(ngx.ctx.buffered, eof) ngx.arg[1] = rewrite_body(ngx.ctx.buffered)
else else
ngx.arg[1] = nil ngx.arg[1] = nil
end end

View file

@ -1,4 +1,9 @@
-- Determine if we rewrite the body of this type of content local utils = require "utils"
if ngx.ctx.jasima_config.rewrite_disable then
return
end
if ngx.header["Content-Type"] then if ngx.header["Content-Type"] then
local content_type = ngx.header["Content-Type"] local content_type = ngx.header["Content-Type"]
if content_type:find("text/html") or if content_type:find("text/html") or
@ -14,19 +19,10 @@ if ngx.header["Content-Type"] then
end end
end end
-- Rewrite any redirects from the origin to point at a mirror
if ngx.header["Location"] then if ngx.header["Location"] then
if ngx.ctx.jasima_pool_map and not ngx.ctx.jasima_config.rewrite_disable then local pool_map = ngx.ctx.jasima_pool_map
if ngx.ctx.rewriting and pool_map then
local location = ngx.header["Location"] local location = ngx.header["Location"]
for from, to in pairs(ngx.ctx.jasima_pool_map) do ngx.header["Location"] = location:gsub("//([a-zA-Z0-9%.%-]+%.[a-zA-Z0-9]+)/", utils.get_mirror)
if ngx.ctx.jasima_config.rewrite_case_insensitive then
local pattern = ngx.re.escape(from)
location = ngx.re.gsub(location, pattern, to, "ijo")
else
local pattern = from:gsub("([%^%$%(%)%%%.%[%]%*%+%-%?])", "%%%1") -- escape Lua patterns
location = location:gsub(pattern, to)
end
end
ngx.header["Location"] = location
end end
end end

View file

@ -72,4 +72,11 @@ function _M.filter_bogons(ip_list)
return filtered return filtered
end end
function _M.get_mirror(host)
ngx.log(ngx.DEBUG, "Looking up mirror for " .. host)
local host_lower = host:lower()
local mirror = ngx.ctx.jasima_pool_map[host_lower]
return "//" .. (mirror or host) .. "/"
end
return _M return _M