【问题标题】:Nginx routing rewrite configNginx 路由重写配置
【发布时间】:2015-04-03 01:16:54
【问题描述】:

目前我通过为 nginx 定义以下服务器块将所有 http 流量路由到 https。

server {
  listen 80;
  server_name someserver.xyz www.someserver.xyz;
  rewrite ^ https://someserver.xyz$request_uri? permanent;
}

server {
  listen 443;
  server_name someserver.xyz;
  location / {
    proxy_next_upstream error timeout http_500 http_502 http_503 http_504;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_set_header X-NginX-Proxy true;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_buffer_size 8k;
    proxy_http_version 1.1;
    proxy_read_timeout 900;
    proxy_connect_timeout 900;
    proxy_pass http://desktop_upstream;
    proxy_redirect off;
  }
}

但是,对于特定的 url 模式,我不希望将 http 流量路由到 https:

http://someserver.xyz/s/[anything]

例如。 http://someserver.xyz/s/blah 不会从 http 重写为 https。像http://someserver.xyz/dudehttp://someserver.xyz/s 等其他任何东西仍然会重写。

我尝试修改 rewrite 指令中的正则表达式(以匹配除上述模式之外的所有内容)以及在第一个服务器块中添加一个位置块:

server {
  listen 80;
  server_name someserver.xyz www.someserver.xyz;
  rewrite ^.+\.xyz\/(?!s\/).* https://someserver.xyz$request_uri? permanent;
  location / {
    proxy_next_upstream error timeout http_500 http_502 http_503 http_504;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_set_header X-NginX-Proxy true;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_buffer_size 8k;
    proxy_http_version 1.1;
    proxy_read_timeout 900;
    proxy_connect_timeout 900;
    proxy_pass http://desktop_upstream;
    proxy_redirect off;
  }   
}

这个新的服务器块有时会将所有 http 流量重写为 https(所有模式),有时不会将任何 http 流量重写为 https。

我知道正则表达式在我测试过的情况下有效。我想象的http流量发生的是:

  1. 命中第一个服务器块,判断是否重写为https。

  2. 如果它确实重写,它将命中第二个服务器块并转到第二个服务器块的位置。

  3. 如果不重写,它将转到第一个服务器块的位置。

我在这里做错了吗?感谢您的帮助!

【问题讨论】:

    标签: regex nginx url-rewriting rewrite pcre


    【解决方案1】:

    在 http 服务器中使用两个位置块可以简单地解决这个问题,而无需执行任何 if 条件

    server {
      listen 80;
      server_name example.com www.example.com;
      root /path/to/root;
      location ^~ /s/(.+) {
        # try_files or whatever;
      }
      location / {
        return 301 https://$server_name$request_uri;
      }
    }
    server {
      listen 443 ssl;
      server_name example.com;
      root /path/to/root;
      location / {
        # the whole proxy here
      }
    }
    

    【讨论】:

      【解决方案2】:

      您的第二次重写将不起作用,因为您正在尝试匹配包括域部分在内的整个请求字符串,但重写适用于 URIs

      http://nginx.org/en/docs/http/ngx_http_rewrite_module.html#rewrite

      这就是你需要的

      server {
        listen 80;
        server_name someserver.xyz www.someserver.xyz;
        if ($request_uri !~ ^/s/ ) {
          return 301 https://someserver.xyz$request_uri?;
        }
        # continue without redirect
      }
      

      我将“rewrite”改为“return”只是因为我更喜欢它,它似乎更具可读性:)

      【讨论】:

      • 我试过这个并重新启动了 nginx,但它仍然重写了模式。我想确保我理解$request_uri !~ ^/s/!~ 表示不等于?
      • 意思是“不匹配正则表达式”。如果我正确理解您的问题,它应该可以工作
      • 我想你已经足够理解我的问题了。事实证明,重定向适用于www.someserver.xyz,但不适用于someserver.xyz。对于www.someserver.xyz,我得到301(我猜是代码),但对于someserver.xyz,我得到307(我认为我没有设置)。
      猜你喜欢
      • 2018-09-12
      • 2014-03-18
      • 1970-01-01
      • 2016-07-04
      • 2017-06-21
      • 1970-01-01
      • 1970-01-01
      • 2016-02-28
      • 1970-01-01
      相关资源
      最近更新 更多