views:

31

answers:

1

I have html static files on my server. I want the access rules as -

  1. If user visits http://example.com/test/ he should get the contents of the file http://example.com/test.html
  2. 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)
  3. 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>
+2  A: 

Try these rules:

RewriteCond %{REQUEST_FILENAME}.html -f
RewriteRule ^[^/]+$ %{REQUEST_URI}/ [L,R=301]
RewriteRule ^([^/]+)/$ $1.html [L]
Gumbo
Sorry, 404s for both http://example.com/test and http://example.com/test/
pravin
@pravin: Oh, fixed it.
Gumbo
Sorry, still 404s
pravin
@pravin: Do you use my rules only or my rules and your rules at the same time?
Gumbo
I've updated my code to include the new .htaccess with your rules
pravin
@pravin: I don’t see why this shouldn’t work. It works for me at least.
Gumbo
@Gumbo: Does your .htaccess look exactly like mine? Maybe I'm doing something wrong.
pravin
@pravin: Try to debug the rules with mod_rewrite’s logging feature (see [`RewriteLogLevel`](http://httpd.apache.org/docs/2.2/mod/mod_rewrite.html#rewriteloglevel)).
Gumbo