/ 中存储网

Nginx服务器配置中nginx_lua相关的变量

2014-04-09 10:25:01 来源:IT技术网
1、设定变量返回

server {

listen 8080;

location /test {

set $foo hello;

echo "foo: $foo";

}

}

2、输出$

geo $dollar {

default "$";

}

server {

listen 8080;

location /test {

echo "This is a dollar sign: $dollar

}

}

结果

$ curl 'http://localhost:8080/test'

This is a dollar sign: $

3、区分空格

server {

listen 8080;

location /test {

set $first "hello ";

echo "${first}world";

}

}

结果:

$ curl 'http://localhost:8080/test

hello world

4、变量上下文

Nginx 变量名的可见范围虽然是整个配置,但每个请求都有所有变量的独立副本,或者说都有各变量用来存放值的容器的独立副本,彼此互不干扰

5、内部跳转

server {

listen 8080;

location /foo {

set $a hello;

echo_exec /bar;  //通rewrite ^/bar

}

location /bar {

echo "a = [$a]";

}

}

echo_exec 配置指令,发起到

location /bar 的“内部跳转”。

Nginx变量值容器的生命期是与当前正在处理的请求绑定的,而与 location无关

6、nginx内建变量

Nginx 内建变量最常见的用途就是获取关于请求或响应的各种信息

location /test {

echo "uri = $uri";

echo "request_uri = $request_uri

}

运行结果

$ curl 'http://localhost:8080/test?a=3&b=4'

uri = /test

request_uri = /test?a=3&b=4

7、$arg_XXX

另一个特别常用的内建变量其实并不是单独一个变量,而是有无限多变种的一群变量,即名字以 arg_开头的所有变量,我们估且称之为$arg_XXX 变量群。一个例子是$arg_name,这个变量的值是当前请求名为 name 的 URI 参数的值,而且还是未解码的原始形式的值

location /test {

echo "name: $arg_name";

echo "class: $arg_class";

}

$ curl 'http://localhost:8080/test?name=Tom&class=3'

name: Tom

class: 3

$ curl 'http://localhost:8080/test?name=hello%20world&class=9'

name: hello%20world

class: 9

Nginx 会在匹配参数名之前,自动把原始请求中的参数名调整为全部小写的形式

8、对 URI 参数值中的 %XX 这样的编码序列进行解码

set_unescape_uri $name

9、比如用来取 cookie 值的$cookie_XXX 变量群,用来取请求头的 $http_XXX 变量群,以及用来取响应头的 $sent_http_XXX 变量群。可以参考 ngx_http_core 模块的官方文档

10、修改 $args 变量影响标准的 HTTP 代理模块 ngx_proxy 的例子

 server {

        listen 8080;

        location /test {

            set $args "foo=1&bar=2";

            proxy_pass http://127.0.0.1:8081/args;

        }

    }

    server {

        listen 8081;

        location /args {

            echo "args: $args";

        }

    }

运行结果

$ curl 'http://localhost:8080/test?blah=7'

args: foo=1&bar=2

11、ngx_map

 map $args $foo {

        default     0;

        debug       1;

    }

    server {

        listen 8080;

        location /test {

            set $orig_foo $foo;

            set $args debug;

            echo "orginal foo: $orig_foo";

            echo "foo: $foo";

        }

    }

当 $args 的值等于 debug 的时候,$foo 变量的值就是 1,否则 $foo 的值就为 0.

ngx_map 模块认为变量间的映射计算足够昂贵,需要自动将因变量的计算结果缓存下来,这样在当前请求的处理过程中如果次读取这个因变量,Nginx 就可以直接返回缓存住的结果,而不再调用该变量的“取处理程序”再行计算了。

    $ curl 'http://localhost:8080/test'

    original foo: 0

    foo: 0

    $ curl 'http://localhost:8080/test?debug'

    original foo: 1

    foo: 1

在上面的例子中,我们还应当注意到 map 指令是在 server 配置块之外,也就是在最外围的 http 配置块中定义的。很多读者可能会对此感到奇怪,毕竟我们只是在location /test 中用到了它。这倒不是因为我们不想把 map 语句直接挪到location 配置块中,而是因为 map 指令只能在 http 块中使用!

12、子请求

location /main {

echo_location /foo;

echo_location /bar;

}

location /foo {

echo foo;

}

location /bar {

echo bar;

}

“子请求”方式的通信是在同一个虚拟主机内部进行的,所以 Nginx 核心在实现“子请求”的时候,就只调用了若干个 C 函数,完全不涉及任何网络或者 UNIX 套接字(socket)通信

13、子请求变量

    location /main {

        echo "main args: $args";

        echo_location /sub "a=1&b=2";

    }

    location /sub {

        echo "sub args: $args";

    }

运行结果:

    $ curl 'http://localhost:8080/main?c=3'

    main args: c=3

    sub args: a=1&b=2

但不幸的是,并非所有的内建变量都作用于当前请求。少数内建变量只作用于“主请求”,比如由标准模块 ngx_http_core 提供的内建变量$request_method.变量 $request_method。

变量 $request_method 在读取时,总是会得到“主请求”的请求方法,比如 GET、POST 之类。

为了达到我们最初的目的,我们需要求助于第三方模块 ngx_echo 提供的内建变量 $echo_request_method:

    location /main {

        echo "main method: $echo_request_method";

        echo_location /sub;

    }

    location /sub {

        echo "sub method: $echo_request_method";

    }

此时的输出终于是我们想要的了:

    $ curl --data hello 'http://localhost:8080/main'

    main method: POST

    sub method: GET

14、变量找不到和空字符串

ngx_lua,我们可以轻松地在 Lua 代码中做到这一点

 location /test {

        content_by_lua '

            if ngx.var.arg_name == nil then

                ngx.say("name: missing")

            else

                ngx.say("name: [", ngx.var.arg_name, "]")

            end

        ';

    }

15、我们可以选择在 Nginx不同的请求处理阶段插入我们的Lua 代码。这些 Lua 代码既可以直接内联在 Nginx 配置文件中,也可以单独放置在外部 .lua 文件里,然后在 Nginx 配置文件中引用 .lua文件的路径。

16、ngx.var

回到上面这个例子,我们在 Lua 代码里引用 Nginx 变量都是通过ngx.var 这个由 ngx_lua 模块提供的Lua 接口。比如引用 Nginx 变量$VARIABLE 时,就在 Lua 代码里写作 ngx.var.VARIABLE 就可以了。当 Nginx 变量 $arg_name 为特殊值“没找到”(或者“不合法”)时,ngx.var.arg_name 在 Lua 世界中的值就是 nil,即 Lua 语言里的“空”(不同于 Lua 空字符串)。我们在 Lua 里输出响应体内容的时候,则使用了 ngx.say 这个 Lua 函数,也是 ngx_lua 模块提供的,功能上等价于 ngx_echo 模块的 echo配置指令。

17、nil值

在 Lua 里访问未创建的 Nginx 用户变量时,在 Lua 里也会得到 nil 值,而不会像先前的例子那样直接让 Nginx 拒绝加载配置:

location /test {

content_by_lua '

ngx.say("$blah = ", ngx.var.blah)

';

}     curl 'http://localhost:8080/test'

$blah = nil