Uncategorized

Dynamically Replacing Text in Static Files with Nginx Using Lua

September 24, 2025 Rich 2 min read

I have my PowerShell tool, LanScan, that I serve from my server so it can be executed on a machine with irm techish.net/lanscan | iex. I have a few different domains and I want to be able to change some text inside the lanscan file on-the-fly. I’m going to replace SERVER_NAME inside the file with the value of Nginx’s $server_name using Lua.

You might try using Nginx’s sub_filter module:

location ^~ /lanscan {
    alias /var/www/static/lanscan;
    default_type text/plain;
    sub_filter 'SERVER_NAME' $server_name;
    sub_filter_once off;
}

However, this won’t work as expected. The reason is that sub_filter does not evaluate Nginx variables. $server_name is treated as a literal string, so the replacement never happens dynamically.


Solution: Use Lua for Dynamic Replacement

The ngx_http_lua_module (used in OpenResty or compiled into Nginx) allows you to process files dynamically and replace placeholders using Lua scripting.

Here’s a minimal example:

location ^~ /lanscan {
    default_type text/plain;

    content_by_lua_block {
        -- Path to your static file
        local file_path = "/var/www/static/lanscan/index.txt"

        -- Open the file
        local file = io.open(file_path, "r")
        if not file then
            ngx.status = 404
            ngx.say("File not found")
            return
        end

        -- Read the entire file
        local content = file:read("*all")
        file:close()

        -- Replace SERVER_NAME with the actual Nginx server_name
        content = content:gsub("SERVER_NAME", ngx.var.server_name)

        -- Output the modified content
        ngx.say(content)
    }
}

How It Works

  1. The file is read into memory using Lua’s io.open.
  2. The gsub function searches for the placeholder SERVER_NAME and replaces it with the value of ngx.var.server_name.
  3. The modified content is returned to the client dynamically.

Benefits

  • Works for any placeholder in static files.
  • Dynamic replacement based on the current request.
  • Avoids modifying the original file on disk.
  • More flexible than sub_filter for dynamic content.

When to Use

  • You need per-request dynamic replacements.
  • The replacement value comes from an Nginx variable like $server_name, $host, or custom headers.
  • Static preprocessing (e.g., sed) is not desirable.

Leave a comment