Nginx处理请求时的匹配规则详析
nginx在收到一条请求时将先通过server_name匹配一个server,然后使用server中的location继续匹配.
匹配server_name
在nginx中,server_name决定了当收到一个请求后哪一个server会被使用.nginx会使用请求头中的Host字段与server_name进行匹配.定义server_name时可以使用完全名称、通配符名称、正则表达式名称,它们的匹配顺序如下:
- 完全匹配
- 前通配符匹配,即*.example.org
- 后通配符匹配,即mail.*
- 正则表达式匹配
如果没有匹配到结果,将会使用default_server进行处理,如果没有定义,则第一个定义的为default_server.使用三个简单的server作为例子,让他们监听80端口,server_name分别设置为*.org、*.net、*.com:
server{ listen80; server_nameexample.orgwww.example.org; return401; } server{ listen80; server_nameexample.netwww.example.net; return402; } server{ listen80; server_nameexample.comwww.example.com; return403; }
在上面的配置中,默认的服务器为第一个,随便访问一个不存在的server将会返回401.不过可以使用default_server手动设置一个默认主机,default_server设置在listen字段,如下:
server{ listen80default_server; server_nameexample.netwww.example.net; }
之后再匹配时,未匹配到将会使用这个server.
禁止访问
如果想要禁止一个没有携带Host字段的请求,可以定义如下server:
server{ listen80; server_name""; return444; }
server_name定义为空字符串,如果Host字段为空或不存在,将会匹配到这个server,然后返回404状态码.
Nginx的444状态比较特殊,如果返回444那么客户端将不会收到服务端返回的信息,就像是网站无法连接一样,浏览器直接显示502.但是如果使用反向代理,还是显示正常状态码
如果想要禁止访问不存在的主机,可以这样定义:
server{ listen80default_server; server_name_; return444; }
_在这里没有任何特别含义,因为一个域名中不会出现_,所以不会与任何真实的域名相同,使用其他非法字符是相同的道理.
同时匹配IP和server_name
现在来看一下对于监听不同IP和不同server_name混合使用时是如何处理的:
server{ listen192.168.1.1:80; server_nameexample.orgwww.example.org; } server{ listen192.168.1.1:80; server_nameexample.netwww.example.net; } server{ listen192.168.1.2:80; server_nameexample.comwww.example.com; }
在这个配置中,nginx首先匹配IP,匹配到后再匹配它们的server_name,如果没有匹配到server_name,则使用到它们默认的server.举个例子,如果一个域名为www.example.com的请求来自192.168.1.1:80.但是监听192.168.1.1:80的server只有两个,这两个都不能匹配www.example.com,那么就使用这两个server中的默认主机,由于没有使用defualt_server定义监听,所以默认为第一个即www.example.org这个server.当然你可以定义defualt_server:
server{ listen192.168.1.1:80; server_nameexample.orgwww.example.org; } server{ listen192.168.1.1:80default_server; server_nameexample.netwww.example.net; } server{ listen192.168.1.2:80default_server; server_nameexample.comwww.example.com; }
匹配location
在nginx匹配到一个server后,就会通过location继续处理请求,下面是一个示例:
server{ listen172.17.0.3:80; server_name_; location/{ return401; } location~*\.(gif|jpg|png)${ return402; } location~*\.(gif|jpg|png)${ return404; } location/api{ return403; } }
nginx首先会在所有的location中搜索前缀进行匹配,匹配到前缀后,将按顺序匹配使用正则表达式定义的location,匹配到就结束,如果没有匹配到,则使用之前匹配到前缀的那个location进行处理,下面是具体匹配的例子:
- 一个/x.gif请求,首先匹配到的前缀为/,然后使用剩下的x.gif跟location的正则去匹配,先匹配到了location~*\.(gif|jpg|png)$,返回402.
- 一个/x.pdf请求,由于x.pdf无法被匹配到,所以使用location/进行处理.
- 一个/api/x.gif,首先匹配到前缀为/api,然后使用剩下的x.gif跟location的正则去匹配,先匹配到了location~*\.(gif|jpg|png)$,返回402.
- 一个/api/x.pdf请求,由于x.pdf无法被匹配到,所以使用location/api进行处理.
参考
- Hownginxprocessesarequest
- servernames
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对毛票票的支持。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。