Для заданного шаблона URL ( /scripts/.*\.meta\.js
) я хотел бы иметь следующее поведение:
- Если URL-адрес содержит определенный параметр (
version
), передайте запрос на обработку Passenger. - Если URL-адрес не содержит этого конкретного параметра и существует кэшированный файл, предоставьте его.
- Если URL-адрес не содержит этого конкретного параметра и кэшированный файл не существует, передайте запрос на обработку Passenger.
Я делаю это для повышения производительности, избегая необходимости обработки большинства запросов по этому пути 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
), передайте запрос на обработку 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;
}
}