rewrite help please...

Francis Daly francis at
Sun Dec 9 10:29:37 UTC 2012

On Sun, Dec 09, 2012 at 07:06:01PM +1300, Steve Holdoway wrote:

Hi there,

> I've got a WP site that also provides landing pages for a number of
> other sites. I've set it up as the default server config for that IP,
> and that's working fine.

The usual nginx way is to have a different configuration for each
server_name in different server{} blocks, which is usually based on the
Host: header sent by the browser.

You want slightly different handling for different Host: headers, but
all in the same server{} block. That's ok, but when you start adding
more special cases, you should probably consider switching to multiple
server{} blocks.

> However, the requirement I've got is to go to a
> specific landing page dependant on domain name. This is how I've gone
> about it ( as there are a lot of pages...
> map $http_host $page_redirect {

Some small points:

$http_host is "whatever the browser sent, including :80 if it did
that". $host is "the hostname part of that, apart from a couple of
exceptions". If you're not sure which to use, use $host.

"redirect" usually suggests "send a http 301 to the browser, so that
it issues a new request". That's not what you want to happen. Perhaps
$landing_page would be clearer for the next person to read? But that's
not directly relevant to the configuration issue.

> hostnames;
> default notset;
> /link/example1;

When you have many things in the one server block, consistency is great.

"notset" is a flag which means "do something special".

What is "/link/example1"? A file that should be served? A file that
should be php-processed? A directory containing a file that should be

Maybe something like

  default /index.php; /link/example1/index.php;

would allow you to handle all situations equivalently.

> }
> hostname;
> location = / {
> if ( $page_redirect ~ notset ) {
> rewrite ^ /index.php break;
> }

location -> if -> "return ..." is OK.
location -> if -> "rewrite ... last" is OK.
location -> if -> anything else, and you're on your own. It's consistent,
but not necessarily easily predictable what will happen.

> # this one works but rewrites the url.
> rewrite ^ $page_redirect redirect;

Yes - "redirect" means "rewrite the url".

> #try_files $page_redirect $page_redirect/ /index.php?$page_redirect;
> }
> So I'm basically only trying to redirect from for
> example, but not, and only from
> predefined domains.

Given your above configuration, am I right that what you want is: -> php-process /usr/local/nginx/html/index.php -> php-process /usr/local/nginx/html/index.php -> send /usr/local/nginx/html/file.png -> php-process /usr/local/nginx/html/link/example1/index.php -> php-process /usr/local/nginx/html/index.php -> send /usr/local/nginx/html/file.png

where in each case "send" or "php-process" means "respond http 200 with
the output of that file"?

> As the comment says, this does work if I use a rewrite ... redirect; but
> the URL then changes to, whereas I
> want to see alone.
> The try_files comes up with a 404, which is really perplexing... I
> expected it to go through the .php block like the others!

After "location -> if -> anything else", I find it's usually not worth
wondering why things do or don't work as hoped. You're in "here be
dragons" territory anyway. That's nginx.

> Any ideas what I'm doing wrong?

With the assumptions and changes from above, maybe

  location = / {
    fastcgi_pass unix:php.sock;
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root$page_redirect;

is closer to what you want?

Good luck with it,

Francis Daly        francis at

More information about the nginx mailing list