Search code examples
nginxluaopenresty

Nginx variable names are lost between OpenResty captures


When creating a variable from the server_name in Nginx and calling a different endpoint using ngx.location.capture the variable is then gone.

The following example demonstrates by calling testlocalhost and acclocalhost:

server {
    listen 1003;
    server_name ~^(?<name>test|acc)localhost$; #<-Name is set here

    location / {
        #return 200 $name; #This would return the expected test or acc
        content_by_lua 'local options = {
                            method = ngx.HTTP_GET,
                        }
                        local res = ngx.location.capture("/internal", options)
                        ngx.say(res.body)';
    }

    location /internal {   
        return 200 $name; #<- Name is empty here
    }
}

Is there any way to maintain the variable between endpoints without modifying the body or using url parameters?


Solution

  • You need to add to the option to ngx.location.capture to share or copy all available variables.

    https://github.com/openresty/lua-nginx-module#ngxlocationcapture

    copy_all_vars specify whether to copy over all the Nginx variable values of the current request to the subrequest in question. modifications of the nginx variables in the subrequest will not affect the current (parent) request. This option was first introduced in the v0.3.1rc31 release.

    share_all_vars specify whether to share all the Nginx variables of the subrequest with the current (parent) request. modifications of the Nginx variables in the subrequest will affect the current (parent) request. Enabling this option may lead to hard-to-debug issues due to bad side-effects and is considered bad and harmful. Only enable this option when you completely know what you are doing.

        location / {
            #return 200 $name; #This would return the expected test or acc
            content_by_lua 'local options = {
                                method = ngx.HTTP_GET,
                                share_all_vars = true
                            }
                            local res = ngx.location.capture("/internal", options)
                            ngx.say(res.body)';
        }