带有变量的nginx动态server_name

时间:2018-05-08 10:29:52

标签: regex nginx nginx-location nginx-reverse-proxy

亲爱的StackOverflow社区我正在与不支持动态GET请求的第三方(例如example.com?variable=somethingDynamic)合作,因此我决定使用自定义子域,但我不想为子域创建子域每一个动态请求所以我一直在想:

如何以捕获两个或三个动态变量的方式编写server_name?

这是我的示例服务器块:

server {
    listen 80;
    server_name someSecretUrl_$variable1_$variable2.example.com;
    root /usr/share/campagins/campagin1;
    client_max_body_size 10000m;
    proxy_connect_timeout 30000;
    location /funnel_webhooks/test {
        return 200;
    }
    location / {
        if ($request_method = 'OPTIONS') {
            # Tell client that this pre-flight info is valid for 20 days
            add_header 'Access-Control-Max-Age' 1728000;
            add_header 'Content-Type' 'text/plain charset=UTF-8';
            add_header 'Content-Length' 0;
            add_header 'Access-Control-Allow-Origin' "$http_origin" always;
            add_header 'Access-Control-Allow-Credentials' 'true' always;
            add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always;
            add_header 'Access-Control-Allow-Headers' 'Accept,Authorization,Cache-Control,Content-Type,DNT,If-Modified-Since,Keep-Alive,Origin,User-Agent,X-Requested-With,Etag,Last-Modified,HTTP_IF_MODIFIED_SINCE,HTTP_IF_NONE_MATCH' always;
            return 204;
        }
        add_header 'Access-Control-Allow-Origin' "$http_origin" always;
        add_header 'Access-Control-Allow-Credentials' 'true' always;
        add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always;
        add_header 'Access-Control-Allow-Headers' 'Accept,Authorization,Cache-Control,Content-Type,DNT,If-Modified-Since,Keep-Alive,Origin,User-Agent,X-Requested-With,Etag,Last-Modified,HTTP_IF_MODIFIED_SINCE,HTTP_IF_NONE_MATCH,ETag,Retry-After' always;
        add_header 'Access-Control-Expose-Headers' 'ETag,Retry-After' always;
        add_header 'Cache-Control' "must-revalidate, post-check=0, pre-check=0" always;
        rewrite ^(.*)$ $1?preMadeDataParsers=$variable1&preMadeDataParsersOnResponse=$variable2&$args break;
        proxy_buffering off;
        proxy_pass http://localhost:3000; #proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header REMOTE_ADDR $remote_addr;
    }
}

看看上面的代码,你会注意到我正在尝试将$ variable1移动到一个GET变量中,而将$ variable2移动到另一个get变量中,我怎么能实现这样的呢? 谢谢!

1 个答案:

答案 0 :(得分:1)

我不会在nginx中这样做,我会在你的应用程序中这样做。 (特别是如果您希望扩展此资源。)

我会将服务器配置为在没有虚拟主机的情况下侦听IP,以便它回应对IP发出的任何请求。只需省略server_name指令:

server {
    listen 1.2.3.4:80;
    ...

然后使用通配符条目配置DNS,以便* .example.com指向该IP。现在你可以点击any_string.example.com它将解析为你的IP,得到主服务器块的回答,并传递给你的应用程序。

然后,在您的应用内,查看请求的主机名。 (例如,在PHP中,这可以通过$_SERVER['HTTP_HOST']获得。)如果您的应用确定所请求的主机名无效,请发出404并退出。否则,解码主机名并处理请求。

这样,您可以在不编辑nginx配置的情况下添加新变量和新功能。您甚至可以用JSON编码变量,然后BASE64对它们进行编码:

$vars = [
    'var1' => 'one',
    'var2' => 'two',
    'var3' => 'three',
];
$url = base64_encode(json_encode($vars));

eyJ2YXIxIjoib25lIiwidmFyMiI6InR3byIsInZhcjMiOiJ0aHJlZSJ9.example.com

现在,您可以使用任何名称传递任意数量的变量,包括索引和关联数组。 (虽然请注意域名长度有限制,您必须对+/字符执行某些操作,我确信这些字符在域名中无效。)