WordPress ERR_TOO_MANY_REDIRECTS – Fix Through Varnish but Not Apache

apache-2.4varnishWordpress

I'm having this weird problem with a varnish-wordpress setup. I get TOO_MANY_REDIRECTS when I try to divert traffic through varnish, but if I configure apache directly with a vhost listening on 443, it works just fine.
Relevant parts of default.vcl in varnish:

    if (std.port(local.ip) == 80 && req.http.host ~ "example.com(:[0-9]+)?$") {
    set req.http.x-redir = "https://" + req.http.host + req.url;
    return(synth(850, "Moved permanently"));

    [...]


   else if (req.http.host ~ "(www\.)?example.com(:[0-9]+)?$") {
    set req.backend_hint = web227;
        return (pipe);
        }
sub vcl_synth {
    if (resp.status == 850) {
        set resp.http.Location = req.http.x-redir;
        set resp.status = 301;
        return (deliver);
    }

I'm using pipe temporarily, in order to make sure I don't bump into more caching at this stage where I'm still testing.

On this varnish there are several wordpress backends that work without any issues, on which the same .htaccess resides, which the "classic" wordpress .htaccess:

    <IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

And here is my apache site configuration:

<VirtualHost *:80>
        ServerAdmin user@example.com
        ServerName  digital.ringier.ro
        ErrorLog "/var/log/apache2/example.com.error.log"
        CustomLog "/var/log/apache2/example.com.access.log" common
        #Redirect / https://example.com/
        DocumentRoot "/var/www/example.com"
        <Directory "/var/www/example.com">
        AllowOverride all
        Options -Indexes +FollowSymLinks +MultiViews
        </Directory>
</VirtualHost>

<VirtualHost *:443>
        ServerAdmin user@example.com
        ServerName  example.com
        DocumentRoot "/var/www/example.com"
        <Directory "/var/www/example.com">
        AllowOverride all
        Options -Indexes +FollowSymLinks +MultiViews
        </Directory>
        ErrorLog "/var/log/apache2/example.com.error.log"
        CustomLog "/var/log/apache2/example.com.access.log" common
        SSLEngine on
        SSLCertificateFile /etc/apache2/ssl/apache.crt
        SSLCertificateKeyFile /etc/apache2/ssl/apache.key
</VirtualHost>

I can't, for the life of me, understand why it works when I access apache directly (I'm changing the ip in hosts in order to do that), but not through varnish.
This is the response I get in the browser (which is repeated dozens of times):

HTTP/1.1 301 Moved Permanently
Date: Tue, 02 Oct 2018 17:36:28 GMT
Server: Apache/2.4.18 (Ubuntu)
Location: https://example.com/
Content-Length: 0
Connection: close
Content-Type: text/html; charset=UTF-8

This is clearly a response coming from apache, not from varnish, as far as I can tell (because of the 'server' header and because 'via' header is missing)
Any ideas how I can fix this?

Best Answer

Basically the problem was related to wp-config. I inserted this code:

if ($_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') {
   $_SERVER['HTTPS'] = 'on';
}

if ( !isset( $_SERVER['HTTPS'] ) ) {
    $_SERVER['HTTPS'] = 'on';
}

And it worked. Initially I simply tried $_SERVER['HTTPS'] = 'on';, but I received a 50x error. Not sure exactly why. On other wp installation, the simple directly did work. I'll have to do some more tests in the future.

Related Topic