Jump to content

Rewrite non-WWW and WWW to HTTPS://WWW


SaranacLake

Recommended Posts

I want a mod_rewrite that will take either a non-WWW or a WWW request and change it to an HTTPS://WWW

I thought the below code would accomplish that, but it seems to be breaking my SESSION sometimes when I try editing the URL...

	## NON-WWW to HTTPS://WWW
##RewriteCond %{HTTP_HOST} !^www\. [NC]
##RewriteCond %{HTTPS} off
##RewriteRule (.*) https://www.%{HTTP_HOST}/$1 [L,R=301]
##
## WWW to HTTPS://WWW
##RewriteCond %{HTTP_HOST} ^www\. [NC]
##RewriteCond %{HTTPS} off
##RewriteRule (.*) https://%{HTTP_HOST}/$1 [L,R=301]
	

What am I doing wrong?

Link to comment
Share on other sites

Correction:

The above code does NOT break my SESSION, however it doesn't work completely as expected.

 

If you go to www.mysite.com then things redirect to https://www.mysite.com

This is correct.

However, if you go to mysite.com then things redirect to https://mysite.com

While this is secure, it isn't what I want.  I want to always end up with: https://www.mysite.com

Thanks.

 

 

 

 

 

Link to comment
Share on other sites

4 minutes ago, requinix said:

All you need is one rule that checks if either it's HTTP or it's non-WWW. Then you redirect to the right domain, which you specify with the SERVER_NAME or by hardcoding it - not using HTTP_HOST.

I don't follow your response....

A user could type in any of these combinations...

mysite.com
www.mysite.com
----
http://mysite.com
http://www.mysite.com
----
https://mysite.com
https://www.mysite.com
    

 

Where I always want them to end up is...

https://www.mysite.com
	

 

That being said, how can you accomplish all of that in ONE rule or ONE rewrite?

I would say that you cannot...

 

Edited by SaranacLake
Link to comment
Share on other sites

4 minutes ago, requinix said:

You can do it with the magic of the word "or". As in "if they try to go to http://something or they try to go to something://mysite.com then redirect them to https://www.mysite.com".

It sounds like you are proposing a way to make my mod_rewrite more "efficient", but why would this code not work as-is?

# NON-WWW to HTTPS://WWW
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteCond %{HTTPS} off
RewriteRule (.*) https://www.%{HTTP_HOST}/$1 [L,R=301]

# WWW to HTTPS://WWW
RewriteCond %{HTTP_HOST} ^www\. [NC]
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}/$1 [L,R=301]
	

 

Edited by SaranacLake
Link to comment
Share on other sites

Describe to me precisely what Apache and mod_rewrite would do if the request was for https://mysite.com. Not what it should do but what it will do.

Once you fix that, you'll be potentially issuing multiple redirects. That's not good. It needs to be just one redirect to solve all the problems, not one redirect at a time fixing one problem at a time.

Link to comment
Share on other sites

15 minutes ago, requinix said:

Describe to me precisely what Apache and mod_rewrite would do if the request was for https://mysite.com. Not what it should do but what it will do.

Well, based on the code I posted above, I guess my code doesn't handle that scenario.

When I was testing the above rewrites, I typed mysite.com into the address bar, let my website load, and then I added/deleted variants listed above to see if things worked - especially since I was complaining earlier that my SESSIONS were getting broken earlier.

My SESSIONS now work, and nothing breaks when I try the variants above, but I'm just being picky and do not want things to go from mysite.com to https://mysite.com

 

15 minutes ago, requinix said:

Once you fix that, you'll be potentially issuing multiple redirects. That's not good. It needs to be just one redirect to solve all the problems, not one redirect at a time fixing one problem at a time.

Is it correct that when you have multiple mod_rewrite rules, one per line, that each new line adds an AND condition?

Is doing an OR condition as simple as adding the word "OR" on the same line?

 

Link to comment
Share on other sites

4 hours ago, SaranacLake said:

Well, based on the code I posted above, I guess my code doesn't handle that scenario.

Correct. It only handles the HTTPS redirection.

Quote

My SESSIONS now work, and nothing breaks when I try the variants above, but I'm just being picky and do not want things to go from mysite.com to https://mysite.com

Good. You're right: it should not do that. It should go from http://mysite.com directly to https://www.mysite.com. One redirection.

Quote

