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?

  • 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. – kasperd Nov 10 '16 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. – reallynice Nov 10 '16 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. – kasperd Nov 10 '16 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". – reallynice Nov 10 '16 at 9:09

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]
| improve this answer | |
  • This should be in addition to the existing HTTPS check, otherwise you risk getting a loop – Erik Weber Nov 10 '16 at 9:48

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.