nginx - 常用配置记录

一、nginx内置常用变量

  • 使用curl模拟请求
curl --location --request POST 'http://localhost:8081/ngx_vars?a=1&b=2' \
--header 'Content-Type: application/json' \
--header 'request_id: aabbcc' \
--header 'Authorization: Basic Og==' \
--data-raw '{"hello": "world"}'
  • 使用lua打印nginx内置变量
ngx.req.read_body() -- 读取body

ngx.say("==========print nginx var begin=============\n")

ngx.say("$request => ", ngx.var.request, "\n")

ngx.say("$content_type => ", ngx.var.content_type, "\n")

ngx.say("$request_method => ", ngx.var.request_method)

ngx.say("$uri => ", ngx.var.uri)

ngx.say("$is_args => ", ngx.var.is_args)
ngx.say("$args => ", ngx.var.args)

ngx.say("$query_string => ", ngx.var.query_string)
ngx.say("$request_uri => ", ngx.var.request_uri)
ngx.say("$request_body => ", ngx.var.request_body, "\n")

ngx.say("$document_root => ", ngx.var.document_root)
ngx.say("$document_uri => ", ngx.var.document_uri)
ngx.say("$request_filename => ", ngx.var.request_filename, "\n")

ngx.say("$server_name => ", ngx.var.server_name)
ngx.say("$server_addr => ", ngx.var.server_addr)
ngx.say("$server_port => ", ngx.var.server_port, "\n")

ngx.say("$remote_addr => ", ngx.var.remote_addr)
ngx.say("$remote_port => ", ngx.var.remote_port, "\n")

ngx.say("==========print nginx var end=============\n")

ngx.say("==========print nginx header begin=============\n")

local headers = ngx.req.get_headers()
for k, v in pairs(headers) do
    if type(v) == "table" then
        ngx.say(k..": "..table.concat(v, ",").."\n")
    else
        ngx.say(k..": "..v.."\n")
    end
end

ngx.say("==========print nginx header end=============\n")

ngx.say("==========print nginx uri_args begin=============\n")

local uri_args = ngx.req.get_uri_args()
for k, v in pairs(uri_args) do
    if type(v) == "table" then
        ngx.say(k..": "..table.concat(v, ",").."\n")
    else
        ngx.say(k..": "..v.."\n")
    end
end

ngx.say("==========print nginx uri_args end=============")
  • 打印结果
==========print nginx var begin=============

$request => POST /ngx_vars?a=1&b=2 HTTP/1.1

$content_type => application/json

$request_method => POST
$uri => /ngx_vars
$is_args => ?
$args => a=1&b=2
$query_string => a=1&b=2
$request_uri => /ngx_vars?a=1&b=2
$request_body => {"hello": "world"}

$document_root => ./html
$document_uri => /ngx_vars
$request_filename => ./html/ngx_vars

$server_name => localhost
$server_addr => 127.0.0.1
$server_port => 8081

$remote_addr => 127.0.0.1
$remote_port => 4675

==========print nginx var end=============

==========print nginx header begin=============

host: localhost:8081

content-type: application/json

postman-token: d2b0988e-7476-47a4-97d8-7909924eeab2

