【问题标题】:Nginx location without trailing slash works only with trailing slash没有斜杠的 Nginx 位置仅适用于斜杠
【发布时间】:2018-12-07 16:08:48
【问题描述】:

我在使用 nginx 作为 Zeppelin 实例的反向代理时遇到了一个奇怪的问题。我将尝试在下面描述问题。

我使用 EC2 实例作为反向代理来访问 Zeppelin 实例。只是前面的注释是作为“转发代理”的 AWS ALB,这样我可以使用友好的 URL 来公开 UI。 AWS ALB 上的path based routing 配置正确。

  1. 请求将通过域 subdomain.domain.com/ds 到达 AWS ALB,我在其中使用基于路径的路由来匹配所有以 /ds 为路径的请求到我的目标群体。

  2. 然后将传入的请求传递给运行良好的 Nginx 实例。问题是,如果我使用没有斜杠的 URL,Nginx 就会超时。

配置如下:

# Zeppelin
server {
    listen 541;
    location /ds {
        rewrite ^/ds/(.*)$ /$1 break;
        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_pass http://10.10.10.10:8890/;
        proxy_redirect http://10.10.10.10:8890/ $scheme://$host/ds;
    }
    location /ds/ws {
        proxy_pass http://10.10.10.10:8890/ws;
        proxy_http_version 1.1;
        proxy_set_header Upgrade websocket;
        proxy_set_header Connection upgrade;
        proxy_read_timeout 86400;
    }
}

另外,下面是我用于 RStudio 的最简单的示例。

server {
    listen 542;


    location /ds {
      rewrite ^/ds/(.*)$ /$1 break;
      proxy_pass http://10.10.10.10:8787;
      proxy_redirect http://10.10.10.10:8787/ $scheme://$host/ds/;
      proxy_http_version 1.1;
      proxy_set_header Upgrade $http_upgrade;
      proxy_read_timeout 20d;
    }
}

如果没有提供斜杠,我会得到 ​​p>

/ds not found

【问题讨论】:

  • 那么您希望subdomain.domain.com/zeppelin/ds 重定向到subdomain.domain.com/zeppelin 吗?问题可能出在您的重写规则中。尝试添加类似 rewrite ^/ds / break; 的规则
  • @BenWhaley 查看编辑。需要重定向 subdomain.domain.com/ds。但是,添加上述规则时会导致重定向过多。
  • 可能是您在上游传递 URI 时没有将 /ds 重写为 /。试试看:rewrite ^/ds/?(.*)$ /$1 break;
  • @RichardSmith 你是对的。如果您能写一个答案,我将不胜感激,以便我接受。只是一个简短的通知,没有那个,重定向会在一段时间后添加一个端口(542),因为我的 ALB 没有监听它而超时。

标签: amazon-web-services nginx reverse-proxy apache-zeppelin


【解决方案1】:

在您的location 块中:

location /ds {
    rewrite ^/ds/(.*)$ /$1 break;
    ...  
    proxy_pass ...
}

/ds/ 开头的URI 将匹配正则表达式并在没有初始/ds 的情况下被重写。但是,URI /ds 与正则表达式不匹配,将作为/ds 传递给上游应用程序。

有多种方法可以解决此问题,但最简单的解决方案是通过添加 ? 运算符使正则表达式中的第二个 / 成为可选。

例如:

rewrite ^/ds/?(.*)$ /$1 break;

【讨论】: