Home > Software design >  .htaccess Case-Sensitivity and File Extensions
.htaccess Case-Sensitivity and File Extensions

Time:10-28

I'd like to do 2 things with my .htaccess file on https://example.com

  1. I want all file paths to not be case sensitive. Currently all of my files and folder start with a capital letter.

  2. I want all files to be able to be viewed and accessed without adding the file extension to the end.

My current .htaccess file:

ErrorDocument 401 https://www.example.com
ErrorDocument 403 https://www.example.com
ErrorDocument 404 https://www.example.com
ErrorDocument 500 https://www.example.com

RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301,NE]
Header always set Content-Security-Policy "upgrade-insecure-requests;"

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ https://www.example.com%{REQUEST_URI} [R=302,L]

RewriteCond %{HTTP_HOST} ^example\.com\.subdomains\.example\.com$
RewriteRule ^/?$ "https\:\/\/example\.com\/" [R=301,L]

CodePudding user response:

  1. I want all file paths to not be case sensitive. Currently all of my files and folder start with a capital letter.

Since the underlying filesystem path is mixed case you will need to use mod_speling (one l). (You will need access to the server config to ensure this module is enabled.)

Then you can use the following in .htaccess:

# Allow mixed case requests (mod_speling)
CheckSpelling on
CheckCaseOnly on

Note, however, that this triggers an external redirect to the correctly cased URL. So, if the user requests /foo/bar/baz, they will be externally redirected to /Foo/Bar/Baz.

However, if this generates a 500 Internal Server Error then mod_speling probably isn't installed.

  1. I want all files to be able to be viewed and accessed without adding the file extension to the end.

I'm assuming you are referring to just the main .html (or .php) files that are part of your page requests and not literally all files, as in all static resources, eg. image / image.jpg, mystyles / mystyles.css, etc.

You would need to add something like the following immediately after the HTTP to HTTPS redirect and before the redirect that sends non-existent requests to an external server.

# Rewrite request to append file extension. eg. "/foo" to "/foo.html"
RewriteCond %{REQUEST_URI} !(\.\w{2,4}|/)$
RewriteCond %{DOCUMENT_ROOT}/$1.html -f
RewriteRule (. ) $1.html [L]

The first condition avoids checks that the request does not already end with a file extension (or a slash - that indicates a directory). The side-effect of this is that you can't have dots in the final path-segment that "looks like" a file extension (an edge case that can usually be avoided). eg. /example.foo will not be rewritten to /example.foo.html (if that file should exist). But /foo.example could potentially be rewritten. This is an optimisation to avoid a lot of unnecessary filesystem checks.

The second condition checks that the corresponding .html exists before rewriting the request.

You need to make sure you are consistently linking to the URL without the file extension in order to avoid potential duplicate content issues (and exposing the file extension to your users).

If you are changing an existing URL structure then you can implement an external redirect to remove the .html file extension from URLs that are requested directly. This would be necessary in order to preserve SEO and any backlinks. However, this is not a replacement for changing the internal links in your HTML source to remove the .html extension.

If this is required then add the following before the above "rewrite":

# Redirect - remove the ".html" extension, eg. "/foo.html" to "/foo"
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule (. )\.html$ /$1 [R=301,L]

NB: Test first with a 302 (temporary) redirect to avoid potential caching issues.


UPDATE#1:

It's using the LiteSpeed server.

Unfortunately, mod_speling is not currently supported on LiteSpeed - this is an Apache-only module.

And (unfortunately)... LiteSpeed does not "break" when it reads an error in the .htaccess file - it simply ignores it (silently). Which makes debugging these things that much harder.

You won't be able to make the URLs case-insensitive on LiteSpeed without a lot of work (read: it's not worth it). Just make sure you use correctly cased URLs throughout your site (or convert everything to lowercase).


UPDATE#2:

I'm wanting that to work for all files including images and other static files.

Unless you have a very good reason for doing this I would recommend against that. Again, LiteSpeed does not support MultiViews/mod_negotiation - which would be "the easy" way to do this on Apache. (However, MultiViews can conflict with rewrites you might add later and cause you other problems unless you are experienced with this.)

To do this on LiteSpeed would be a rather tedious (and resource-intensive) process of manually checking every file extension to see whether it exists.

You can also have mime-type issues since the browser is unable to infer anything from the file extension. And users that downloaded anything will have to manually add the appropriate file extension for it to "work" locally.

This also opens you up to many "duplicate" issues unless you implement the redirect to strip the file extension.

  • Related