{# roles/sys-srv-web-inj-compose/templates/location.lua.j2 #} {% macro push_snippets(list_name, features) -%} {% set kind = list_name | regex_replace('_snippets$','') %} {% for f in features if inj_enabled.get(f) -%} {{ list_name }}[#{{ list_name }} + 1] = [=[ {%- include 'roles/sys-srv-web-inj-' ~ f ~ '/templates/' ~ kind ~ '_sub.j2' -%} ]=] {% endfor -%} {%- endmacro %} lua_need_request_body on; header_filter_by_lua_block { local ct = ngx.header.content_type or "" if ct:lower():find("^text/html") then ngx.ctx.is_html = true else ngx.ctx.is_html = false end } body_filter_by_lua_block { -- only apply further processing if this is an HTML response if not ngx.ctx.is_html then return end -- initialize or reuse the buffer ngx.ctx.buf = ngx.ctx.buf or {} local chunk, eof = ngx.arg[1], ngx.arg[2] if chunk ~= "" then table.insert(ngx.ctx.buf, chunk) end if not eof then -- drop intermediate chunks; we’ll emit only on eof ngx.arg[1] = nil return end -- on eof: concatenate all buffered chunks local whole = table.concat(ngx.ctx.buf) ngx.ctx.buf = nil -- clear buffer -- remove html CSP, due to management via Infinito.Nexus policies whole = whole:gsub( ']-http%-equiv=["\']Content%-Security%-Policy["\'][^>]->%s*', '' ) -- build a list of head-injection snippets local head_snippets = {} {{ push_snippets('head_snippets', inj_head_features) }} -- inject all collected snippets right before local head_payload = table.concat(head_snippets, "\n") .. "" whole = ngx.re.gsub(whole, "", head_payload, "ijo", nil, 1) -- build a list of body-injection snippets local body_snippets = {} {{ push_snippets('body_snippets', inj_body_features) }} -- inject all collected snippets right before local body_payload = table.concat(body_snippets, "\n") .. "" whole = ngx.re.gsub(whole, "", body_payload, "ijo", nil, 1) -- finally send the modified HTML out ngx.arg[1] = whole }