Nginx配置文件中if的&&和||的实现(nginx不支持&&和||的写法)
1.与(&&)的写法:
set $condiction '';
if ($http_user_agent ~ "Chrome"){
set $condiction a;
}
if ($args ~ "r=hao123"){
set $condiction "${condiction}b";
}
if ($condiction = ab){
rewrite ^/(.*)$ https://www.hao123.com/?tn=94408350_hao_pg;
}
说明:当浏览器是Chrome并且url的参数是r=hao123的时候做重定向。
rewrite有四个flag,不带flag时默认是redirect(302),如下:
1)last(重写后的规则,会继续用重写后的值去匹配下面的location。)
2)break(重写后的规则,不会去匹配下面的location。使用新的规则,直接发起一次http请求了。)
3)permanent(301永久重定向,搜索引擎在抓取新内容的同时也将旧的网址替换为重定向之后的网址)
4)redirect(302临时重定向,搜索引擎会抓取新的内容而保留旧的网址)(网站换量的场景下使用)
2.或(||)的写法:
set $condiction 0;
if ($http_x_forwarded_for ~ " ?xxx.xxx.xxx.xx1$"){
set $condiction 1;
}
if ($http_x_forwarded_for ~ " ?xxx.xxx.xxx.xx2$"){
set $condiction 1;
}
if ($condiction){
rewrite ^/(.*)$ https://www.hao123.com/?tn=94408350_hao_pg;
}
说明:当ip是xxx.xxx.xxx.xx1或xxx.xxx.xxx.xx2的时候做重定向。
3.结合上面两段代码,实现禁止IP访问,禁止Chrome浏览器并且url参数是r=hao123的访问。
set $condiction1 true;
set $condiction2 '';
if ($http_user_agent ~ "Chrome") {
set $condiction2 a;
}
if ($args ~ "r=hao123") {
set $condiction2 "${condiction2}b";
}
if ($condiction2 = ab) {
set $condiction1 false;
}
if ($http_x_forwarded_for ~ " ?xxx.xxx.xxx.xx1$") {
set $condiction1 false;
}
if ($http_x_forwarded_for ~ " ?xxx.xxx.xxx.xx2$") {
set $condiction1 false;
}
if ($condiction1 = false) {
return 403;
}
扩展:nginx+lua,实现upstream是由lua从redis中读取配置动态生成的。
server {
listen 80;
server_name _;
server_name_in_redirect off;
port_in_redirect off;
root /root/html;
location / {
set $upstream "";
rewrite_by_lua '
-- load global route cache into current request scope
-- by default vars are not shared between requests
local routes = _G.routes
-- setup routes cache if empty
if routes == nil then
routes = {}
ngx.log(ngx.ALERT, "Route cache is empty.")
end
-- try cached route first
local route = routes[ngx.var.http_host]
if route == nil then
local redis = require "redis"
local client = redis.connect("localhost", 6379)
route = client:get(ngx.var.http_host)
end
-- fallback to redis for lookups
if route ~= nil then
ngx.var.upstream = route
routes[ngx.var.http_host] = route
_G.routes = routes
else
ngx.exit(ngx.HTTP_NOT_FOUND)
end
';
proxy_buffering off;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_redirect off;
proxy_connect_timeout 10;
proxy_send_timeout 30;
proxy_read_timeout 30;
proxy_pass http://$upstream;
}
}