accept: */*

cache-control: no-cache

content-length: 18

accept-encoding: gzip, deflate, br

user-agent: PostmanRuntime/7.24.1

connection: keep-alive

authorization: Basic Og==

==========print nginx header end=============

==========print nginx uri_args begin=============

a: 1

b: 2

==========print nginx uri_args end=============

二、nginx - location

location 比较的是$uri内置参数

  • = 优先级最高,绝对匹配
  • ^~ 在正则之前匹配,普通字符串匹配
  • ~~* 正则匹配
  • 在正则之后匹配,普通字符串匹配,可以假想一下,空 = ~$
GET http://localhost:8081/hello?a=1
    location / {
        default_type  text/html;
        content_by_lua 'ngx.say("default route")';
    }
    
    location = /hello {
        default_type  text/html;
        content_by_lua 'ngx.say("= /hello")';
    }
    
    location ^~ /hello {
        default_type  text/html;
        content_by_lua 'ngx.say("^~ /hello")';
    }

    location ~ /hello {
        default_type  text/html;
        content_by_lua 'ngx.say("~ /hello")';
    }
    
    #location /hello {
    #    default_type  text/html;
    #    content_by_lua 'ngx.say("/hello")';
    #}

1、优先匹配location = /hello
2、注销1,优先匹配location ^~ /hello
3、注销2,打开最后一个,优先匹配location ~ /hello
4、注销3,打开最后一个,优先匹配location /hello
5、找不到任何匹配项,会默认匹配location /

三、nginx - rewrite

rewrite,重写的是$uri内置参数,并默认拼接上$args

POST http://localhost:8081/ngx_vars?a=1&b=2
server {
    listen 8081;
    server_name localhost;
    
    location /ngx_vars {
        # 注意看这里
        rewrite ^/(.*)$ /hello?q=$1 last;
        # 关闭lua缓存
        lua_code_cache off;
        default_type  text/html;
        content_by_lua_file conf/lua/test.lua;
    }
    
    location / {
        default_type  text/html;
        content_by_lua 'ngx.say("default route ", ngx.var.args)';
    }
    
    location = /hello {
        default_type  text/html;
        content_by_lua 'ngx.say("= /hello ", ngx.var.args)';
    }
    
    location ^~ /hello {
        default_type  text/html;
        content_by_lua 'ngx.say("^~ /hello ", ngx.var.args)';
    }

    location ~ /hello {
        default_type  text/html;
        content_by_lua 'ngx.say("~ /hello ", ngx.var.args)';
    }
    
    #location /hello {
    #    default_type  text/html;
    #    content_by_lua 'ngx.say("/hello ", ngx.var.args)';
    #}
}
  • 请求结果
= /hello q=ngx_vars&a=1&b=2

我们看到,$1匹配提取的是ngx_vars,然后重写后的路由是/hello?q=ngx_vars&a=1&b=2
$args参数的内容默认拼接到了后面,不想拼接的话,可以在后面加一个问号?,如下

rewrite ^/(.*)$ /hello?q=$1? last;

后面的lua脚本并没有被执行,因为lastflag,表示重新从开头匹配location
如果是break,则中断所有的后续匹配,执行当前的location到最后为止。
我们看看,修改为break以后,nginx内置参数的变化,如下:

==========print nginx var begin=============

$request => POST /ngx_vars?a=1&b=2 HTTP/1.1

$content_type => application/json

$request_method => POST
$uri => /hello
$is_args => ?
$args => q=ngx_vars&a=1&b=2
$query_string => q=ngx_vars&a=1&b=2
$request_uri => /ngx_vars?a=1&b=2
$request_body => {"hello": "world"}

$document_root => ./html
$document_uri => /hello
$request_filename => ./html/hello

$server_name => localhost
$server_addr => 127.0.0.1
$server_port => 8081

$remote_addr => 127.0.0.1
$remote_port => 6508

==========print nginx var end=============

==========print nginx header begin=============

host: localhost:8081

content-type: application/json

postman-token: ac87d63c-1d64-48f2-9f4f-b733a78de6ee

accept: */*

cache-control: no-cache

content-length: 18

accept-encoding: gzip, deflate, br

user-agent: PostmanRuntime/7.24.1

connection: keep-alive

authorization: Basic Og==

==========print nginx header end=============

==========print nginx uri_args begin=============

b: 2

q: ngx_vars

a: 1

==========print nginx uri_args end=============

由此可见,重写以后
变化的有

$uri => /hello
$args => q=ngx_vars&a=1&b=2
$query_string => q=ngx_vars&a=1&b=2

$document_uri => /hello
$request_filename => ./html/hello

没有变化的重点变量为

$request => POST /ngx_vars?a=1&b=2 HTTP/1.1
$request_uri => /ngx_vars?a=1&b=2

另外,值得一说的是breaklast
last:立马跳出当前的location,从头开始逐个匹配新的$uri
break:不会立马跳出location,而是默默的继续执行当前location中的其他代码,然后结束

还有2个flag
redirect:返回302,临时重定向
permanent:返回301,永久重定向

四、nginx - condition - if

1、if的正则表达式有如下匹配
  • =:等值比较
  • ~:区分大小写,匹配
  • ~*:不区分大小写,匹配
  • !~:区分大小写,不匹配
  • !~*:不区分大小写,不匹配
2、if的文件相关的判断
  • -f, !-f:判断文件是否存在
  • -d, !-d:判断目录是否存在
  • -e, !-e:判断文件、目录或者符号链接是否存在
  • -x, !-x:判断文件是否存在且可执行
    location /hello {
        default_type  text/html;
        if ($args ~* "^a=(\d)$") 
        {
            return 401;
        }
        
        if (!-f $request_filename) 
        {
            return 404;
        }
        
        content_by_lua 'ngx.say("= /hello ", ngx.var.args)';
    }

如果参数$argsa=数字,就会401,文件不存在就返回404,否则打印字符串

你可能感兴趣的:(LINUX)