Remove multiple trailing slashes in root using htaccess - regex

I have a rule in my htaccess file to remove any extra trailing slashes from a url, this works on sub-directories with any more than 1 trailing slash. However it doesn't work on the root; which i need it to do.
For example.
http://www.example.com/test//// Redirects to http://www.example.com/test/
http://www.example.com/// Needs to redirect to http://www.example.com
Any ideas on what i need to add?. Cheers.
RewriteCond %{REQUEST_URI} ^(.*?)(?:/){2,}$
RewriteRule . %1/ [R=301,L]

For removing multiple slashes anywhere in REQUEST_URI this rule works best:
RewriteEngine On
RewriteCond %{THE_REQUEST} \s[^?]*//
RewriteRule ^.*$ /$0 [R=301,L,NE]
It takes advantage of the fact that mod_rewrite engine itself converts all multiple forward slashes to a single slash in the RewriteRule pattern. We use RewriteCond %{THE_REQUEST} to make sure original REQUEST_URI contains multiple slashes.
Here [^?]*// matches 2 // before matching query string since [^?] matches anything except ?. This will allow // in query string.

Try with:
RewriteCond %{REQUEST_URI} ^(.*?)//+$
RewriteRule ^ %1/ [R=301,L]

You htaccess works great as you can test on below link
https://htaccess.madewithlove.be/
So you need to make sure you test either with a Chrome Incognito window or using like below
curl -v http://example.com////
I usually prefer curl as I know it will give a fresh response from the server always

You just need two rule to match two different pattern
RewriteCond %{REQUEST_URI} ^(?:/){2,}$
RewriteRule . / [R=301,L]
RewriteCond %{REQUEST_URI} ^(.*?)(?:/){2,}$
RewriteRule . %1/ [R=301,L]

Related

How to match quantifiers { 6, } in RewriteRules?

I did a rewrite rule matching document names that are 6 characters, and it succeeds.
RewriteRule ^document\/(.{6})\/?$ document/?name=$1 [NE,L]
Since I know documents are named only up to 12 characters, I added a maximum length quantifier. However, using this, it produces a 500 Server Error:
RewriteRule ^document\/(.{6,12})\/?$ document/?name=$1 [NE,L]
In fact, I'm getting the following results:
(.{6}) works
(.{6,}) faults
(.{6,7}) works
(.{6,8}) works
(.{6,9}) faults
and so on.
I should also mention that https://www.regexpal.com/?fam=109235 tells me there isn't anything wrong with my rule. However I'm still getting the 500 Server Error on use.
Thank you #emma, example URLs to be rewritten:
http://www.mywebsite.com/document/051201-22
http://www.mywebsite.com/document/051201-22/
I'm not quite sure how you'd like to write this RewriteRule. However, this tool might help you to first find an expression, then write and test a RewriteRule. I'm pretty sure, you can write it without using a quantifier. For example:
document\/([0-9]+)
would pass your exampled URLs.
Then, if you wish to only replace the first six digits to the name variable, you might want to write a RewriteRule similar to:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTP_HOST} mywebsite\.com [NC]
RewriteRule document\/([0-9]+) document\/?name=$1 [NE,L]
</IfModule>
For yes or no trailing slashes, these might work:
# No Trailing Slash Policy, if you wish no slash at the end of your URLs
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /$1 [L,R] # <- for test, for prod use [L,R=301]
# Trailing Slash Policy, if you wish to have a slash at the end of your URLs
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /$1/ [L,R] # <- for test, for prod use [L,R=301]
I think you enter in a redirect loop with this setup.
Add a RewritCond to check that there is not a query string in the request
RewriteCond %{QUERY_STRING} ^$
RewriteRule ^document/([^/]{6,12})/?$ document?name=$1 [NE,L]

.htaccess redirects aren't respecting my regex

I need to redirect any requests with query strings from a set of origin URLs back to a thank you page.
For example, I need to redirect:
http://example.com/test1/test2/[origin]/?id=1
back to
http://example.com/thank-you
The way I've got it set up in my .htaccess file is as such:
RewriteEngine On
RedirectMatch 302 ^/test1/test2/(.*)/.+ /thank-you
I've tested the regex I'm using in an online regex tester and it appears to work as expected, so I'm confused as to why the redirect isn't taking place. Here's the link to that.
Obviously, I had to add backslashes to escape the slashes in the URL in the regex tester, but based on my understanding of how .htaccess evaluates regex, these aren't necessary.
My question is: the redirect works perfectly from the page without the query string if I remove the .+ from the end of the regex string, meaning that the beginning part of the regex works fine. I don't understand why the query string isn't matching the regex I've created.
I have also tried:
RewriteCond %{REQUEST_URI} ^/test1/test2/(.*)/
RewriteCond %{QUERY_STRING} id=([0-9]+) [NC]
RewriteRule (.*) /thank-you [R=302,L]
For your RedirectMatch, you may use:
RedirectMatch 302 ^/test1/test2/(.*)/(.*)+ /thank-you?
For your RewriteRule section, you may use:
RewriteCond %{REQUEST_URI} ^/test1/test2/(.*)/
RewriteCond %{QUERY_STRING} id=([0-9]+) [NC]
RewriteRule (.*) /thank-you [R=302,L,QSD]
First , no need to RewriteEngine On with mod_alias which is RedirectMatch at your rules use it with mod_rewrite , the second rules .
Try this :
RewriteEngine On
RewriteCond %{QUERY_STRING} ^id=([0-9]+)$ [NC]
RewriteRule ^test1/test2/[^\/]+/$ /thank-you? [R=302,L]
I use ^id=([0-9]+)$ to restrict query string for a one that start with id and end with numerical value.
I remove this line RewriteCond %{REQUEST_URI} ^/test1/test2/(.*)/ becasue you could match against URI in RewriteRule as well.
If this rules wrok , change [R=302,L] to [R=301,L] to be permanent redirection.
Note: clear browser cache then test

