Nginx中if条件语句不支持proxy_set_header的解决方案

转:Nginx中if条件语句不支持proxy_set_header的解决方案 | CHEGVA

最近开发有个需求,需要通过一个域名加国家地区代码跳转到不同机房的服务。由于中间还要走一层ingress,需要设置下指定域名的头,ingress才能打到指定后端服务。

在if语句中通过proxy_set_header来实现,发现nginx不支持,检测会报错:

nginx: [emerg] "proxy_set_header" directive is not allowed here in /home/anzhihe/app/nginx/conf/vhost/global.chegva.com.conf:12

网上查了下,主要有两种解决方案,通过if加设置变量来解决或者使用map。

The "if" directive is a block directive and creates a separate context (or, rather, two separate contexts - "if in server", "if in location"). When a directive is allowed in a specific context, this is explicitly documented. For example, the set directive:

Context: server, location, if

So the set directive is allowed inside serverlocation, and if blocks.

The proxy_set_header is not allowed inside if blocks, and there are no plans to change this. If you want to pass headers conditionally, consider using proxy_set_header with values set conditionally instead, for example:

# default value is empty
set $x_value "";

if ($arg_test) {
    set $x_value "present only when test argument set";
}

# the header will be only sent if $x_value is not empty
proxy_set_header X-Header $x_value;

You may also use map to provide a value. Depending on the particular use case it may also be a better idea to use distinct server or location blocks instead.

if statements aren't a good way of setting custom headers because they may cause statements outside the if block to be ignored.

You can use a map directive instead which is not prone to the same problems.

# outside server blocks
map $http_X_Amz_Cf_Id $is_cloudfront {
    default "No";
    ~. "Yes"; # Regular expression to match any value
}

Then:

# inside location block
proxy_set_header X_Custom_Header $is_cloudfront;

最终配置如下:

upstream sgp_chegva_com {
        server sgp-pubproxy.chegva.com:443 weight=1 max_fails=2 fail_timeout=10s;
        check interval=3000 rise=3 fall=3 timeout=1000 type=tcp default_down=false;
}

upstream ind_chegva_com {
        server ind-pubproxy.chegva.com:443 weight=1 max_fails=2 fail_timeout=10s;
        check interval=3000 rise=3 fall=3 timeout=1000 type=tcp default_down=false;
}

server {
    listen 80;
    server_name global.chegva.com;

    access_log /home/anzhihe/logs/nginx/global.chegva.com.log mainproxy;
    error_log /home/anzhihe/logs/nginx/global.chegva.com.err;
    error_page   403 404 500 502 503 504  https://chegva.com/error.html;

    set $is_matched 0;
    if ($request_uri ~* ^/([^/]*)/?(.*)) {
            set $local $1;
    }

    location / {
    	if ($local = "es|it|us|uk|de|fr|jp") {
    		set $domain_name "sgp.chegva.com";
    		set $proxy_backend "sgp_chegva_com";
    		set $is_matched 1;
    	}
    	if ($is_matched = 0) {
    		set $domain_name "global.chegva.com";
    		set $proxy_backend "ind_chegva_com";
    	}
    	proxy_set_header Host $domain_name;
    	proxy_pass http://$proxy_backend;
    }
}

参考:

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值