Is it correct that when you have multiple mod_rewrite rules, one per line, that each new line adds an AND condition?

Yes, multiple RewriteConds affecting the same RewriteRule will AND themselves together - unless you say not to.

Quote

Is doing an OR condition as simple as adding the word "OR" on the same line?

Check the documentation.

Link to comment
Share on other sites

 

 @requinix,

Is this what you wanted me to do...

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

 

Or maybe also this...

	RewriteCond %{HTTP_HOST} ^(www\.)?
RewriteCond %{HTTPS} off
RewriteRule (.*) https://www.mysite.com/$1 [L,R=301]
	

 

 

Also, you said...

5 hours ago, requinix said:

All you need is one rule that checks if either it's HTTP or it's non-WWW. Then you redirect to the right domain, which you specify with the SERVER_NAME or by hardcoding it - not using HTTP_HOST.

 

Is SERVER_NAME an Apache constant?

Or is it a PHP constant?

If the former, then how do I find it on my VPS which runs cPanel?

 

 

 

Edited by SaranacLake
Added another question...
Link to comment
Share on other sites

18 minutes ago, SaranacLake said:

Is this what you wanted me to do...


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

"( If the hostname in the browser does not start with "www." or if the hostname in the browser does start with "www." ) and HTTPS is not in use.."

18 minutes ago, SaranacLake said:

Or maybe also this...


	RewriteCond %{HTTP_HOST} ^(www\.)?
RewriteCond %{HTTPS} off
RewriteRule (.*) https://www.mysite.com/$1 [L,R=301]
	

"If the hostname in the browser starts with an optional "www." and HTTPS is not in use..."

 

How about this:

Tell me in English what you want the rewriting to do. Make it sound like the way I described your two examples above.

18 minutes ago, SaranacLake said:

Is SERVER_NAME an Apache constant?

See this page.

Link to comment
Share on other sites

3 minutes ago, requinix said:

How about this:

Tell me in English what you want the rewriting to do. Make it sound like the way I described your two examples above.

Well, I did above, but here goes again...

IF a user requests my website (i.e. domain name)

starting with either a "www." OR with no "www."

AND the request lacks an "https://"

THEN ultimately I want the url to read "https://www.mydomain.com"

SO THAT

it uses my server's SSL certificate

AND is properly formatted like a url should be.

 

The last two code samples I gave should do that, PLUS they do it with one condition like you said I should do.

So did I not apply your advice properly to get what I wanted?

 

 

3 minutes ago, requinix said:

See this page.

I will have to ask my webhost how to determine the SERVER_NAME variable and how to set it to - in my case - www.mysite.com 

That is the proper format of the SERVER_NAME constant, right?

 

Is there any issue hard-coding my domain as www.mysite.com ??

 

Link to comment
Share on other sites

25 minutes ago, SaranacLake said:

IF a user requests my website (i.e. domain name)

starting with either a "www." OR with no "www."

AND the request lacks an "https://"

THEN ultimately I want the url to read "https://www.mydomain.com"

SO THAT

it uses my server's SSL certificate

AND is properly formatted like a url should be.

Good. But what happened to redirecting https://mysite.com to https://www.mysite.com? Do you not want to do that anymore?

25 minutes ago, SaranacLake said:

I will have to ask my webhost how to determine the SERVER_NAME variable and how to set it to - in my case - www.mysite.com 

Don't bother. Just hardcode it.

Link to comment
Share on other sites

2 minutes ago, requinix said:

Good. But what happened to redirecting https://mysite.com to https://www.mysite.com? Do you not want to do that anymore?

If I do my mod_rewrite properly, then Apache should never create a https://mysite.com

Right?

Now if the user typed into the address bar https://mysite.com then I guess my above code doesn't handle that...

 

