在 nginx 中使用 proxy_pass 时如何设置 SCRIPT_NAME

在 nginx 中使用 proxy_pass 时如何设置 SCRIPT_NAME

我有一个 perl catalyst 应用程序,它安装在特定的 URL 上(而不是安装在子域上),在向后端发出请求时设置 SCRIPT_NAME 时遇到问题。这会影响应用程序生成的 URL。它需要知道它安装在哪里,以便可以正确生成 URL。

所以我的链条是:

请求 => [ nginx,proxy_pass ] => [ starman:5000 ] => [ perl_app ]

当 proxy_pass 将请求发送到 starman 时,我希望它设置SCRIPT_NAME。如果我使用 fastcgi,我会执行fastcgi_param SCRIPT_NAME something或使用fastcgi_split_path_info。此时我已准备好切换到 fastcgi,但我很固执,想弄清楚这是否可行。我无论如何都尝试设置 fastcgi_params,只是为了看看它是否会影响SCRIPT_NAME使用 proxy_pass 发送的内容,但据我所知,它不会。

我的 nginx 服务器配置:

server {
  #listen   80; ## listen for ipv4; this line is default and implied
  #listen   [::]:80 default ipv6only=on; ## listen for ipv6

  root /usr/share/nginx/default;
  index index.html;

  server_name www.example.com example.com;
  listen 80 default_server;
  listen 443 ssl;
  ssl_certificate     certs/cert.pem;
  ssl_certificate_key certs/key.pem;
  ssl_protocols       SSLv3 TLSv1 TLSv1.1 TLSv1.2;
  ssl_ciphers         HIGH:!aNULL:!MD5;

  location / {
    # First attempt to serve request as file, then
    # as directory, then fall back to index.html
    try_files $uri $uri/ =404;
  }

  location /ff/ {
    if ( $https = "off" ) {
      return 302 https://$server_name$request_uri;
    }

    #fastcgi_split_path_info (.*)(.*);
    #include fastcgi_params;
    #fastcgi_param PATH_INFO /blah;
    #fastcgi_param SCRIPT_NAME /test;
    proxy_set_header Host $http_host;
    proxy_set_header X-Forwarded-Host $http_host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Port $server_port;
    #fastcgi_pass localhost:5000;
    proxy_pass  http://localhost:5000/;
  }

  error_page 404 /errors/404.html;
  error_page 500 502 503 504 /errors/50x.html;
}

因此应用程序已打开example.com/ff,并且应该如果您尝试在未登录的情况下example.com/ff/login访问,则重定向到。相反,当您向PATH_INFO 发出请求时,它将设置为 /home(如预期的那样)并且为 '',因此应用程序会生成重定向到,而不是example.com/ff/homeexample.com/ff/homeSCRIPT_NAMEexample.com/homeexample.com/ff/home

据我所知,我唯一的解决方案是:

  • 使用 fastcgi
  • 在催化剂应用程序中执行某些操作以使其知道其安装在哪里(例如,读取 http 请求标头以了解其安装在哪里,然后 uri 生成代码可以创建正确的路径)

感谢您的见解。

答案1

负担不在于 nginx。代理或 FastCGI 都通过套接字传递信息,然后进行解释。FastCGI 并没有太大不同,只是有一个契约指定如何传输和处理要放入 CGI 应用程序中的信息。SCRIPT_NAME 就是其中之一。

如果您希望坚持使用代理,您需要教 starman hoe 解释某些标头并告诉 nginx 使用 proxy_set_header 设置它们。

相关内容