1

I'm testing a setup where I'd like to have nginx serve up static media and proxy all other requests to another backend. My configuration looks like this:

location /media    {alias /var/httpd/media;}
location /         {proxy_pass http://127.0.0.1:8080;}

However, if a request is made for a non-existing media resource, e.g. /media/foo.js, nginx tries looking for /var/httpd/media/foo.js and then when not found it also tries to proxy the request to 127.0.0.1:8080. Here are the nginx error logs:

2012/05/18 17:09:21 [error] 10073#0: *1 open() "/var/httpd/media/foo.js" failed (2: No such file or directory), client: 127.0.0.1, server: www.example.com, request: "GET /media/foo.js HTTP/1.1", host: "www.example.com"
2012/05/18 17:09:21 [error] 10073#0: *1 connect() failed (111: Connection refused) while connecting to upstream, client: 127.0.0.1, server: www.example.com, request: "GET /media/foo.js HTTP/1.1", upstream: "http://127.0.0.1:8080/media/foo.js", host: "www.example.com"

Additionally, I notice that if /var/httpd/media/foo.js does exist but is not readable by the process running nginx, then nginx does not attempt to proxy to http://127.0.0.1:8080 and returns a 403 Forbidden. Error log:

2012/05/18 17:09:33 [error] 10073#0: *1 open() "/var/httpd/media/foo.js" failed (13: Permission denied), client: 127.0.0.1, server: www.example.com, request: "GET /media/foo.js HTTP/1.1", host: "www.example.com"

Why does the first scenario cause both location blocks to be processed and the second scenario only cause the media location block to be processed? How can I make the first scenario only process the media location block and not attempt to proxy to the backend?

Note: I also tried adding a ^~ prefix to the media location block:

location ^~ /media    {alias /var/httpd/media;}

...but this did not change nginx's behavior, as it continued to drop into the / block after failing in the /media block.

Gary
  • 165
  • 3

1 Answers1

1

I guess you have error_page 404 set to somewhere in second location

DukeLion
  • 3,259
  • 1
  • 18
  • 19
  • Excellent guess, this was exactly the problem! I guess I'd need move the URI of the error files to their own location that gets picked up by a specific `location` directive to not be handled by `proxy_pass`, though unfortunately since `location` directives can't be inside of `http` directives (only `server` directives according to the docs) I'd need to include that error `location` directive into every `http` directive in every included config. – Gary May 21 '12 at 14:52