nginx/Passenger:僅當請求中沒有參數時才提供快取文件

nginx/Passenger:僅當請求中沒有參數時才提供快取文件

對於給定的 URL 模式 ( /scripts/.*\.meta\.js),我希望有以下行為:

  • 如果URL中包含特定參數( version),則將請求交給Passenger處理。
  • 如果 URL 不包含該特定參數且存在快取文件,則提供該文件。
  • 如果 URL 不包含該特定參數且快取檔案不存在,則將請求交給 Passenger 處理。

我這樣做是為了避免 Passenger 及其背後的 Rails 應用程式必須處理對該路徑的大多數請求,從而提高效能。

我的 nginxconf 檔案是:

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是一個要嘗試的“事物”列表,您可以在任何位置放置一個命名位置。正如邁克爾漢普頓在評論中指出的那樣,這是不正確的。命名位置和 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;
  }

}

相關內容