Here is my last block of code (#NEW 3) with comments...

	# NEW 3a
# IF(not www OR www) AND (not https)
# THEN (https://www.mysite.com)
RewriteCond %{HTTP_HOST} !^www\. [OR]
RewriteCond %{HTTP_HOST} ^www\. 
RewriteCond %{HTTPS} off
RewriteRule (.*) https://www.mysite.com/$1 [L,R=301]
	 
	# NEW 3b
# IF(not www OR www) AND (not https)
# THEN (https://www.mysite.com)
RewriteCond %{HTTP_HOST} ^(www\.)?
RewriteCond %{HTTPS} off
RewriteRule (.*) https://www.mysite.com/$1 [L,R=301]
	

 

This is an interesting site I found...

http://www.ckollars.org/apache-rewrite-htaccess.html#precedence

 

And here is my best attempt at handling the https://mysite.com scenario...

	# NEW 4
# IF((not www OR www) AND (not https)) OR ((https) AND (not www))
# THEN (https://www.mysite.com)
RewriteCond %{HTTP_HOST} ^(www\.)?
RewriteCond %{HTTPS} off
RewriteRule (.*) https://www.mysite.com/$1 [L,R=301]
	RewriteCond %{HTTPS} on
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule (.*) https://www.mysite.com/$1 [L,R=301]
	

 

Comments??

 

Link to comment
Share on other sites

4 minutes ago, SaranacLake said:

If I do my mod_rewrite properly, then Apache should never create a https://mysite.com

Right?

Now if the user typed into the address bar https://mysite.com then I guess my above code doesn't handle that...

And we all know that our users are highly educated and very knowledgeable about things like HTTPS and www/non-www domain names.

4 minutes ago, SaranacLake said:

Here is my last block of code (#NEW 3) with comments...

Good. Now for the next step:

Will mysite.com match the hostname conditions? Will www.mysite.com match the hostname conditions? Will any domain whatsoever match the hostname conditions?

Can you conclude anything from that?

4 minutes ago, SaranacLake said:

And here is my best attempt at handling the https://mysite.com scenario...

So you've added a second rule, yes?

4 minutes ago, SaranacLake said:

Comments??

Does it work? Do you still think it's not possible to do both in one single rule set?

Link to comment
Share on other sites

8 minutes ago, requinix said:

And we all know that our users are highly educated and very knowledgeable about things like HTTPS and www/non-www domain names.

:P

 

8 minutes ago, requinix said:

Good. Now for the next step:

Will mysite.com match the hostname conditions? Will www.mysite.com match the hostname conditions?

Yes.

 

8 minutes ago, requinix said:

Will any domain whatsoever match the hostname conditions?

Interesting point!  😮

Yes, www.requinix.com would rewrite to https://www.mysite.com

 

8 minutes ago, requinix said:

Can you conclude anything from that?

a.) Don't trust what you read on the Internet!

b.) I guess I technically need *specificity*, right?

Maybe...

RewriteCond %{HTTP_HOST} ^(www\.)?(.*)$

 

8 minutes ago, requinix said:

So you've added a second rule, yes?

Does it work? Do you still think it's not possible to do both in one single rule set?

Based on the link I posted above, it seems tricky at best to do complicated AND/OR logic with mod_rewrites since you cannot use parentheses.

I didn't feel confident doing it all in one rule.

Do you know how?  If so, can you share a solution?

 

As far as testing, I am actually doing a backup/clone of my Mac and it will be tied up for a few hours.

In the mean time I am just trying to think things out in NotePad...

😉

 

Link to comment
Share on other sites

4 minutes ago, SaranacLake said:

a.) Don't trust what you read on the Internet!

b.) I guess I technically need *specificity*, right?

Maybe...

Maybe, if your rule is matching the hostname of every single domain then maybe, you don't need to test for the hostname at all...

4 minutes ago, SaranacLake said:

Do you know how?  If so, can you share a solution?

You might kick yourself over this.

RewriteCond %{HTTP_HOST} !^www\. [OR]
RewriteCond %{HTTPS} off
RewriteRule ^ https://www.mysite.com%{REQUEST_URI} [L,R=301]

Think about what it does for each of the four conditions:
1. http and mysite.com
2. http and www.mysite.com
3. https and mysite.com
4. https and www.mysite.com

As for the last line, I did the same thing as you had, but I prefer my version because it doesn't require doing any regular expression matching, it doesn't rely on mod_rewrite automatically appending any query string, and it's overall just more explicit and obvious about where it's redirecting to.

Link to comment
Share on other sites

10 minutes ago, requinix said:

Maybe, if your rule is matching the hostname of every single domain then maybe, you don't need to test for the hostname at all...

You might kick yourself over this.


RewriteCond %{HTTP_HOST} !^www\. [OR]
RewriteCond %{HTTPS} off
RewriteRule ^ https://www.mysite.com%{REQUEST_URI} [L,R=301]