htaccess RewriteRule regex

I have hundreds of these old links I need to redirect.
Here is one example:
/index.php?option=com_content&view=article&id=433:seventh-character-code-categories-and-icd-10-cm&Itemid=101&showall=1
to
/seventh-character-code-categories-and-icd-10-cm
Essentially I need to remove the /index.php?option=com_content&view=article&id=433: part.
I tried this but I am getting confused with the [0-9] and : parts, so the following does not work:
RewriteRule ^/index.php?option=com_content&view=article&id=[0-9]:(.*)$ /$1 [L,R=301]
Say you want to capture from after : to right before & in the query string you mentioned, then try this expression:
^[^\:]*\:([^\&]*)\&.*$
As #starkeen mentioned in comments, you got to check against the query string. This can be done using RewriteCond %{QUERY_STRING}
So if index.php is in the root folder:
RewriteEngine On
RewriteCond %{REQUEST_URI} ^\/index\.php$
RewriteCond %{QUERY_STRING} ^[^\:]*\:([^\&]*)\&.*$
RewriteRule ^(.*)$ http://example.com/%1 [R=301,L]
Here's another example. This one is for a sub folder:
RewriteEngine On
RewriteCond %{REQUEST_URI} ^\/pages\/index\.php$
RewriteCond %{QUERY_STRING} ^[^\:]*\:([^\&]*)\&.*$
RewriteRule ^(.*)$ /pages/%1? [R=301,L]
Also, notice the ? at the end of the url /pages/%1?, this prevents from re-attaching the query string.
Another thing, captured groups will be set to variables %{number} since set in the RewriteCond.
BTW, depending on your server's configuration, you may need to add the NE flag, like [NE,L,R=301] Plus test whether it is necessary to double escape the literal characters.
what is about direct approach. Skip all till semicolon, mach string till & and replace all with first much
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{QUERY_STRING} [^:]+:([\w-]+[^&]).*
RewriteRule .*$ \/%1? [R=301,L]
</IfModule>

Removing additional trailing backslash with .htacess – domain.com/page//

I have content that can display with a double-slash:
domain.com/folder/name//
Obviously this is not ideal.
I want to create a .htaccess 301 rewrite that removes the additional trailing slash:
domain.com/folder/name/
I came-up with:
RewriteRule /(.*)/(.*)// /$1/$2/ [R=301,L]
Though no-dice.
You can't match // in RewriteRule since Apache strips it to single there.
Use RewriteCond instead:
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/+(.*?)/+(/.*)$
RewriteRule ^ /%1%2 [R=302,L,NE]

mod_rewrite trailing slash for directory and remove for file url

Ok. I got this problem I trying to remove the last slash in a file url for example http://domain.com/styles/styles.css/. I got the code for adding slash to the end but cannot figure how to do the conditional.
If the URL has an extesion then remove end slash
else add slash..
Here what I got right now some blogs says its the solution but still isn't working for what I expect.
RewriteCond %{REQUEST_URI} !\.[^./]+$
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteRule ^(.*)([^/])$ http://%{HTTP_HOST}/$1$2/ [L,R=301]
Also a problem, when I type http://domain.com/index it goes to http://domain.com/inde/.
Need your help guys.. Thanks a lot in advance.
add following code in your htaccess, for better understanding.
RewriteCond %{HTTP_HOST} !^\.yourdomain\.com$ [NC]
RewriteRule ^(.+)/$ http://%{HTTP_HOST}/$1 [R=301,L]
I have a link : domain.com/folder/
it will change to : domain.com//folder
also You can turn off mod_dir's redirect by including a DirectorySlash Off.
Why do you want to do an external redirect for such "furniture" files? Surely an internal redirect is what you want here?
Options -MultiViews
RewriteCond %{REQUEST_URI} !-d
RewriteRule ^(.+)/$ $1 [L]
I advise that you turn off mutliviews if you don't use it as this can generate subrequests which confuse things.
Your RewriteCond conditions are logically inverted because you have the ! operator there. So the rewrite is applying only for those inputs which do not have extensions, and which do not have a trailing slash!
You can do this with a single rule with no conditions:
# Match any sequence of characters, ending in a dot followed
# by one or more characters that don't contain dots or slashes,
# followed by a final trailing slash.
#
# Rewrite this absolutely and treat as redirect.
RewriteRule ^(.*\.[^./]+)/$ /$1 [L, R=301]