0

For a given URL pattern (/scripts/.*\.meta\.js), I would like to have the following behaviour:

  • If the URL contains a specific parameter (version), give the request to Passenger to handle.
  • If the URL does not contain that specific parameter and a cached file exists, serve it up.
  • If the URL does not contain that specific parameter and a cached file does not exist, give the request for Passenger to handle.

I am doing this to improve performance by avoiding having Passenger and the Rails app behind it having to deal with the majority of requests to this path.

My nginx conf file is:

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

}

I have placed test files under /path/to/rails/public/a. This gives the following behaviour:

  • ✓ If the URL contains a specific parameter (version), give the request to Passenger to handle.
  • ✓ If the URL does not contain that specific parameter and a cached file exists, serve it up.
  • ❌ If the URL does not contain that specific parameter and a cached file does not exist, give the request for Passenger to handle. Actual behaviour: HTTP 401.

It would seem that what I have is not the correct way to reference Passenger in try_files. What do I need to do to make this work?

3
  • Why is there =401 in your try_files? Feb 24, 2018 at 1:56
  • I wanted it to respond with a 401 for debugging purposes if @passenger didn't handle the request. However now that I try it without that it seems to work as I intended. I may be misunderstanding how try_files works.
    – jb_314
    Feb 24, 2018 at 2:06
  • 1
    Only the last parameter can be a named location. In that case passenger will always receive the request. Feb 24, 2018 at 2:27

1 Answer 1

0

I was under the impression that try_files is a list of "things" to try, and you could put a named location at any position. As Michael Hampton notes in a comment, this is incorrect. Named locations and HTTP codes can only be at the last position in try_files; anything not in the last position must be a file path. So try_files /a$uri @passenger works as I intend it.

It is also unnecessary to repeat the configuration inside @passenger as it is inherited from the server block. So a working configuration is:

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

}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .