FREE THOUGHT · FREE SOFTWARE · FREE WORLD

Paste your .htaccess, enter a URL, and see exactly what Apache does with it: which RewriteRule matched, what every RewriteCond compared, the values of $1 and %1, and when the rules run a second time after an internal rewrite (where most redirect loops come from). Nothing leaves your browser.

Request details and files on the server

Simulates Apache 2.4 per-directory rewriting with DocumentRoot /var/www/html. Not simulated: <If> blocks and expr conditions, RewriteMap, proxying ([P]) and symlink tests. Need redirect rules? Use the redirect generator.

How the .htaccess tester works

Paste your .htaccess, type a full URL, and the tester shows exactly what Apache 2.4 does with that request: the final result (an internal rewrite, a redirect with its status, a 403 or 410, or no change), followed by a rule-by-rule trace. For each RewriteRule you see the string it was matched against, whether it matched, the captured $1, $2, every RewriteCond with its expanded test string, the captured %1, and the action taken. It all runs in your browser; nothing is uploaded.

Open Request details and files on the server to set the method, client IP, User-Agent, Referer, Cookie and X-Forwarded-Proto, the directory the .htaccess lives in, and which files and directories exist. That last list drives -f and -d conditions and decides whether the final path is a 200 or a 404.

Why your RewriteRule does not match

In .htaccess (per-directory context) Apache strips the directory prefix before matching. For a request to /blog/post in the document root, the pattern sees blog/post, with no leading slash. A rule written as ^/blog/(.*)$ works in a VirtualHost and never matches in .htaccess. The trace shows the exact subject string for every rule, so this mistake is obvious at a glance.

Other things the trace makes visible:

  • RewriteRule never sees the query string. Match it with RewriteCond %{QUERY_STRING}.
  • [OR] binds a condition to the next one, and %1 comes from the last condition that matched, not the first.
  • Without RewriteBase, a relative target in an external redirect puts the server's file path into the Location header. The tester shows the leaked path and tells you to add RewriteBase / or a leading slash.
  • A full URL to the same host without R is treated as a local path, not a redirect.

Redirect loops and the second round

This is the part most testers skip. In .htaccess, when a rule rewrites the URL, Apache performs an internal redirect and runs the whole file again on the new URL, with %{ENV:REDIRECT_STATUS} set to 200. It repeats until the URL stops changing, and gives up with a 500 after 10 rounds (AH00124). The tester shows every round, so you can see why this classic rule loops:

RewriteEngine On
RewriteRule ^(.*)$ /app/$1 [L]

[L] only stops the current round. Fix it with a condition (RewriteCond %{REQUEST_URI} !^/app/), with the -f / -d guards, or with [END], which stops all rounds.

What is simulated

RewriteEngine, RewriteBase, RewriteCond (regex, negation, =, <, >, -eq style integer tests, -f, -d, -s), RewriteRule with the flags L, END, R, NC, QSA, QSD, NE, C, S, N, F, G, E, CO and B, server variables such as %{HTTP_HOST}, %{HTTPS}, %{REQUEST_URI}, %{THE_REQUEST}, %{REQUEST_FILENAME} and %{HTTP:Header}, <IfModule> blocks, ErrorDocument, and mod_alias Redirect and RedirectMatch, which run after mod_rewrite. PCRE patterns are converted for the browser, including POSIX classes like [[:alnum:]]. <If> blocks, expr conditions, RewriteMap and proxying are listed as not simulated.

FAQ

Is this exactly what my server does?

It follows Apache 2.4's per-directory rules closely, including the condition chaining from mod_rewrite's source. Differences can come from modules and settings it cannot see, such as AllowOverride, MultiViews or rules in the server config that run first. Confirm on the server with LogLevel alert rewrite:trace3.

Why is my result a 404?

The final path is not in the list of existing files. Add the files your site really has, for example /index.php for a front controller.

Can I share a test?

Yes. Copy link to this test puts the URL, rules and request details into the link, so someone else can open the same trace.