nginx/Passenger:仅当请求中没有参数时才提供缓存文件

nginx/Passenger:仅当请求中没有参数时才提供缓存文件

对于给定的 URL 模式(/scripts/.*\.meta\.js),我希望有以下行为:

  • 如果 URL 包含特定参数(version),则将请求交给 Passenger 处理。
  • 如果 URL 不包含该特定参数并且存在缓存文件,则提供该文件。
  • 如果 URL 不包含该特定参数且缓存文件不存在,则将请求交给 Passenger 处理。

我这样做是为了避免让 Passenger 和其后面的 Rails 应用程序处理这条路径上的大多数请求,从而提高性能。

我的 nginx conf 文件是:

server {

  listen 80;
  server_name my.site;

  root /path/to/rails/public;
  passenger_enabled on;
  rails_env development;
  passenger_min_instances 1;

  client_max_body_size 5m;

  location ~* /scripts/.*\.meta\.js {

    error_page 418 = @noparams;

    if ( $arg_version = '' ) {
      return 418;
    }
  }

  location @passenger {
    root /path/to/rails/public;
    proxy_set_header X-Forwarded-Proto http;
    passenger_enabled on;
  }

  location @noparams {
    try_files  /a$uri @passenger =401;
  }

}

我已将测试文件放在 下/path/to/rails/public/a。这会产生以下行为:

  • ✓ 如果URL包含特定参数(version),则将请求交给Passenger处理。
  • ✓ 如果 URL 不包含该特定参数且存在缓存文件,则提供该文件。
  • ❌ 如果 URL 不包含该特定参数且缓存文件不存在,则将请求交给 Passenger 处理。实际行为:HTTP 401。

看来我所拥有的不是引用 Passenger 的正确方法try_files。我需要做什么才能使其工作?

答案1

我的印象是,这try_files是要尝试的“事物”列表,您可以将命名位置放在任何位置。正如 Michael Hampton 在评论中指出的那样,这是不正确的。命名位置和 HTTP 代码只能位于 中的最后一个位置try_files;任何不在最后一个位置的东西都必须是文件路径。所以try_files /a$uri @passenger它按我的意图工作。

@passenger由于配置是从块继承而来的,因此也没有必要重复内部配置server。因此,工作配置是:

server {

  listen 80;
  server_name my.site;

  root /path/to/rails/public;
  passenger_enabled on;
  rails_env development;
  passenger_min_instances 1;

  client_max_body_size 5m;

  location ~* /scripts/.*\.meta\.js {

    error_page 418 = @noparams;

    if ( $arg_version = '' ) {
      return 418;
    }
  }

  location @passenger { }

  location @noparams {
    try_files  /a$uri @passenger;
  }

}

相关内容