1

I have an email verification script that looks like this:

http://example.com/v/index.php?t=TOKEN_EMAILED_TO_CLIENT

And I want it to look like this:

http://example.com/v/TOKEN_EMAILED_TO_CLIENT

Essentially just removing the index.php?t= portion of the URL, but still allowing the index.php file to process the token.

I have tried the following three settings and none of them have worked:

location /v/ {
    try_files index.php$args;
}

The above results in a failed nginx.conf file

location ^~ /v/ {
    try_files /v/index.php?q=$uri;
}

The above results in a failed nginx.conf file

location ^~ /v/ {
    rewrite ^/v/index.php?q=(.*)$ $1 permanent;
}

The above passes nginx.conf file requirements, but still does not do what I would like. It shows a 404 error when visiting http://example.com/v/TOKEN_EMAILED_TO_CLIENT

Any help would be greatly appreciated.

1
  • 1
    First two fails because try_files requires at least two arguments.
    – Alexey Ten
    Jun 1, 2015 at 6:12

1 Answer 1

3

First thing, ^~ usage is not necessary if you don't have any regex matching this pattern prior to the location your are defining. What you want to do is basically have proper URIs and rewrite them to pass an argument to your php application. In this case, the appropriate solution is using rewrites.

The thing you missed in there is that the URI you are matching against is the first argument to the rewrite directive so it can obviously not match ^/v/index.php?q=(.*)$ since it equals /v/TOKEN_EMAILED_TO_CLIENT. The second argument to the rewrite directive is the URI to rewrite to.

So given you have somewhere a location of this kind which handles .php files :

location ~ \.php$ {
     [ ... ]
}

Then you need this location block instead :

location /v/ {
    rewrite ^/v/(.*)$ /v/index.php?t=$1? last;
}
6
  • That did it, and makes great sense the way you wrote it. Thank you. Can you comment about why the "last" is needed at the end as opposed to "break" or "permanent"? May 31, 2015 at 23:29
  • 2
    last causes nginx to start searching for a new location block that matches the rewritten URL. break just stops processing current rewrite rules, and therefore the PHP script doesn't get executed after that. permanent returns a 301 redirect HTTP response to the client, and is completely different from the other two options. Jun 1, 2015 at 0:17
  • Actually last here is redundant. It prevents processing other rewrite rules in current location. And I think you should explain ? suffix in rewrite's second argument.
    – Alexey Ten
    Jun 1, 2015 at 6:12
  • @AlexeyTen, why would I want other rewrite rules being processed when this is a one-off rewrite? Jun 1, 2015 at 8:42
  • 1
    The last directive is indeed not mandatory in this particular case but it's good practice to mention it since if you start adding new rewrite rules and the rewriten URI somehow matches further rewrite rules regex in the same location block then you will end up with results you probably didn't expect. The question mark added at the end of the rewriten URI prevent nginx from adding additionnal query string parameters from the original URI (which is the default behaviour when rewritting query string parameters). Jun 1, 2015 at 9:30

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .