nginx Redirect Tester
runs in your browserPaste an nginx config and URLs: see which server and location take each request, what rewrite and return do, and every redirect hop, loop or 500.
Drop a file here, or .
Drop an nginx.conf or a site file
Each URL goes through server choice, the server’s rewrites, location choice and the location’s rewrites, and every redirect starts again from the top. Read in your browser; nothing is fetched.
Configuration
URLs to test
about this tool
Paste a server block, or a whole nginx.conf, and the URLs you are unsure
about, and see what nginx does with each: which server answers, which
location takes the request and why, what every rewrite, return, if and
set does there, and where each redirect sends the browser next, hop after
hop, until it is served, loops or leaves for another site.
The order nginx works in
A request does not run the configuration top to bottom. It goes through phases, and most surprises come from forgetting one:
- The server. The port first, then
server_name: an exact name, then the longest wildcard at the start (*.example.com), then the longest at the end (www.example.*), then the first regular expression that matches. A host none of them names goes to thedefault_serverfor the port, or the first server listed. - The server's rewrites.
rewrite,return,ifandsetwritten directly in the server block run next, in order, before any location is chosen. - The location. An exact
=match wins outright. Otherwise the longest matching prefix is found; if it is marked^~it is used, and if not the regular expression locations are tried in file order, nested ones first, and the first match wins over the prefix. - The location's rewrites.
rewrite ... last, or a rewritten URI at the end, searches for a location again;breakstays put;redirect,permanentandreturnanswer the browser.
A redirect is a new request: the browser comes back, and the whole order starts again, which is why two rules that each look right can loop.
Variables
$request_uri is the path and query as the browser sent them, and never
changes. $uri is the current path: decoded and normalised as the request arrives,
and then exactly what each rewrite sets it to. $host, $scheme, $args, $arg_name, $is_args,
captures from regular expressions, set variables and map blocks are all
filled in, so return 301 https://$host$request_uri; and a map of old URLs
to new ones are traced as nginx would run them. A rewrite keeps the original
query string unless its replacement ends with ?.
What it cannot know
Whether a file exists (-f, try_files), request headers, cookies and the
client's address are not in a URL. A condition on them is assumed to hold,
and the step says so. Included files cannot be read, so paste their contents
in; error_page, internal and auth_request are listed, not followed.
For Apache's .htaccess and RewriteRule, use the
Apache redirect tester. Nothing is fetched: the
configuration is read in your browser.
questions
- Which location does nginx choose?
- An exact match with = wins outright. Otherwise nginx finds the longest matching prefix; if that prefix is marked ^~ it is used, and if not, the regular expression locations are tried in the order they are written, nested ones inside the prefix first, and the first match wins. Only when no regular expression matches does the longest prefix take the request. The tool names the location for every request and why it won.
- What is the difference between rewrite last and break?
- Both stop the rewrite directives where they are. last then searches for a location again with the new URI, so a different location’s rules can run; break stays in the current location and serves the new URI there. nginx allows ten such searches before giving up with a 500, which the tool reports as a rewrite cycle.
- Why does $request_uri differ from $uri?
- $request_uri is the path and query exactly as the browser sent them, and never changes. $uri is the current path: percent-decoded and normalised as the request arrives, and then exactly what each rewrite sets it to. Redirecting with $request_uri keeps what was asked for; using $uri after a rewrite sends the rewritten path.
- What can it not know?
- Anything a URL does not carry: whether a file exists (-f, try_files), headers such as the user agent, cookies and the client’s address. A condition on those is assumed to hold and the step says so. Included files cannot be read, so paste their contents, and error_page, internal and auth_request are listed but not followed.
- Is my configuration uploaded?
- No. It is read and every URL traced in your browser; nothing is fetched or sent, so a configuration with internal hostnames or paths stays on your computer.