Regex Nginx路由重写配置

Regex Nginx路由重写配置,regex,nginx,url-rewriting,rewrite,pcre,Regex,Nginx,Url Rewriting,Rewrite,Pcre,目前,我正在通过为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

目前,我正在通过为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/[任何内容]

例如,
http://someserver.xyz/s/blah
不会从http重写为https。还有什么像
http://someserver.xyz/dude
http://someserver.xyz/s
etc仍将重写

我已尝试在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流量会发生以下情况:

  • 它命中第一个服务器块并确定是否重写为https

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

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


  • 我做错什么了吗?谢谢你的帮助

    您的第二次重写将不起作用,因为您试图匹配整个请求字符串(包括域部分),但重写URI是可行的

    这是你需要的

    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”,只是因为我更喜欢它,它看起来更具可读性:)

    在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
      }
    }
    

    我尝试了这个并重新启动了nginx,但它仍然重写了模式。我想确保我理解
    $request\u uri!~^/s/
    <代码>~表示不等于?表示“不匹配正则表达式”。如果我正确理解你的问题,它应该会起作用。我想你对我的问题理解得足够好了。事实证明,重定向适用于
    www.someserver.xyz
    ,但不适用于
    someserver.xyz
    。对于
    www.someserver.xyz
    我得到了
    301
    (我猜就是代码),但是对于
    someserver.xyz
    我得到了
    307
    (我想我没有设置)。