Think about what it does for each of the four conditions:
1. http and mysite.com
2. http and www.mysite.com
3. https and mysite.com
4. https and www.mysite.com

 

I went back to the scenarios that I spelled out earlier, and mapped things to your code...

	# NEW 5
# Scenarios...
#
# mysite.com  ===> COND1
# www.mysite.com  ===> COND2
# ----
# http://mysite.com  ===> COND1
# http://www.mysite.com  ===> COND2
# ----
# https://mysite.com  ===> COND1
# https://www.mysite.com  ==> OK AS-IS
RewriteCond %{HTTP_HOST} !^www\. [OR]
RewriteCond %{HTTPS} off
RewriteRule ^https://www.mysite.com%{REQUEST_URI} [L,R=301]
	

 

 As always, you're a GENIUS, @requinix!!  🏆

 

 

10 minutes ago, requinix said:

As for the last line, I did the same thing as you had, but I prefer my version because it doesn't require doing any regular expression matching, it doesn't rely on mod_rewrite automatically appending any query string, and it's overall just more explicit and obvious about where it's redirecting to.

Okay, fair enough.

 

So, I will have to test this out later when my backup is done, but it looks like thanks to you I have a better understanding of things and cleaner code.

Of course there is still (likely) a gotcha here... 😉

When I ran the code in my OP - which worked and didn't break my SESSION but which did miss the https://mysite.com scenario - I ran into another problem...

On my VPS I am running CloudFlare, and while the code in my OP worked good enough with CloudFlare temporarily turned off, when I turned CLoudFlare back on, it not only sent Apache into an infinite loop, but it crahsed my Mac?! :o

 

@requinix, should I start another thread about that, or continue n in this thread?

 

Link to comment
Share on other sites

@requinix,

I just tested your code, and while it mostly works, there were two web pages where when I loaded them, and then deleted off the "https://www." I was redirected to my "Access Denied" error-handling page, which means that my SESSION didn't like me changing the URL.

When I tested my code in my OP, I did not have this issue.  (This is with Cloudflare turned OFF.)

Any ideas how to prevent your code from agitating my SESSION???

Link to comment
Share on other sites

12 hours ago, requinix said:

"My" code has nothing to do with your session.

If your sessions are breaking then your session cookie configuration is wrong. Likely the domain: it needs to be either "www.mysite.com" or ".mysite.com".

From what I have read, mod_rewrites can most certainly break SESSIONS if you are redirecting the wrong way. 

In addition to the SESSION sometimes breaking when I modify the URL for testing purposes, I got a weird error last night...

  •     Notice: session_start(): ps_files_cleanup_dir: opendir(/var/cpanel/php/sessions/ea-php72) failed: Permission denied (13) in path/to/index.php
        so on so on

        

I am thinking that the way cPanel is set up might need to be tweaked, so for now let's assume that "your" 😉 mod_write is correct...

 

At any rate, I do need help getting all of this to work with CloudFlare...

13 hours ago, requinix said:

Sounds like maybe your CloudFlare configuration is wrong.

 

Can I post my questions here, or should I start a new thread?

 

 

Edited by SaranacLake
Link to comment
Share on other sites

1 hour ago, SaranacLake said:

From what I have read, mod_rewrites can most certainly break SESSIONS if you are redirecting the wrong way. 

There aren't too many ways to break it. As long as your session configuration uses the right domain names and paths, and as long as the redirect does what it is supposed to do, then sessions will continue to work.

Quote

In addition to the SESSION sometimes breaking when I modify the URL for testing purposes, I got a weird error last night...

  •     Notice: session_start(): ps_files_cleanup_dir: opendir(/var/cpanel/php/sessions/ea-php72) failed: Permission denied (13) in path/to/index.php
        so on so on

Some sort of permissions are wrong. Like, the user PHP is running as does not have permissions on that ea-php72 directory. I can't explain why.

Quote

Can I post my questions here, or should I start a new thread?

Might as well as here. If it's too complicated I'll split the post(s) into a new thread.

Link to comment
Share on other sites

27 minutes ago, requinix said:

There aren't too many ways to break it. As long as your session configuration uses the right domain names and paths, and as long as the redirect does what it is supposed to do, then sessions will continue to work.

Here is a link to a thread that I started before this one and asking about these erratic log-in/SESSION issues...

