We have a bit of a complicated problem to solve in our nginx configuration. Currently we have a piece of software installed in our document root. This software uses a single entry point (index.php) and query strings in order to show content. Example URLs are:
/index.php?forums/forum-name.1
/index.php?threads/thread-name.1
/index.php?users/user-name.1
Etc…
Now, we are moving this software into a subdirectory of /f/
and installing a new piece of software into the document root. This software ALSO uses index.php (No query strings, though). So we need to come up with a set of rewrite rules to ONLY rewrite the URLs from the old software. At the same time, we are also going to be removing the index.php from the URLs. A set of example mappings is:
/index.php?forums/forum-name.1 --> /f/forums/forum-name.1
/index.php?threads/thread-name.1 --> /f/threads/thread-name.1
/index.php?users/user-name.1 --> /f/users/user-name.1
So basically, I need to redirect a certain subset of index.php requests (Only containing ?forums, ?threads, ?users, etc…), then remove the index.php part and send to the /f/ directory.
I have played with this all morning and just can't get it to work how I need it to.
Best Answer
To manage complex redirections, particularly when query strings are involved, the
map
directive can be used.You cannot match the query string (anything from the
?
onwards) inlocation
andrewrite
expressions, as it is not part of the normalized URI, however, the$request_uri
contains the original request complete with query string.Matching the
$request_uri
may be problematic if the parameters are not sent in a consistent order, also URIs containing strange characters will be percent encoded.The
map
directive can match strings and/or regular expressions. See this document for details.For example:
Always use named captures in a
map
block regular expression. The mapped expression is evaluated at thereturn
statement. As I understand it, every timenginx
encounters a statement containing a regular expression (such asrewrite
, somelocation
blocks, and someif
statements), the numeric captures are reset. Using named captures ensures that they remain in scope at thereturn
statement.See this caution on the use of
if
.