remove multiple trailing slashes mod_rewrite
Asked Answered
O

5

5

I know this question was asked a number of times on this site alone, but browsing through the relevant posts I couldn't find a solution. Trying to remove multiple trailing slashes after domain. The following mod_rewrite expressions seem to work for URLs such as http://www.domain.com//path1///path2////, but do not work for domain//

DirectorySlash Off

RewriteEngine on

# Canonical fix
RewriteCond %{HTTP_HOST} !^www.domain.com$ [NC]
RewriteRule ^(.*)$ http://www.domain.com/$1 [R=301]
RewriteRule ^/main.do http://www.domain.com/ [R=301,L]
RewriteRule ^/index.jsp http://www.domain.com/ [R=301,L]

# Remove bogus query strings
RewriteCond %{query_string} q= [NC]
RewriteRule (.*) http://www.domain.com/$1? [R=301,L]

# Remove multiple slashes after domain - DOESN'T WORK!!!
#RewriteCond %{REQUEST_URI} ^//+(.*)$ [OR]
#RewriteCond %{REQUEST_URI} ^(.*/)/+$
#RewriteRule / http://www.domain.com/%1 [R=301,L]

# Remove multiple slashes anywhere in URL
RewriteCond %{REQUEST_URI} ^(.*)//(.*)$
RewriteRule . %1/%2 [R=301,L]

# Externally redirect to get rid of trailing slash except for home page, ads
RewriteCond %{REQUEST_URI} !^/ads/
RewriteRule ^(.+)/$ $1 [R=301,L]
Outstretch answered 17/5, 2010 at 1:32 Comment(3)
But 'domain//' isn't a valid URI anyway?!?, as 'domain' isn't in TLD format. If this is an internal setup, use domain.lan or if you mean 'localhost//' then add an entry to your hosts file.Eyeshade
Aiden, I was not allowed to post more that one URL therefore I had to abbreviate. To clarify domain.com// does not work. Thanks for taking the time to respond, BoyanOutstretch
For the shortest solution have a look at the answer by Gerben on this question. #8460515Purkey
J
10

Can't reproduce. Extra slashes immediately after the domain are never passed to mod_rewrite even with DirectorySlashes off -- I haven't checked whether it's Opera or Apache that's removing the slash). But otherwise, everything works fine:

RewriteBase /
RewriteCond %{REQUEST_URI} ^//+(.*)$ [OR]
RewriteCond %{REQUEST_URI} ^(.*/)/+$
RewriteRule .* http://domain/%1 [R=301,L]

Request for http://localhost//abc/b//

