nginx/Passenger: servir un archivo en caché solo si un parámetro no está en la solicitud

nginx/Passenger: servir un archivo en caché solo si un parámetro no está en la solicitud

Para un patrón de URL determinado ( /scripts/.*\.meta\.js), me gustaría tener el siguiente comportamiento:

  • Si la URL contiene un parámetro específico ( version), entregue la solicitud a Passenger para que la maneje.
  • Si la URL no contiene ese parámetro específico y existe un archivo en caché, publíquelo.
  • Si la URL no contiene ese parámetro específico y no existe un archivo en caché, envíe la solicitud a Passenger para que la maneje.

Estoy haciendo esto para mejorar el rendimiento al evitar que Passenger y la aplicación Rails detrás tengan que lidiar con la mayoría de las solicitudes en esta ruta.

Mi archivo de configuración de nginx es:

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;
  }

}

He colocado archivos de prueba en /path/to/rails/public/a. Esto da el siguiente comportamiento:

  • ✓ Si la URL contiene un parámetro específico ( version), entregue la solicitud al Pasajero para que la maneje.
  • ✓ Si la URL no contiene ese parámetro específico y existe un archivo en caché, publíquelo.
  • ❌ Si la URL no contiene ese parámetro específico y no existe un archivo en caché, envíe la solicitud a Passenger para que la maneje.Comportamiento real: HTTP 401.

Parecería que lo que tengo no es la forma correcta de hacer referencia a Passenger en try_files. ¿Qué necesito hacer para que esto funcione?

Respuesta1

Tenía la impresión de que try_fileses una lista de "cosas" para probar y que se podía colocar una ubicación con nombre en cualquier posición. Como señala Michael Hampton en un comentario, esto es incorrecto. Las ubicaciones con nombre y los códigos HTTP solo pueden estar en la última posición en try_files; todo lo que no esté en la última posición debe ser una ruta de archivo. Funciona try_files /a$uri @passengercomo lo pretendo.

Tampoco es necesario repetir la configuración en el interior @passengerya que se hereda del serverbloque. Entonces una configuración funcional es:

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;
  }

}

información relacionada