How do I configure Apache and Varnish with both HTTP and HTTPS access and prevent mixed content error? I have Drupal 7 installed on Ubuntu server with apache2 and varnish. I was asked to provide both http and https access to the site.

To utilize Varnish I setup apache reverse proxy to redirect all https traffic to varnish(http). Now I can access my site via http/https protocols fine.

However, when I load any https page with images in it, all images are served via http, thus making browsers issue a warning about mixed content. I would like to suppress that.

To suppress that, I changed $base_url to https:// in site/default/settings.conf and that worked fine for all https pages.

However, I experienced the same mixed content error while loading normal http pages (images were served via https this time.) Then, I created an if statement trying to differentiate between http and https and assigning different $base_url values accordingly.

I have tried using $_SERVER['']  array variables as well as $is_https, and nothing seems to be working.

I also used $GLOBALS[''] variable to make sure variables are defined. I would clear the Drupal cache as well as browsers before each testing. However, when I access https version of a site, all is rendered ok and everuthing is fine. But when I access http, all images are served with https. I would clear cache again, and try accessing http first, and everything would be fine. But when I access https after that, images would be served with http. So, the logic within settings.conf is fine, but possibly caching makes browsers/Drupal to serve images with the protocol they were first accessed (be it http OR https).

My question: is there a way to assign $base_url dynamically based on the protocol used?

Some of the settings I have tried:

-----------------------------------
if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) &amp;&amp; $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') {
        $_SERVER['HTTPS']='on';
        $base_url = 'https://';
        }
else {
         $_SERVER['HTTPS']='';
         $base_url = 'http://';
} 
-------------------------------------
#if (isset($GLOBALS['$is_https'])) {
#       $_SERVER['HTTPS']='on';
#       $base_url = 'https://example';
#       }
#else {
#        $_SERVER['HTTPS']='';
#        $base_url = 'http://example';
#}
---------------------------------------
$base_url = '//example'
---------------------------------------
$base_url = '';
---------------------------------------
Drupal 8

Apply the following settings in site's settings.php file:

$settings['reverse_proxy'] = TRUE;
$settings['reverse_proxy_addresses'] = [@$_SERVER['REMOTE_ADDR']]


It should work for CDN where IP addresses are dynamic.

This is explained in the following comment:

 * In order for this setting to be used you must specify every possible
 * reverse proxy IP address in $settings['reverse_proxy_addresses'].
 * If a complete list of reverse proxies is not available in your
 * environment (for example, if you use a CDN) you may set the
 * $_SERVER['REMOTE_ADDR'] variable directly in settings.php.
 * Be aware, however, that it is likely that this would allow IP
 * address spoofing unless more advanced precautions are taken


Drupal 7

$conf['reverse_proxy'] = TRUE;
$conf['reverse_proxy_addresses'] = [@$_SERVER['REMOTE_ADDR']];




See also:


Setting reverse_proxy and reverse_proxy_addresses behind AWS ELBs.
Using a load balancer or reverse proxy