1

The issue happens when you:

  1. issue a request with the header "Host" including the port, e.g. "Host: www.example.com:80", which is legal as per https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.23. You can do it for instance with curl curl -v -H "Host: www.example.com:80" -X GET -i http://www.example.com
  2. the server issues a redirect to https for that request, in my case using the following RewriteRule
 RewriteCond %{HTTPS} off RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L] 

I noticed that the "Location" header of the response also includes the port, and it's the same of that specified in the "Host" header of the request. So the server would respond with "Location: https://www.example.com:80", which is wrong.

This happens to me with "Apache/2.4.7 (Ubuntu)", but I noticed the issue also with Varnish cache server. Why does it behave this way? Is there a way to correct this?

4
  • What is the reason for using RewriteRule for this? I find it easier to simply have separate <VirtualHost> sections for HTTP and HTTPS. In that case the HTTP section only needs to use a Redirect and it can be trimmed down a lot. And why are you using the Host header to find out where to redirect to? You could end up redirecting to a domain for which you don't have a certificate. I would instead write an actual domain name in the Redirect directive such that it is guaranteed to match the certificate. Commented Nov 10, 2016 at 8:37
  • There actually is a virtual host for http and a virtual host for https, I wanted to have all traffic on https and for me it's easier to have shared content of virtual hosts. I'm not using the Host header to find out where I need to go, I use the Location header of the response, which is wrongly populated with the port specified in the request Host header. Commented Nov 10, 2016 at 8:42
  • 1
    You are using the Host header from the client. Why? I assume you know the domain name of your server. Why not write the domain name in a Redirect directive instead of relying on the client to tell you? I have done it like this Redirect / https://example.com/ which has worked without any problems. Commented Nov 10, 2016 at 8:49
  • You are right, I'm sorry: I've been using this configuration for a while and I wasn't really reading it anymore. For those who don't see it it's %{HTTP_HOST}. With the redirect you say, the problem doesn't happen. Why have I been using this? Because I found it out years ago answers with many points on stackoverflow, for instance in stackoverflow.com/a/3239775/1504300 and stackoverflow.com/a/4083233/1504300. Now that I see it, my question is pretty obvious, but I think you should answer "officially", then I would point this entire question in those 2 mentioned as "why not". Commented Nov 10, 2016 at 9:09

1 Answer 1

1

HTTP_HOST refers to the Host: header specified, so your configuration works as expected based on what you're telling it to.

If you want to, you can either strip away the port, or specify another by matching it and using a backreference:

Remove port and default to https:

RewriteCond %{HTTP_HOST} ^([^:]+)(:[0-9]+)?$ RewriteRule ^ https://%1%{REQUEST_URI} [R=301,L] 

Change the port to something else (8443 here):

RewriteCond %{HTTP_HOST} ^([^:]+)(:[0-9]+)?$ RewriteRule ^ https://%1:8443%{REQUEST_URI} [R=301,L] 
1
  • This should be in addition to the existing HTTPS check, otherwise you risk getting a loop Commented Nov 10, 2016 at 9:48

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.