https://forums.phpfreaks.com/topic/309716-problems-logging-in/

A few posts down I posted the code related to this.

 

Ask #1:

@requinix, if you could check out how I was doing SESSIONS and redirecting it might help you to help me solve this issue.  (In the past, I thought using PHP sessions was as simple as starting a SESSION on each page, but maybe there is more to it than that?!)

 

Quote

Some sort of permissions are wrong. Like, the user PHP is running as does not have permissions on that ea-php72 directory. I can't explain why.

You would think that my webhost would have things configured to work out-of-the-box?! 

I have a ticket in, but who knows when I will get a response - let alone a solution?!

 

 

Ask #2:

@requinix

Quote

Might as well as here. If it's too complicated I'll split the post(s) into a new thread.

So my questions relate to how my mod_rewrites - that you helped me with above - should be set up to work with CloudFlare.  (I set up a free account to obuscate my VPS from people and add a little security.)

Originally when my mod_rewrites looked like in my OP (shown again below), they seemed to be mostly working in that they no longer broke my SESSION but there was the fact my code wasn't handling the https://mysite.com to https://www.mysite.com scenario.

Original mod_rewrite code:

	# NON-WWW to HTTPS://WWW
	RewriteCond %{HTTP_HOST} !^www\. [NC]
	RewriteCond %{HTTPS} off
	RewriteRule (.*) https://www.%{HTTP_HOST}/$1 [L,R=301]
	 
	# WWW to HTTPS://WWW
	RewriteCond %{HTTP_HOST} ^www\. [NC]
	RewriteCond %{HTTPS} off
	RewriteRule (.*) https://%{HTTP_HOST}/$1 [L,R=301]
	

 

HOWEVER, when I turned ON CloudFlare, the above code sent Apache into an infinite loop, and even after killing it in the Activity Manager, I had to reboot my MacBook to get everything working properly.

In order to fix this issue, my webhost suggested the following code...

Webhost code:

	RewriteCond %{HTTP_HOST} !^www\.
RewriteRule (.*) https://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
RewriteCond %{HTTPS} off
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
	

 

This code from my webhost fixed things, but it looks poorly written from a mod_rewrite standpoint!

I conceded that the code @requinix helped write above is better, and I would like to use it, but I am concerned that it might cause the same issue.  (nd, NO, I haven't tried the code you helped me with yet, because I have a window open on my Mac with the new error I got above, and I'm afraid Apache might crash again and lock up my Mac, so I am waiting to hear back from my webhost on the permission issue FIRST before testing things out.

In the mean time, I did some research and found this...

https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Proto

The gist of it is that in order to see what a user requests between his/her computer and CloudFlare, you need to use X-Forwarded-Proto,

It seems that in order to get the code we worked with yesterday, I would need to tweak your code and somehow include the X-Forwarded-Proto but I'm not sure where to begin on this...

Can you comment on this second issue, @requinix?

Thanks!

 

 

Edited by SaranacLake
Link to comment
Share on other sites

6 minutes ago, SaranacLake said:

Originally when my mod_rewrites looked like in my OP (shown again below), they seemed to be mostly working in that they no longer broke my SESSION but there was the fact my code wasn't handling the https://mysite.com to https://www.mysite.com scenario.

Yes, you keep saying that. But it's irrelevant. You didn't have redirects working the way they needed to work so what your site was or was not doing doesn't matter.

You might as well say that "my car is making rattling noises when I turn it on, but it wasn't doing that when I had it turned off...".

6 minutes ago, SaranacLake said:

Original mod_rewrite code:

I'm ignoring it.

6 minutes ago, SaranacLake said:

HOWEVER, when I turned ON CloudFlare, the above code sent Apache into an infinite loop, and even after killing it in the Activity Manager, I had to reboot my MacBook to get everything working properly.

What does the access log say?

6 minutes ago, SaranacLake said:

In order to fix this issue, my webhost suggested the following code...

Their version is not proper because it will result in multiple redirects: http and mysite.com -> https and mysite.com -> https and www.mysite.com.

What they do show is the use of X-Forwarded-Proto. It suggests that your CloudFlare configuration is middleman-ing the HTTPS: browser thinks it wants HTTPS, goes to CloudFlare, CloudFlare handles the SSL and then forwards it as HTTP to your server.

Is that what it's doing? Are you seeing many duplicate entries in your access log?

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.