Php – How to make an Apache 301 redirect to retain the referrer

apache-2.4httpmod-rewritePHP

I have an Apache 301 redirect in my httpd.conf file which redirects all traffic to a single domain for canonicalization purposes. I recently noticed this redirect does not retain the referrer in the headers. RFC2616 seems to indicate preserving the referrer is optional on a redirect and actually advises against it when crossing between HTTP and HTTPS.

Though, I have found other questions in which a simple Apache 301 redirect preserves the referrer and this generally seems to be the case by default. What are some other factors which may influence this behavior that I can play around with to preserve the referrer? Are the only factors based on the Apache server version and/or the client's browser settings (IE. Outside my control)?

My redirect:

ServerAlias www.example.com sub1.example.com   

## Redirect all sub-domains to www
RewriteCond %{HTTP_HOST} !^www\.example\.com$ [NC]
RewriteRule ^(.*)$ http://www.example.com$1 [R=301,L]

With respect to the above rewrite rule, I'm visiting http://sub1.example.com. I'm currently just working with HTTP for simplicity until I can figure this out.

The way I'm determining the referrer is not being carried over is by visiting the redirected site manually via a browser with developer tools open. I have also determined the referrer is not included in PHP's $_SERVER global on the receiving page. I can confirm there is only 1 redirect occurring. The server side language is PHP.

Here is the request header for the initial page (sub1.example.com):

GET / HTTP/1.1
Host: sub1.example.com
Connection: keep-alive
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36
Upgrade-Insecure-Requests: 1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.8

Here is the response header for the initial page (sub1.example.com):

HTTP/1.1 301 Moved Permanently
Date: Wed, 04 Oct 2017 18:14:34 GMT
Server: Apache
Upgrade-Insecure-Requests: 0
Location: http://www.example.com/
Cache-Control: max-age=1
Expires: Wed, 04 Oct 2017 18:14:35 GMT
Content-Length: 243
Keep-Alive: timeout=5, max=99
Connection: Keep-Alive
Content-Type: text/html; charset=UTF-8

Here is the request header for the receiving page (www.example.com):

GET / HTTP/1.1
Host: www.example.com
Connection: keep-alive
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36
Upgrade-Insecure-Requests: 1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.8
Cookie: <redacted>

Response header for the receiving page (www.example.com):

HTTP/1.1 200 OK
Date: Wed, 04 Oct 2017 18:14:34 GMT
Server: Apache
Upgrade-Insecure-Requests: 0
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate
Pragma: no-cache
Vary: Accept-Encoding
Content-Encoding: gzip
Keep-Alive: timeout=5, max=99
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: text/html; charset=UTF-8

Best Answer

A redirect, 301 or otherwise, sends a reponse back to the client (user's browser) which simply says "send your request again, but this time use foo.com." If the client chooses to send again, then it does, and how it formulates the request is entirely up to the client. Because there is no action on the server side, you cannot influence inclusion of the referer.