I have html static files on my server. I want the access rules as -
- If user visits http://example.com/test/ he should get the contents of the file http://example.com/test.html
- If the user visits http://example.com/test (without the trailing slash), he gets redirected to http://example.com/test/ (which runs rule 1 and gets him the contents of the file test.html)
- Rules 1 and 2 should only fire if the file test.html exists.
So far, I have -
Options All -Indexes -Multiviews
# Do not return details of server
ServerSignature Off
<IfModule mod_rewrite.c>
DirectorySlash Off
RewriteEngine On
RewriteBase /
# If it's a request to index.html
RewriteCond %{THE_REQUEST} \ /(.+/)?index\.html(\?.*)?\ [NC]
# Remove it.
RewriteRule ^(.+/)?index\.html$ /%1 [R=301,L]
# Add missing trailing slashes to directories if a matching .html does not exist.
RewriteCond %{SCRIPT_FILENAME}/ -d
RewriteCond %{SCRIPT_FILENAME}.html !-f
RewriteRule [^/]$ %{REQUEST_URI}/ [R=301,L]
# If it's a request from a browser, not an internal request by Apache/mod_rewrite.
RewriteCond %{ENV:REDIRECT_STATUS} ^$
# And the request has a HTML extension. Redirect to remove it.
RewriteRule ^(.+)\.html$ /$1 [R=301,L]
# If the request exists with a .html extension.
RewriteCond %{SCRIPT_FILENAME}.html -f
RewriteRule ^(.*)/?$ $1.html [QSA,L]
</IfModule>
Although it works for http://example.com/test, it fails for http://example.com/test/ (500 internal error)
Shouldn't the second last line take care of trailing slashes?
[Update] If I use Gumbo suggestions (.htaccess follows), I get a 404 for both http://example.com/test and http://example.com/test/ (with trailing slash)
Options All -Indexes -Multiviews
# Do not return details of server
ServerSignature Off
ErrorDocument 404 /404.html
# Hide .htaccess
<Files ~ "^\.ht">
Order allow,deny
Deny from all
</Files>
<IfModule mod_rewrite.c>
DirectorySlash On
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME}.html -f
RewriteRule ^[^/]+$ %{REQUEST_URI}/ [L,R=301]
RewriteRule ^([^/]+)/$ $1.html [L]
</IfModule>
[Update 2] I have given up. The code below works, but instead of forcing everything end with a / (http://example.com/test/), it removes the trailing slash (http://example.com/test). On the bright side, it ensures that the content is pointed to by only one url, preserving SEO. I'm going to live with it for now.
Options All -Indexes -Multiviews
# Do not return details of server
ServerSignature Off
ErrorDocument 404 /404.html
# Hide .htaccess
<Files ~ "^\.ht">
Order allow,deny
Deny from all
</Files>
<IfModule mod_rewrite.c>
DirectorySlash On
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)/$ /$1 [R=301,L]
# If the request exists with a .html extension.
RewriteCond %{SCRIPT_FILENAME}.html -f
# And there is no trailing slash, rewrite to add the .html extesion.
RewriteRule [^/]$ %{REQUEST_URI}.html [QSA,L]
</IfModule>