3

Apache does not force HTTPS in a subfolder of a folder, but it works in the first level subfolders.

Here are all the HTAccess snippets I have tried:

RewriteCond %{HTTP:CF-Visitor} '"scheme":"http"'
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=302,L]
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}/$1 [R=302,L]

RewriteCond %{SERVER_PORT} !=443 [OR]
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^(.*)$ https://www.%{HTTP_HOST/$1 [R=302,L]

RewriteCond %{HTTPS} off
RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [L,R=302]
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule .* https://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=302]

Hope someone has the answer

Edit: After playing around with it some more I found part of the problem.

For example in one of the subdirectories in one of the subfolders directly under the site root, in the HTAccess file, I had this code

RewriteRule ^jquery_autocomplete.html$ jquery_autocomplete.php [L]

As soon as I add that line, for whatever reason it stops forcing HTTPS in that subdirectory, but as soon as I remove it again, HTTPS is forced.

  • Which version of Apache? – MrWhite Nov 15 '15 at 17:55
1

You may want to consider not using .htaccess. This will help with performance and avoid that other .htaccess files overwrite your conf. In your main apache .conf file you can add:

<Directory "YOUR WEB DIRECTORY">
   AllowOverride None
   .....
   RewriteCond %{HTTPS} off
   RewriteCond %{HTTP:X-Forwarded-Proto} !https
   RewriteRule ^ https://www.example.com%{REQUEST_URI} [L,R=301]
   ....
</Directory>

If this is a permanent change, using 301 instead of 302 is better, 302 is temporary

  • I always use 302 until I test that the rule works which is when I change it to 301 but thanks for the tip anyway :) – itteam Dec 29 '15 at 16:18
  • "...avoid that other .htaccess files overwrite your conf" - Specifically, it is the AllowOverride None directive here that prevents .htaccess from "overwriting the conf" - because it disables .htaccess altogether. However, you can prevent .htaccess directives from "overwriting your conf" and still have .htaccess enabled, by placing these directives outside of the <Directory> container, directly in the virtualhost or server context. Or, by changing the mod_rewrite inheritance order using the RewriteOptions directive. – MrWhite Oct 19 '18 at 23:03
  • However, if you have access to the server config then you probably shouldn't be using mod_rewrite anyway for HTTP to HTTPS redirects. Instead, you should be using the simpler mod_alias Redirect in the appropriate VirtualHost container - unless you are behind a proxy, which is suggested by the code posted here - but that is not the case as stated in the question. – MrWhite Oct 19 '18 at 23:08
2

in one of the subdirectories in one of the subfolders directly under the site root, in the HTAccess file, I had this code

And that's the problem. By default, mod_rewrite does not inherit the directives from parent folders. So the mod_rewrite directives in the subfolder completely override the directives in parent folders (the directives that canonicalize the URL). In fact, simply enabling the RewriteEngine in the subfolder is enough to block the parent directives.

In the .htaccess file in the subdirectory you can try adding the following:

RewriteOptions Inherit

However, you should note that mod_rewrite directives in the parent .htaccess file are applied after the directives in the subfolder. (Also, the inherited directives are "virtually copied" to the subfolder's .htaccess file - so they may not behave quite as expected.)

If you are on Apache 2.4+ then you have additional options. For instance, you could specify the following in the .htaccess file in your document root to inherit the parent directives for all subfolders .htaccess files and the parent directives are executed first.

RewriteOptions InheritDownBefore

Reference:
http://httpd.apache.org/docs/current/mod/mod_rewrite.html#rewriteoptions


In order to force HTTPS and www in one rule you can do something like:

RewriteCond %{HTTPS} !on [OR]
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule (.*) https://www.example.com/$1 [R=302,L]

Similar to what you already had, but you can't use %{HTTP_HOST in the substitution (incidentally you are missing the closing curly brace), since this may or may not already contain the www. subdomain. (You might be able to use %{SERVER_NAME} but that is server dependent.)

The 302 (temporary) redirect is good for testing, but change this to 301 when you are happy it's working OK.

To have two separate rules then use your 3rd code block.

  • Thanks :) It works I just have one more question. When I add the RewriteOptions Inherit directive to the correct HTAccess file, and then remove the WWW and HTTPS from the browser's address bar, it redirects back to https: // www. domain. tld and requests the correct resource but still appends the file extension on the end. Is there any way to solve this? – itteam Nov 15 '15 at 19:00
  • My Apache version is 2.4.12 – itteam Nov 15 '15 at 19:07
  • Yes, that will happen unfortunately since the parent directives are run after the directives in the subfolder. (You internally rewrite to the .php file, but then externally redirect to the correct HTTPS/www.) If you are on Apache 2.3.10+ you can change Inherit to InheritBefore to get the parent directives to execute first. – MrWhite Nov 15 '15 at 19:09
  • Since you are on Apache 2.4 you can try the InheritDownBefore option as mentioned above - note that this goes in the parent .htaccess file, not the subfolder. (It inherits down.) – MrWhite Nov 15 '15 at 19:11
  • Which would you recommend, InheritBefore or InheritDownBefore – itteam Nov 15 '15 at 19:12

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.