OiO.lk Community platform!

Oio.lk is an excellent forum for developers, providing a wide range of resources, discussions, and support for those in the developer community. Join oio.lk today to connect with like-minded professionals, share insights, and stay updated on the latest trends and technologies in the development field.
  You need to log in or register to access the solved answers to this problem.
  • You have reached the maximum number of guest views allowed
  • Please register below to remove this limitation

Apache mod_rewrite How to strip slash off document root AND all URIs

  • Thread starter Thread starter Alex Regan
  • Start date Start date
A

Alex Regan

Guest
I have apache-2.4.59 on fedora40 and trying to strip any trailing slash(es) from the root and any other URIs using RewriteCond/RewriteRule in my vhost config. I've tried a dozen different combinations of rewritecond and rewriterule but they always create a redirect loop for the document root URI because once the trailing slash is removed, it matches the same pattern, or the .htaccess in the document root starts the rewrite rules again.

Google Search Console interprets the document root with a trailing slash and without a trailing slash as two separate documents, creating confusion about duplicated content.

I've tried a simple rewrite rule that should match any URI with one or more slashes then redirects to that URI without the slash.

Code:
RewriteRule ^(.*)/+$ https://example.com$1 [R=301,L]

It works fine for any URL other than the homepage. Somehow for the homepage it creates an infinite loop. The (.*) is supposed to match any character, but there wouldn't be any preceding elements for the homepage.

The problem as I see it is that, for the homepage, (.*) would be null, so $1 would also be null? This then creates the same URL as the one we're trying to fix.

First it appears to work properly (trimmed for legibility):

Code:
init rewrite engine with requested uri /
applying pattern '^(.*)/+$' to uri '/'
rewrite '/' -> 'https://linuxsecurity.com'
explicitly forcing redirect with https://linuxsecurity.com
escaping https://linuxsecurity.com for redirect
redirect to https://linuxsecurity.com [REDIRECT/301]

then it looks like it inits the rewrite engine again?

Code:
init rewrite engine with requested uri /, referer: https://linuxsecurity.com/
applying pattern '^(.*)/+$' to uri '/', referer: https://linuxsecurity.com/
rewrite '/' -> 'https://linuxsecurity.com', referer: https://linuxsecurity.com/
explicitly forcing redirect with https://linuxsecurity.com, referer: https://linuxsecurity.com/
escaping https://linuxsecurity.com for redirect, referer: https://linuxsecurity.com/
redirect to https://linuxsecurity.com [REDIRECT/301], referer: https://linuxsecurity.com/

This just loops repeatedly until it dies. I've also made sure there's only one "RewriteEngine on" in the virtual host config and the .htaccess. Would that even matter?

I then got the idea to use the REDIRECT_STATUS flag, thinking that it would only process this rule if it was the first time through.

Code:
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^/?$ https://%{HTTP_HOST} [R=302,L]
RewriteRule ^(.*)/+$ https://%{HTTP_HOST}$1 [R=302,L]

However, it also creates an infinite loop. There are countless examples of RewriteRule and RewriteCond that strip the trailing slash off a URI but none apparently consider a slash on the document root. Please help me create one that works for the document root and any other URI on the HTTP_HOST.
<p>I have apache-2.4.59 on fedora40 and trying to strip any trailing slash(es) from the root and any other URIs using RewriteCond/RewriteRule in my vhost config. I've tried a dozen different combinations of rewritecond and rewriterule but they always create a redirect loop for the document root URI because once the trailing slash is removed, it matches the same pattern, or the .htaccess in the document root starts the rewrite rules again.</p>
<p>Google Search Console interprets the document root with a trailing slash and without a trailing slash as two separate documents, creating confusion about duplicated content.</p>
<p>I've tried a simple rewrite rule that should match any URI with one or more slashes then redirects to that URI without the slash.</p>
<pre><code>RewriteRule ^(.*)/+$ https://example.com$1 [R=301,L]
</code></pre>
<p>It works fine for any URL other than the homepage. Somehow for the homepage it creates an infinite loop. The (.*) is supposed to match any character, but there wouldn't be any preceding elements for the homepage.</p>
<p>The problem as I see it is that, for the homepage, (.*) would be null, so $1 would also be null? This then creates the same URL as the one we're trying to fix.</p>
<p>First it appears to work properly (trimmed for legibility):</p>
<pre><code>init rewrite engine with requested uri /
applying pattern '^(.*)/+$' to uri '/'
rewrite '/' -> 'https://linuxsecurity.com'
explicitly forcing redirect with https://linuxsecurity.com
escaping https://linuxsecurity.com for redirect
redirect to https://linuxsecurity.com [REDIRECT/301]
</code></pre>
<p>then it looks like it inits the rewrite engine again?</p>
<pre><code>init rewrite engine with requested uri /, referer: https://linuxsecurity.com/
applying pattern '^(.*)/+$' to uri '/', referer: https://linuxsecurity.com/
rewrite '/' -> 'https://linuxsecurity.com', referer: https://linuxsecurity.com/
explicitly forcing redirect with https://linuxsecurity.com, referer: https://linuxsecurity.com/
escaping https://linuxsecurity.com for redirect, referer: https://linuxsecurity.com/
redirect to https://linuxsecurity.com [REDIRECT/301], referer: https://linuxsecurity.com/
</code></pre>
<p>This just loops repeatedly until it dies. I've also made sure there's only one "RewriteEngine on" in the virtual host config and the .htaccess. Would that even matter?</p>
<p>I then got the idea to use the REDIRECT_STATUS flag, thinking that it would only process this rule if it was the first time through.</p>
<pre><code>RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^/?$ https://%{HTTP_HOST} [R=302,L]
RewriteRule ^(.*)/+$ https://%{HTTP_HOST}$1 [R=302,L]
</code></pre>
<p>However, it also creates an infinite loop. There are countless examples of RewriteRule and RewriteCond that strip the trailing slash off a URI but none apparently consider a slash on the document root. Please help me create one that works for the document root and any other URI on the HTTP_HOST.</p>
Continue reading...
 
Top