Nginx
nginx/Passenger:僅當參數不在請求中時才提供記憶體文件
對於給定的 URL 模式 (
/scripts/.*\.meta\.js
),我希望具有以下行為:
- 如果 URL 包含特定參數 (
version
),則將請求交給乘客處理。- 如果 URL 不包含該特定參數並且存在記憶體文件,則提供它。
- 如果 URL 不包含該特定參數並且記憶體文件不存在,則將請求交給乘客處理。
我這樣做是為了避免讓Passenger 和它背後的Rails 應用程序不得不處理對這條路徑的大部分請求來提高性能。
我的 nginx 配置文件是:
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
),則將請求交給乘客處理。- ✓ 如果 URL 不包含該特定參數並且存在記憶體文件,則提供它。
- ❌ 如果 URL 不包含該特定參數並且記憶體文件不存在,則將請求交給乘客處理。實際行為:HTTP 401。
看來我所擁有的不是在
try_files
. 我需要做什麼才能完成這項工作?
我的印
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; } }