WordPress SSL Offloading

Understanding what’s happening

When your page is accessed over HTTPS, but the Load Balancer is performing SSL offloading and actually requesting your content on the non-SSL port 80, the webserver, PHP, or anything else for that matter, does not understand or see that it’s being accessed over https://.

The fix for this, is that Load Balancer sends the de-facto standard X-Forwareded-Proto HTTP header, which we can use to figure out which protocol the client is actually using on the other side of the Load Balancer.

With Apache 2.2, you could use something along the lines of:

<IfModule mod_setenvif.c>

SetEnvIf X-Forwarded-Proto “^https$” HTTPS


This simply reads the X-Forwared-Proto header, and if it equals https then, sets the HTTPS environment variable to 1. PHP will see this environment variable, and eventually it will become $_SERVER[‘HTTPS’] that equals 1 — just like it would be for a “real” native SSL request.

The solution

Websites behind load balancers or reverse proxies that support HTTP_X_FORWARDED_PROTO can be fixed by adding the following code to the wp-config.php file

if ($_SERVER[‘HTTP_X_FORWARDED_PROTO’] == ‘https’)


Then to redirect any http requests to https, we need to define the following In the .htaccess file:

<IfModule mod_rewrite.c>

RewriteEngine On

RewriteCond %{HTTP:X-Forwarded-Proto} !https

RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

RewriteBase /

RewriteRule ^index\.php$ – [L]

RewriteCond %{REQUEST_FILENAME} !-f

RewriteCond %{REQUEST_FILENAME} !-d

RewriteRule . /index.php [L]



The important parts here are in bold. Under usual circumstances inside the .htaccess file the rewrite condition would be to check for https to be set to OFF:

RewriteCond %{HTTPS} off

When behind some forms of proxying, whereby the client is connecting via HTTPS to a proxy, load balancer, Passenger application, etc., the %{HTTPS} variable may never be on and cause a rewrite loop. This is because your application is actually receiving plain HTTP traffic even though the client and the proxy/load balancer are using HTTPS. In these cases, check the X-Forwarded-Proto header.




Vertically aligning elements

For a long time I’ve always been using the following method of vertically aligning elements on a web page:

display: table;
width: 100%;
display: table-cell;
text-align: center;
vertical-align: middle;

This method works good across all browsers and includes solid IE support down to IE7. The downfall of this particular method is that it requires two html elements in order for it to work (a parent and a child).

Using CSS3 transforms property, we can now vertically align elements with just 3 lines of css:

.element {
  position: relative;
  top: 50%;
  transform: translateY(-50%);

Transforming the element on the Y axis with a negative 50% of the height the element is currently contained in will pull it up half way (more than likely outside the parents width and height).


Now if we add a top: 50% it will pull the element back down directly in the center of whatever parent container the element is sitting inside of.