2

In the default .htaccess rules for a WordPress 4.7 multisite subdomain installation, I'm trying to understand the purpose for one particular rule.

First I'll present the rule on its own

RewriteRule ^(wp-(content|admin|includes).*) $1 [L]

In isolation, to me, it would appear that the rule would simply rewrite any url in wp-content or wp-admin or wp-includes to itself. Since it comes after the file system checks, we know it doesn't exist on the file system, so I'm at a loss for what it's trying to do.

Now here's the entirety of the suggested .htaccess file. The rule is third from the end.

RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]

# add a trailing slash to /wp-admin
RewriteRule ^wp-admin$ wp-admin/ [R=301,L]

RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
RewriteRule ^(wp-(content|admin|includes).*) $1 [L]
RewriteRule ^(.*\.php)$ $1 [L]
RewriteRule . index.php [L]

Any insight that anyone can shed would be fantastic. I'm getting an error - "Request exceeded the limit of 10 internal redirects due to probable configuration error." - whenever anyone tries to access any directory beyond wp-content/ that doesn't exist. I would be hoping for a 404 instead.

For what it's worth, this appears to be a long running WP issue per this ticket

https://core.trac.wordpress.org/ticket/20746

There are suggestions of fixes there, but I'd like to understand any change I deploy there since it won't be "official WP". I'm thinking that understanding how that rule could lead to anything other than a self-rewrite would help me be confident in deployment of one of the suggested changes.


EDIT: Here's an example of the rule being applied:

[rid#7f58a5a5dcb0/initial/redir#2] [perdir /var/www/wordpress/] applying pattern '^(wp-(content|admin|includes).*)' to uri 'wp-content/invalid_directory/nothing.png'
[rid#7f58a5a5dcb0/initial/redir#2] [perdir /var/www/wordpress/] rewrite 'wp-content/invalid_directory/nothing.png' -> 'wp-content/invalid_directory/nothing.png'
[rid#7f58a5a5dcb0/initial/redir#2] [perdir /var/www/wordpress/] add per-dir prefix: wp-content/invalid_directory/nothing.png -> /var/www/wordpress/wp-content/invalid_directory/nothing.png
[rid#7f58a5a5dcb0/initial/redir#2] [perdir /var/www/wordpress/] trying to replace prefix /var/www/wordpress/ with /
[rid#7f58a5a5dcb0/initial/redir#2] strip matching prefix: /var/www/wordpress/wp-content/invalid_directory/nothing.png -> wp-content/invalid_directory/nothing.png
0
RewriteRule ^(wp-(content|admin|includes).*) $1 [L]

I think the main intention of that directive is to prevent further processing of the file (ie. to prevent the request being forwarded to the front controller: index.php) when requesting a URL that starts /wp-content, /wp-admin or /wp-includes.

By rewriting to itself, the URL passes through unchanged and processing stops.

However, the resulting substitution is also relative, so whatever is stated as the RewriteBase will also be prefixed to the rewritten URL. In this case the RewriteBase is simply /, so it is indeed rewritten to itself on the first pass (assuming this .htaccess file is in the document root). I assume this must be intentional, otherwise they would have used a hyphen (-) as the substitution, as in the directive above.

This "shouldn't" result in a rewrite loop, since processing should stop if the URL passes through unchanged (the rewrite is essentially "ignored").

However, to be sure it's not changed, you could simply replace $1 with - in the RewriteRule substitution.

If you enable full rewrite debugging, eg. LogLevel rewrite:trace6 in the server config on Apache 2.4+ you should see exactly what is happening as it should show each iteration of the rewrite.

  • Thanks for the clues! I had read somewhere that this might be related to cases where the wordpress files are hosted outside of the root (either in a subfolder or above the webroot) but where users don't want the URL to reflect that. – Joe Flowers Jun 30 '17 at 2:32
  • Also, I added some logging info above. It doesn't appear that Apache/2.4.7 (Ubuntu) is smart enough to avoid re-running the engine. When I replaced the $1 with - it fixed the issue, so marking this as answered – Joe Flowers Jun 30 '17 at 2:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.