homepage Welcome to WebmasterWorld Guest from 107.20.34.144
register, free tools, login, search, pro membership, help, library, announcements, recent posts, open posts,
Become a Pro Member

Home / Forums Index / Code, Content, and Presentation / Apache Web Server
Forum Library, Charter, Moderators: Ocean10000 & incrediBILL & phranque

Apache Web Server Forum

    
htaccess trailing slash + rule order
Best htaccess rule order and remove trailing slash
132shaun132



 
Msg#: 4646245 posted 7:06 am on Feb 18, 2014 (gmt 0)

Hi everyone,

I have a few questions regarding .htaccess files and they are as follows:

1. I am very new to .htaccess and wrote one for my website by copying and pasting from all over the web so i was wondering if someone here could advise me on the correct order i should place my rules.
Here is my .htaccess...

AddDefaultCharset utf-8
Options +FollowSymLinks
RewriteEngine On

# Remove trailing slash
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ $1 [R=301]

# Redirect index to root
RewriteCond %{THE_REQUEST} ^.*/index\.php
RewriteRule ^(.*)index.php$ /$1 [R=301,L]

# Block attack
RewriteCond %{HTTP_USER_AGENT} libwww-perl.*
RewriteRule .* [F,L]

# Canonical remove www
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ http://%1%{REQUEST_URI} [R=301,QSA,NC,L]

# Keep domain on top
RewriteCond %{HTTP_HOST} !^example.com$ [NC]
RewriteCond %{HTTP_HOST} !^static.example.com$ [NC]
RewriteCond %{HTTP_HOST} !^m.example.com$ [NC]
RewriteRule ^(.*)$ http://example.com/$1 [R=301,L]

# Remove php extension
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s([^.]+)\.php [NC]
RewriteRule ^ %1 [R=301,L]
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^ %{REQUEST_URI}.php [L]

ErrorDocument 403 /403.shtml
ErrorDocument 404 /404.shtml
ErrorDocument 500 /500.shtml

AddOutputFilterByType DEFLATE text/plain
AddOutputFilterByType DEFLATE text/html
AddOutputFilterByType DEFLATE text/css
AddOutputFilterByType DEFLATE application/xml
AddOutputFilterByType DEFLATE application/xhtml+xml
AddOutputFilterByType DEFLATE application/javascript

<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType text/css "access plus 1 month"
ExpiresByType image/jpg "access plus 1 month"
ExpiresByType image/jpeg "access plus 1 month"
ExpiresByType image/png "access plus 1 month"
ExpiresByType image/gif "access plus 1 month"
ExpiresByType application/javascript "access plus 1 month"
ExpiresByType image/x-icon "access plus 1 year"
</IfModule>

2. Is there anything important that i am missing in the htaccess file or if there is any changes / recommendations you may have?

3. I have a slight problem with trailing slash's everything is fine but when it comes to main home/index page it does not seem to work.

Example:
example.com////
Will not rewrite/redirect to
example.com

All other pages work fine with this rule.

I thank you for your help/comments if you are nice enough to leave one :)

Regards Shaun.

[edited by: phranque at 1:53 pm (utc) on Feb 18, 2014]
[edit reason] unlinked url [/edit]

 

phranque

WebmasterWorld Administrator phranque us a WebmasterWorld Top Contributor of All Time 10+ Year Member Top Contributors Of The Month



 
Msg#: 4646245 posted 2:12 pm on Feb 18, 2014 (gmt 0)

RewriteBase /

unnecessary

RewriteCond %{THE_REQUEST} ^.*/index\.php

^.* is superfluous if you aren't capturing anything.

RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ $1 [R=301]

any 301 redirect should include the [L] flag and the substitute string should include the full canonical protocol and hostname.
RewriteRule ^(.*)/$ http://example.com/$1 [R=301,L]

# Block attack
RewriteCond %{HTTP_USER_AGENT} libwww-perl.*
RewriteRule .* [F,L]

move the block before the redirects.
it doesn't make sense to 301 to a 403.

