nsommer
nsommer

Reputation: 283

nginx tries to serve .rss/.json itself rather than letting rails/unicorn serve it

My rails app runs perfectly fine in production using nginx and unicorn except for one thing: Requesting /articles.rss and /articles.json leads to a 404 with an error in the nginx logs that the requested file doesn't exist. Requesting e.g. /articles?format=rss works. So it looks like the .rss leads nginx to think this is a static file rather than dynamically generated content. In development (using the builtin server of rails) this works fine.

I use the h5bp config files for nginx, here's my site configuration (domain name replaced):

# www to non-www redirect -- duplicate content is BAD:
# https://github.com/h5bp/html5-boilerplate/blob/5370479476dceae7cc3ea105946536d6bc0ee468/.htaccess#L362
# Choose between www and non-www, listen on the *wrong* one and redirect to
# the right one -- http://wiki.nginx.org/Pitfalls#Server_Name
upstream app {
  server unix:/var/www/rails-cms/shared/tmp/sockets/rails-cms.unicorn.sock fail_timeout=0;
}

server {
  # don't forget to tell on which port this server listens
  listen [::]:80;
  listen 80;

  # listen on the www host
  server_name www.<my domain>;

  # and redirect to the non-www host (declared below)
  return 301 $scheme://<my domain>$request_uri;
}

server {
  # listen [::]:80 accept_filter=httpready; # for FreeBSD
  # listen 80 accept_filter=httpready; # for FreeBSD
  # listen [::]:80 deferred; # for Linux
  # listen 80 deferred; # for Linux
  listen [::]:80;
  listen 80;

  # The host name to respond to
  server_name <my domain>;

  # Path for static files
  root /var/www/rails-cms/current/public;

  try_files $uri/index.html $uri @app;

  location @app {
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header Host $http_host;
    proxy_redirect off;
    proxy_pass http://app;
  }

  #Specify a charset
  charset utf-8;

  # Custom 404 page
  error_page 404 /404.html;

  # Include the basic h5bp config set
  include h5bp/basic.conf;
}

Upvotes: 1

Views: 145

Answers (1)

Oleg
Oleg

Reputation: 23297

This occurs because you include h5bp/basic.conf file which in turn includes h5bp/location/expires.conf file. Take a look at the latter file's contents:

# cache.appcache, your document html and data
location ~* \.(?:manifest|appcache|html?|xml|json)$ {
  expires -1;
  access_log logs/static.log;
}

# Feed
location ~* \.(?:rss|atom)$ {
  expires 1h;
  add_header Cache-Control "public";
}

See? the first location intercepts .json requests, and the second one - .rss requests, so your app never catches these requests.

If you want your app to handle these requests, you should either refuse h5bp at all, or just comment out abovementioned locations.

In both cases your app should send cache headers itself, if you want it of course.

Edit:

But since your json and rss contents are dynamically generated, I would not recommend using cache headers.

Upvotes: 2

Related Questions