127.0.0.1 - - [17/May/2010:12:26:36 +0100] [localhost/sid#c08fb0][rid#2756540/initial] (3) [perdir C:/HTTP/htdocs/] add path info postfix: C:/HTTP/htdocs/abc -> C:/HTTP/htdocs/abc/b/
127.0.0.1 - - [17/May/2010:12:26:36 +0100] [localhost/sid#c08fb0][rid#2756540/initial] (3) [perdir C:/HTTP/htdocs/] strip per-dir prefix: C:/HTTP/htdocs/abc/b/ -> abc/b/
127.0.0.1 - - [17/May/2010:12:26:36 +0100] [localhost/sid#c08fb0][rid#2756540/initial] (3) [perdir C:/HTTP/htdocs/] applying pattern '.*' to uri 'abc/b/'
127.0.0.1 - - [17/May/2010:12:26:36 +0100] [localhost/sid#c08fb0][rid#2756540/initial] (4) [perdir C:/HTTP/htdocs/] RewriteCond: input='/abc//b//' pattern='^//+(.*)$' => not-matched
127.0.0.1 - - [17/May/2010:12:26:36 +0100] [localhost/sid#c08fb0][rid#2756540/initial] (4) [perdir C:/HTTP/htdocs/] RewriteCond: input='/abc//b//' pattern='^(.*/)/+$' => matched
127.0.0.1 - - [17/May/2010:12:26:36 +0100] [localhost/sid#c08fb0][rid#2756540/initial] (2) [perdir C:/HTTP/htdocs/] rewrite 'abc/b/' -> 'http://domain//abc//b/'
127.0.0.1 - - [17/May/2010:12:26:36 +0100] [localhost/sid#c08fb0][rid#2756540/initial] (2) [perdir C:/HTTP/htdocs/] explicitly forcing redirect with http://domain//abc//b/
127.0.0.1 - - [17/May/2010:12:26:36 +0100] [localhost/sid#c08fb0][rid#2756540/initial] (1) [perdir C:/HTTP/htdocs/] escaping http://domain//abc//b/ for redirect
127.0.0.1 - - [17/May/2010:12:26:36 +0100] [localhost/sid#c08fb0][rid#2756540/initial] (1) [perdir C:/HTTP/htdocs/] redirect to http://domain//abc//b/ [REDIRECT/301]

Note: consider not hard-coding the host:

RewriteCond %{HTTP_HOST} !=""
RewriteCond %{REQUEST_URI} ^//+(.*)$ [OR]
RewriteCond %{REQUEST_URI} ^(.*/)/+$
RewriteRule .* http://%{HTTP_HOST}/%1 [R=301,L]

Also note that the inner "//" was not replaced. You will to add another rule to replace inner slashes.

NEW EDIT: OK, this seems to work for preventing URLs starting or ending with //:

RewriteEngine on
RewriteBase /
RewriteCond %{HTTP_HOST} !=""
RewriteCond %{THE_REQUEST} ^[A-Z]+\s//+(.*)\sHTTP/[0-9.]+$ [OR]
RewriteCond %{THE_REQUEST} ^[A-Z]+\s(.*/)/+\sHTTP/[0-9.]+$
RewriteRule .* http://%{HTTP_HOST}/%1 [R=301,L]
Jeri answered 17/5, 2010 at 11:39 Comment(3)
Artefacto, localhost//abc//b// works fine, what doesn't work is localhost//. Thanks for the %{HTTP_HOST} tip. I have listed the expression as well as an excerpt from the log. # Remove multiple slashes after domain - STILL DOESN'T WORK!!! RewriteCond %{HTTP_HOST} !="" RewriteCond %{REQUEST_URI} ^//+(.*)$ [OR] RewriteCond %{REQUEST_URI} ^(.*/)/+$ RewriteRule .* http://%{HTTP_HOST}/%1 [R=301,L] RewriteCond %{REQUEST_URI} ^(.*)//(.*)$ RewriteRule . %1/%2 [R=301,L] 127.0.0.1 - - [18/May/2010:06:13:19 -0700] "GET /// HTTP/1.1" 200 10626 Thanks, BoyanOutstretch
maybe it will work with THE_REQUEST instead of REQUEST_URI. I'll check that when i get homeJeri
The first solution did not work for double slashes right after the domain, but worked for double slashes ending the domain. For me, the solution with THE_REQUEST works in both cases. Post your rewrite log with rewriteloglevel 9.Jeri
O
2

Here is the complete listing that seems to be working:

DirectorySlash Off
RewriteEngine on

# Fix Canonical URLs
RewriteCond %{HTTP_HOST} !^www.domain.com$ [NC]
RewriteRule ^(.*)$ http://www.domain.com/$1 [R=301]
RewriteRule ^/main.do http://www.domain.com/ [R=301,L]
RewriteRule ^/index.jsp http://www.domain.com/ [R=301,L]

# Remove bogus query strings
RewriteCond %{HTTP_HOST} !=""
RewriteCond %{query_string} q= [NC]
RewriteRule (.*) http://%{HTTP_HOST}/$1? [R=301,L]

# Remove multiple slashes after domain
RewriteCond %{HTTP_HOST} !=""
RewriteCond %{THE_REQUEST} ^[A-Z]+\s//+(.*)\sHTTP/[0-9.]+$ [OR]
RewriteCond %{THE_REQUEST} ^[A-Z]+\s(.*/)/+\sHTTP/[0-9.]+$
RewriteRule .* http://%{HTTP_HOST}/%1 [R=301,L]

# Remove multiple slashes anywhere in URL
RewriteCond %{REQUEST_URI} ^(.*)//(.*)$
RewriteRule . %1/%2 [R=301,L]

# Externally redirect to get rid of trailing slash except for home page and ads
RewriteCond %{REQUEST_URI} !^/ads/
RewriteRule ^(.+)/$ $1 [R=301,L]
Outstretch answered 21/5, 2010 at 3:32 Comment(0)
V
1

You're telling Apache map everything including the first slash to $1

RewriteRule ^(.*)$ domain/$1 [R=301]

RewriteRule (.*) domain/$1? [R=301,L]

RewriteRule ^(.+)/$ $1 [R=301,L]

add a slash after the caret or drop the one after your domain name

Valor answered 21/5, 2010 at 0:50 Comment(0)
C
1

The following code will strip all extra slashes including extra slashes after the domain.

RewriteCond %{THE_REQUEST} //
RewriteRule ^(.*)$ /$1 [L,R=301]
Canister answered 13/5, 2014 at 18:28 Comment(0)
S
0

This one removes all the slashes before sending the redirect

# if match set environment variable and start over
RewriteRule ^(.*?)//+(.*)$ $1/$2 [E=REDIR:1,N]

# if done at least one. redirect with 301
RewriteCond %{ENV:REDIR} 1
RewriteRule ^/(.*) /$1 [R=301,L]
Scrubber answered 18/6, 2013 at 19:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.