# Canonical remove www
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ http://%1%{REQUEST_URI} [R=301,QSA,NC,L]

i'm pretty sure this ruleset is unnecessary given the following ruleset.

RewriteCond %{HTTP_HOST} !^example.com$ [NC]
RewriteCond %{HTTP_HOST} !^static.example.com$ [NC]
RewriteCond %{HTTP_HOST} !^m.example.com$ [NC]

i would combine these into one conditional and also add handling for HTTP/1.0 requests which don't send a HTTP_HOST header:
RewriteCond %{HTTP_HOST} !^((m\.|static\.)?example\.com)?$ [NC]

# Remove php extension
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s([^.]+)\.php [NC]
RewriteRule ^ %1 [R=301,L]

add the full canonical protocol and hostname.
move the rule set to before the general hostname canonicalization redirect to avoid chained 301 responses.

132shaun132



 
Msg#: 4646245 posted 10:46 pm on Feb 18, 2014 (gmt 0)
phranque thank you very much for you help.

I have made some changes to the file that i could do myself and i have got the following so far...

# Block attack
RewriteCond %{HTTP_USER_AGENT} libwww-perl.*
RewriteRule .* [F,L]

# Remove trailing slash
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ $1 [R=301,L]

# Redirect index to root
RewriteCond %{THE_REQUEST} ^.*/index\.php
RewriteRule ^(.*)index.php$ /$1 [R=301,L]

# Remove php extension
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s([^.]+)\.php [NC]
RewriteRule ^ %1 [R=301,L]
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^ %{REQUEST_URI}.php [L]

# Canonical remove www
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ http://%1%{REQUEST_URI} [R=301,QSA,NC,L]

# Keep domain on top
RewriteCond %{HTTP_HOST} !^((m\.|static\.)?example\.com)?$ [NC]
RewriteRule ^(.*)$ http:/[smilestopper]/example.com/$1 [R=301,L]

Does it all look fine so far?

I was un-able to remove "RewriteBase /" due problems as i was getting redirected to:
http:/[smilestopper]/example.com/home/USERNAME/public_html/example.com/page
and regarding RewriteCond %{THE_REQUEST} ^.*/index\.php would this be simply changed to RewriteCond %{THE_REQUEST} /index\.php removing the ^.* only.

As i stated in my first post:
example.com////
Will still not rewrite to
example.com

Any ideas why?

Thanks Shaun.
lucy24

WebmasterWorld Senior Member lucy24 us a WebmasterWorld Top Contributor of All Time Top Contributors Of The Month



 
Msg#: 4646245 posted 1:11 am on Feb 19, 2014 (gmt 0)

As i stated in my first post:
example.com////
Will still not rewrite to
example.com

Good. You don't want it to. You do want it to redirect, and that's where .* falls down. There are two approaches:

RewriteCond !-d
RewriteRule ^((?:[^/]+/)*[^/]+)/+$ http://www.example.com/$1 [R=301,L]

and

RewriteCond !-d
RewriteCond %{REQUEST_URI} ^/((?:[^/]+/)*[^/]+)/+$
RewriteRule \w/+$ http://www.example.com/%1 [R=301,L]

If you use extensionless URLs and you have no literal periods in path or directory names, replace all [^/] with [^./]. If one or the other but not both, replace either the final or non-final of each pair. I can explain this better if it applies to your site.

The second (longer) version may seem redundant, but it saves your server the extra work of capturing when the rule ends up not applying-- which will be the vast majority of requests.

Global Options:
 top home search open messages active posts  
 

Home / Forums Index / Code, Content, and Presentation / Apache Web Server
rss feed

All trademarks and copyrights held by respective owners. Member comments are owned by the poster.
Home ¦ Free Tools ¦ Terms of Service ¦ Privacy Policy ¦ Report Problem ¦ About ¦ Library ¦ Newsletter
WebmasterWorld is a Developer Shed Community owned by Jim Boykin.
© Webmaster World 1996-2014 all rights reserved