try_files, POST, and redirecting requests to Passenger

António P. P. Almeida appa at perusio.net
Wed Jan 9 08:40:59 UTC 2013


On 9 Jan 2013 00h13 CET, lists at ruby-forum.com wrote:

> The application I'm working on (CMS) has a few interesting
> requirements:
>
> * Custom user domains
> * Very heavily page cached.
> * Any page can be POSTed to (page has a form on it)
>
> In Apache, this was easily handled. If GET, then look in the cache,
> then fall to Passenger. Otherwise, just go straight to Passenger.
>
> I have been unable to get nginx working for my needs and am
> wondering if anyone else has any insight into how to solve this
> problem.
>
> Basically what I want is the following (but can't because try_files
> can't be in an if):
>
> location / {
> if ($request_method ~* ^(GET|HEAD)$) {
> try_files /cache/$domain/$uri
> /cache/$domain/$uri.html
> /cache/$domain/$uri/index.html
> /maintenance.html
> @passenger;
> break;
> }
>
> try_files /maintenance.html @passenger;
> }
>
> location @passenger {
> passenger_enabled on;
> }

You're mixing different things. break is a rewrite phase
directive, like if. So they're executed well before try_files and the
content phase handlers.

You should use the map directive.

At the http level:

map $request_method $idempotent {
    default 0;
    GET 1;
    HEAD 1;
} 

then at the server level (vhost config):

location / {

    error_page 418 = @idempotent;

    if ($idempotent) {
        return 418;
    } 
      
    try_files /cache/$domain/$uri /cache/$domain/$uri.html
    /cache/$domain/$uri/index.html /maintenance.html @passenger;
}

location @idempotent {
   try_files /maintenance.html @passenger;
}

location @passenger {
   passenger_enabled on;
}

Try it.
--- appa



More information about the nginx mailing list