如何在nginx配置文件中对变量进行简单的数学计算

时间:2016-11-17 03:45:48

标签: nginx reverse-proxy

无论如何,我可以对ngnix配置文件进行简单的数学计算。假设我想基于主机域进行代理传递。当前缀为0到9时,我能够将主机重定向到正确的端口号。但我真正想要的是前缀10到端口1410.但是根据我现在的配置,它将代理到端口14010

主机:
http://prefix0.domain.com - > 127.0.0.1:1400
http://prefix10.domain.com - > 127.0.0.1:1410
http://prefix99.domain.com - > 127.0.0.1:1499

server {
    listen       80;
    server_name ~^(prefix(?<variable>[0-9]+)).domain.com;

    location  / {
        proxy_pass http://127.0.0.1:140$variable;
    }
}

3 个答案:

答案 0 :(得分:2)

使用ngx-perlngx-lua模块可以轻松完成此操作。但是如果你没有安装它们或者只是在寻找一个老派的解决方案,那么有一种方法可以通过良好的旧rewrite魔术和正则表达式解决问题:

server {
    listen       80;
    server_name ~^(prefix(?<variable>[0-9]+)).domain.com;

    location  / {
        # Since it's always wise to validate the input, let's
        # make sure there's no more than two digits in the variable.
        if ($variable ~ ".{3}") { return 400; }

        # Initialize the port variable with the value.
        set $custom_port 14$variable;

        # Now, depending on the $variable, $custom_port can contain 
        # values like 1455, which is correct, or like 149, which is not.

        # Nginx does not have any functions like "replace" that could be 
        # used on random variables. However, the rewrite directive can
        # replace strings using regular expression patterns. The only 
        # problem is that the rewrite only works with one specific variable,
        # namely, $uri.

        # So the trick is to assign the $uri with the string we want to change,
        # make necessary replacements and then restore the original value or 
        # the $uri:

        if ($custom_port ~ "^.{3}$") {  # If there are only 3 digits in the port
            set $original_uri $uri;     # Save the current value of $uri
            rewrite ^ $custom_port;     # Assing the $uri with the wrong port
            rewrite 14(.) 140$1;        # Put an extra 0 in the middle of $uri
            set $custom_port $uri;      # Assign the port with the correct value
            rewrite ^ $original_uri;    # And restore the $uri variable
        }

        proxy_pass http://127.0.0.1:$custom_port;
    }
}

答案 1 :(得分:1)

替代(我会说更简洁)的方法是在配置中使用硬编码/自动生成的地图,如下所示:

map $prefix $custom_port {
  0    1400
  10   1410
  99   1499 
  # any other values/numbers 
}

server {
    server_name ~^(prefix(?<prefix>[0-9]+)).domain.com;
    location / {
        proxy_pass http://127.0.0.1:$custom_port;
    }
}

答案 2 :(得分:0)

是的,事实证明我只需要写     设置$ custom_port $ variable;     if($ custom_port~“^。{3} $”){         设置$ custom_port 140 $ variable;     }