Understanding location blocks and try files

AD7six nginx-forum at nginx.us
Thu Jan 23 11:55:04 UTC 2014


Hey, thanks for the responses!

Indeed your input has been very insightful, some follow ups:

@Jonathan/@Valentin
Your analysis is about right, the linked prior posts on the mailing list
were very informative.

@Francis
> > An invalid response when passed to php:
>
> >$ curl -i http://nginx.dev/apples.json
> > HTTP/1.1 404 Not Found

> Why do you think that this request is passed to php?

Because I (mis)read the debug log =) (linked in the first post). Re-reading
it I was looking at the log for a different response.

> >Is there a way to define location blocks for static files - without that
> >causing problems for dynamic requests for the same url pattern?
>
> "location" matches the uri. "static file" or "dynamic request" is
irrelevant at that point.

Allow me to rephrase: Is there a way to define rules for static files -
without that causing problems for dynamic requests matching the same url
pattern?

Nginx docs are full of warnings about If is evil and advocates using
try_files instead - yet doing that is not functionally/logically equivalent,
which leaves me kind of stuck.

> Either check the debug log, or add something like
> return 200 "location#2\n";

I've been using `add_header section "file:line";` for this purpose - a
useful technique imo.

My conclusion at this time is that it's not possible to define rules for
static files without adding `try_files` to all location blocks; or by using
`if (!-f $request_filename) {` or by adding a nested location block e.g.:

    location ~
^/(?:apple-touch-icon-precomposed[^/]*.png$|crossdomain.xml$|favicon.ico$|css/|files/|fonts/|img/|js/)
{
        require static-files.conf;
    }

I did also try using the front controller as a 404 handler which worked
exactly how I am trying to get things to work _except_ of course everything
from the front controller is a http 404. Is there a way to prevent the http
response code being set..?

Cheers,

AD

----
Further info =)

I feel I should give some context as to what I'm trying to do in general so
here goes:

I use nginx for everything, as do many of my peers and colleagues - we're
typically backend developers who simply appreciate performance.  However, I
also use and contribute to http://html5boilerplate.com /
https://github.com/h5bp/html5-boilerplate - which many frontend developers
use as the basis for the projects. Most frontend developers are familiar
with and use apache - their combined knowledge distilled into
https://github.com/h5bp/html5-boilerplate/blob/master/.htaccess - knowledge
which I'd like to apply by default to the use of nginx. 

There is an nginx version of the apache rules here
https://github.com/h5bp/server-configs-nginx which I'd really like to get
into a position to point at - right now it's kind of dis-functional in part
because of the problem I'm trying to solve in this thread. One of the goals
of asking here was to eventually achieve a "just include this config file"
solution to optimize frontend performance. This post so far leads to the
conclusion that's not possible and an application-specific config file is
required for all apps.

An example of the kind of apache rule I'd like to emulate with nginx is:

    <FilesMatch "\.(eot|otf|ttc|ttf|woff)$">
        Header set Access-Control-Allow-Origin "*"
    </FilesMatch>

Here's a similar example as a further reference:

http://www.servermom.org/setup-nginx-virtual-host-for-wordpress-with-wp-super-cache/262/
(I don't use wordpress but it serves the purpose as an example)

The suggestion there is to include the following:

    # Cache static files for as long as possible
    location ~*
.(ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|css|rss|atom|js|jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf)$
{
        expires max; log_not_found off; access_log off;
    }

Which would mean any request for those file types which is intended to be
handled by wordpress - fails.

it also means you can't optimize static requests _and_ do "funky caching" or
similar by which I mean handling the first request for something that
doesn't exist, and caching the result in a path such that the next and all
subsequent requests are served by the webserver:

<?php //index.php
....
$response = ....;

file_put_contents($_SERVER['REQUEST_URI'], $response);
echo $response;

I hope that's sufficient, should anyone have any general or specific advice
I'd be very grateful to hear it.

Posted at Nginx Forum: http://forum.nginx.org/read.php?2,246713,246751#msg-246751



More information about the nginx mailing list