Mixed content and ERR_TOO_MANY_REDIRECTS in WordPress
When your run your WordPress site behind a Varnish cache and terminate the SSL connection, you might end up with mixed content, or an ERR_TOO_MANY_REDIRECTS
error in your browser.
Varnish and SSL
In a lot of cases these problems occur when you terminate your SSL connection on another machine. The main reason why you would do that, is because of Varnish.
Varnish is a reverse caching proxy server that speeds up the performance of your website. It is commonly used in conjunction with WordPress.
Unfortunately, Varnish does not support SSL. So we need to terminate the SSL connection elsewhere and speak plain HTTP with Varnish and your WordPress site.
Not only does Varnish not support SSL, it is also unaware of the SSL termination and just uses the hostname and the URL of the request as an identifier.
Mixed content
Because of the lack of protocol identification in a cached object, there is a high risk of “mixed content”.
Mixed content means that your browser does not load resources (Javascript, CSS, images, web fonts, …) because the request protocol does not match the one that was used to load the page itself.
If you request a page over HTTPS, but some of the resources are loaded over HTTP, your browser will complain.
Mixed Content: The page at ‘https://wp.feryn.eu/’ was loaded over HTTPS, but requested an insecure script ‘http://wp.feryn.eu/wp-includes/js/jquery/jquery.js?ver=1.12.4’. This request has been blocked; the content must be served over HTTPS.
Mixed content occurs when the WordPress site URL was set to an HTTP-based URL, or when a page was saved in the Varnish cache in plain HTTP format.
Force HTTPS redirection
To avoid mixed content, you could force HTTPS by redirecting non-HTTP pages to their HTTPS equivalent.
The following rewrite rule does this:
<IfModule mod_rewrite.c> RewriteEngine on RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301] </IfModule>
ERR_TOO_MANY_REDIRECTS
But by solving the mixed content issue, we trigger another problem: forcing HTTPS redirects on an application that is not aware what the initial request protocol, can cause ERR_TOO_MANY_REDIRECTS
errors in your browser.
This happens when the HTTP version of a page is stored in cache. The output is nothing more than a 301 redirect to the HTTPS version. But because Varnish and WordPress are unaware of SSL termination, you’ll end up in a redirection loop until the browser throws this error.
X-Forwarded-Proto
Luckily there’s a way to identify the request protocol that was used on the entry node. The X-Forwarded-Proto
request header either contains https
or http
based on the request protocol that was used before the connection was terminated.
The trick is to make WordPress aware of this, by checking the value of the X-Forwarded-Proto
header. There are plugins for that, you could also add a check in your wp-config.php
file.
The solution I’ll propose is a bit different.
The solution
The solution to mixed content, and the ERR_TOO_MANY_REDIRECTS
error I’m proposing assumes that you use an Apache webserver.
The snippet below can be added to your .htaccess
file, and contains all the logic to perform the HTTPS redirect conditionally, and make both Varnish and WordPress aware of SSL:
The first line sets the HTTPS
environment variable to “on” when the X-Forwarded-Proto
request header is set to “https”. WordPress uses the value of the HTTPS
environment variable to build its URLs either with HTTPS or HTTP.
The second line adds a Vary
response header that performs a “cache variation” on the value of the X-Forwarded-Proto
header. This is something that Varnish uses to create cache variations of a page. This means that there is an HTTP and an HTTP version in the Varnish cache for every URL.
The rest of the code will force a “301 redirect” when the HTTPS
is not set to “on”, and when X-Forwarded-Proto
is not set to “HTTPS”.
Read my book
If you want to learn more about Varnish, I suggest you read my book. It’s published by O’Reilly.
In this book I explain:
- How Varnish works,
- How you can configure the server
- How Varnish respects HTTP best practices
- What VCL is and how you can write your own VCL file
- How to increase your hit rate
- How to invalidate your cache
- What Varnish can mean for your business