1

Last time I used regex was to manipulate some BGP routes and it didn't go well. I don't expect anyone to write me a full .htaccess file, but: in which order would you write the lines? Should there be multiple .htaccess files in multiple directories?

There are multiple things I want to achieve:

  1. Remove .html from URL even if users enter .html at the end (e.g I can link to a category in Navbar like https://example.org/category1)

  2. Serve https://example.org for following scenarios:

    • https://example.org
    • http://example.org
    • http://example.org
    • https://example.org/index.html
    • https://www.example.org/index.html
    • http://example.org/index.html
    • http://www.example.org/index.html

    Also, serve https://www.example.org/c/category or https://www.example.org/p/article for any other combination. Use only HTTPS-non-www version.

  3. Disable directory browsing

    This is my file structure:

    • example.org
    • example.org/contact
    • example.org/c/
    • example.org/c/category1
    • example.org/p/
    • example.org/p/article1
    • /css
    • /js
    • /images
  4. Serve my custom 404 page (404.html), also without .html at the end.

You can talk to me like to a labrador. This is my first time spinning up a webserver.

2 Answers 2

2

My answers a little verbose but since the redirects in htaccess are done once and then forgotten about and these needed to be in one place ... you got a verbose answer.

The 404 error document does not redirect the browser to the 404 page.

# when a 404 error happens gives message Oops! We Can't find that file sorry.

ErrorDocument 404 "Oops! We can't find that file Sorry."

# read a file and present it as the 404 page, can be a 404.php page

ErrorDocument 404 /404.html

The advantage to a 404.php file is you may log information about the error not available in the log file. Or the 404.php could look at the URL and suggest an alternative; Because the 404.php is running as if it is the 404 page. One could build a CMS system under the 404 error which would work but look like everything is a page not found, the web-bots would hate you.

Dealing with sending the 301 from the server to the browser is also confusing because the browser caches the last 301 so when you change it the browser may continue to do what it did last time.

use Google, Developer tools > Network tab > disable caching check box ... in the window and tab that you are using to check. A different window or tab may still cache.

First take care of http to https

The rule for going from a http to https is straight forward.

RewriteEngine On
RewriteCond %{SERVER_PORT} ^80$
RewriteRule ^(.*)$ "https://example.com/$1" [R=301,L]

I'm checking the port number as I've double checked this on my sandbox system ... Port 80 is http, I've http connections on ports 80 and 8080 on my sandbox.

Since we don't want https://www.example.com I'm sending the traffic to https://example.com

If we want to combine the http to https with the removal of index.html or index.ht(anything IE wild card).

We will need two sets of Rewrite conditions. And because it is pre-processed by apache the rewriteRule becomes estranged. It can be done but it may be needlessly complex if we do not have links to http://www.example.com/c/index.html and want to use our full budget given by the browser as three redirects ... I tend away from linking to an index.html so I can keep things simple.

RewriteEngine On

# redirect http(.*)index.html to https://example.com 
# or http://www.example.com/index.html to https://example.com/
# and http://example.com/c/index.html to https://example.com/c/
# NOTE !!! this only redirects if an index.html or index.htm exists.

RewriteCond %{SERVER_PORT} ^80$
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule (.*)index\.ht(.*)$ https://example.com/$1 [L,R=301]

# Note for above line 
# the first (.*) is $1 everything between host and index.ht??
# the second (.*) is $2 and we don't need to use it
# the redirect is to http://example.com/[first (.*) is our directory]  


# OK its not an index.html so send we need to redirect non index.ht?? as well.

RewriteCond %{SERVER_PORT} ^80$
RewriteRule ^(.*)$ "https://example/$1" [R=301,L]

The normal Apache file setup is to have one directory for ssl and another for html. The above .htaccess is for sending the html to the SSL. So the above .htaccess can go in the root of the html folder. There are two .conf in etc/apache2/sites-enabled/ one for port 80 and the other for port 443 ... which directory each uses is specified there ... on shared hosting a minimum of two per site, and two per subdomain.

Remove index.html and index.htm from https

We already did that above but we don't to check http so

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule (.*)index.ht(.*)$ https://example.com/$1 [L,R=301]

To remove www from https://www.example.com/

RewriteEngine On
RewriteCond %{HTTP_HOST}  ^www\.example\.com$ [NC]
RewriteRule ^(.*) http://example.com/$1 [L,R]

These two could be combined as well but first consider how the .htaccess would look if you went ahead and allowed multiple 301s, IE http://www.example.com/index.html redirects to https://example.com/index.html and then again to https://example.com/ not ideal from users point of view but it works.

Here's all the needed redirects in a single file.

RewriteEngine On

# 301 to https
RewriteCond %{SERVER_PORT} ^80$
RewriteRule ^(.*)$ "https://example.com/$1" [R=301,L]

# 301 to example.com not www.example.com
RewriteCond %{HTTP_HOST}  ^www\.example\.com$ [NC]
RewriteRule ^(.*) https://example.com/$1 [L,R]

# 301 to remove index.html and index.htm
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule (.*)index\.ht(.*)$ https://example.com/$1 [L,R=301]

# I'm in my budget of 3 with only 2 301 redirects worst case.

ErrorDocument 404 /404.html

# almost forgot disable directory listing.
Options -Indexes
2
  • Hello Wayne! It's been a really long day, but I couldn't wait to tell you that - you are the GOAT. I really appreciate your time. Such a detailed answer was the least expected thing. As there are too many characters in my observation, I posted it as an answer below. There are indeed tom odd things going on. Before I start putting my content up there, this will probably be the biggest headache that I had
    – ErikB
    Oct 14 at 20:54
  • @ErikB well I may need to refer back to it in the distant future, so I'll benefit on a future tomorrow by being a goat, today. Everything I sandbox - gets verbose comments by default.
    – Wayne
    Oct 15 at 0:13
1

To post as an answer, because of too many characters for comment section;

My version .htaccess

# php -- BEGIN cPanel-generated handler, do not edit
# Set the “ea-php80” package as the default “PHP” programming language.
<IfModule mime_module>
  AddHandler application/x-httpd-ea-php80 .php .php8 .phtml
</IfModule>
# php -- END cPanel-generated handler, do not edit

RewriteEngine on

# 301 to https
RewriteCond %{SERVER_PORT} ^80$
RewriteRule ^(.*)$ "https://mysite.tech/$1" [R=301,L]

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

#to remove .html from files
RewriteCond %{REQUEST_URI} ^/(.+)\.html?$ [nocase]
RewriteRule ^ /%1 [L,R=301]

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.html -f
RewriteRule ^ %{REQUEST_URI}.html [END]

ErrorDocument 404 /404.html

Options -Indexes
==================================================================
Your .htaccess
# php -- BEGIN cPanel-generated handler, do not edit
# Set the “ea-php80” package as the default “PHP” programming language.
<IfModule mime_module>
  AddHandler application/x-httpd-ea-php80 .php .php8 .phtml
</IfModule>
# php -- END cPanel-generated handler, do not edit

RewriteEngine On

# 301 to https
RewriteCond %{SERVER_PORT} ^80$
RewriteRule ^(.*)$ "https://mysite.tech/$1" [R=301,L]

# 301 to example.com not www.example.com
RewriteCond %{HTTP_HOST}  ^www\.mysite\.tech$ [NC]
RewriteRule ^(.*) https://mysite.tech/$1 [L,R]

# 301 to remove index.html and index.htm
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule (.*)index.ht(.*)$ https://mysite.tech/$1 [L,R=301]

# I'm in my budget of 3 with only 2 301 redirects worst case.

ErrorDocument 404 /404.html

# almost forgot disable directory listing.
Options -Indexes

The behaviour is the same with both of the above .htaccess files:

    http://www.mysite.tech/c/category1   ---> 301 to http://mysite.tech/c/category1, 301 to https://mysite.tech/c/category1
    https://www.mysite.tech/c/category1  ---> 301 to http://mysite.tech/c/category1, 301 to https://mysite.tech/c/category1 
    http://mysite.tech/c/category1       ---> 301 to https://mysite.tech/c/category1
    https://mysite.tech/c/category1   ---> 200 

   

http://www.mysite.tech/contact      ---> 301 to https://mysite.tech/contact ,all in 1 redirection (both www and http). How come only 1 redirection?
https://www.mysite.tech/contact     ---> 301 to http://mysite.tech/contact, 301 to https://mysite.tech/contact
http://mysite.tech/contact          ---> 301 to https://mysite.tech/contact 
https://mysite.tech/contact         ---> 200 

http://www.mysite.tech/p/article-template ---> 301 to http://mysite.tech/p/article-template, 301 to https://www.mysite.tech/p/article-template
https://www.mysite.tech/p/article-template---> 301 to http://mysite.tech/p/article-template, 301 to https://mysite.tech/p/article-template
http://mysite.tech/p/article-template     ---> 301 to https://mysite.tech/p/article-template
https://mysite.tech/p/article-template    ---> 200


http://www.mysite.tech              ---> 301 to http://mysite.tech, 301 to https://mysite.tech 
https://www.mysite.tech/            ---> 301 to http://mysite.tech, 301 to https://www.mysite.tech 
http://mysite.tech                  ---> 301 to https://mysite.tech 
https://mysite.tech         ---> 200

The phenomenon mysite.tech/c/cloud    - why it gets redirectes to example.com? It makes no sense. 
There is no such thing in .htaccess file. And, there is only 1 .htaccess file on the server. 
I did save it once by mistake with example.com from your .htaccess file, but that was some time ago. 
http://www.mysite.tech/c/cloud   ---> 301 to https://mysite.tech/c/cloud all in 1 redirect
https://www.mysite.tech/c/cloud  ---> 301 to http://mysite.tech/c/cloud, 301: Permanent redirect to https://example.com/c/cloud , 404 https://example.com/c/cloud 404: This page is NOT FOUND
http://mysite.tech/c/cloud       ---> 301: Permanent redirect to https://example.com/c/cloud, 404 https://example.com/c/cloud 404: This page is NOT FOUND
https://mysite.tech/c/cloud      ---> 200 

I don't know if there can be something on the shared server. Also, my domain is hosted on Namecheap, pointed to 3 namesevers that I was provided by hosting company. The website of hosting company was down the first day after I bought hosting :D

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.