In https://github.com/omega8cc/nginx-for-drupal/blob/master/aegir/conf/over... there is code that handles https to http redirection. However, it doesn't work well in conjunction with boost, because as soon as a page is cached, it can then be accessed over http and https, and the redirection from one to the other no longer happens as the page is served directly from bost's static file cache.

In order to work with Boost I think this needs to be done at the server level. Here is my now working nginx config that makes this work on pages donate* en/donate* civicrm* and en/civicrm*

In the site's vhost conf, add the following:

   # Serve these pages only over https, bypassing the static cache.
   # Later on, we will redirect all other pages back to http.
   location ~* ^/(en/)?(donate|civicrm.*)$ {
     if ( $scheme = 'http' ) {
       rewrite     ^(.*) https://$host$1 permanent;
     }
     try_files $host @drupal;
   }

In ~/config/includes/nginx_simple_include.conf and ~/config/includes/nginx_advanced_include.conf, make a slight change to the @cache directive, adding on https to http redirection:

    ###
    ### boost compatible cache check - nginx 0.7.27 or newer required with try_files support
    ###
    location @cache {
        if ( $scheme = 'https' ) {
            rewrite ^(.*) http://$host$1 permanent; # redirect to http
        }
        if ( $request_method !~ ^(?:GET|HEAD)$ ) {
             return 405;
        }
        if ( $http_cookie ~ "DRUPAL_UID" ) {
             return 405;
        }
        error_page 405 = @drupal;
        add_header Expires "Tue, 24 Jan 1984 08:00:00 GMT";
        add_header Cache-Control "must-revalidate, post-check=0, pre-check=0";
        add_header X-Header "Boost Citrus 1.9";
        charset utf-8;
        try_files /cache/normal/$host${uri}_$args.html @drupal;
    }

Not sure of this is something that could be included in some form to barracuda, but I thought I paste it here for others anyway. I wish I could find a way to do with without having to modify nginx_simple_include.conf, but I cant!

One problem with this is that it means that boost cache won't be used for https pages.

Comments

mrfelton’s picture

Infact, here is a slightly better config that also allows boost to work for https pages:

  # Serve these pages only over https, bypassing the static cache.
   # Later on, we will redirect all other pages back to http.
   location ~* ^/(en/)?(donate|civicrm.*)$ {
     if ( $scheme = 'http' ) {
       rewrite     ^(.*) https://$host$1 permanent;
     }
     try_files $uri @sslcache;
   }

Then, add a new location for @sslcache, and as before add the https->http redirect to @cache:

    ###
    ### boost compatible cache check - nginx 0.7.27 or newer required with try_files support
    ###
    location @sslcache {
        if ( $request_method !~ ^(?:GET|HEAD)$ ) {
             return 405;
        }
        if ( $http_cookie ~ "DRUPAL_UID" ) {
             return 405;
        }
        error_page 405 = @drupal;
        add_header Expires "Tue, 24 Jan 1984 08:00:00 GMT";
        add_header Cache-Control "must-revalidate, post-check=0, pre-check=0";
        add_header X-Header "Boost Citrus 1.9";
        charset utf-8;
        try_files /cache/normal/$host${uri}_$args.html @drupal;
    }

    ###
    ### boost compatible cache check - nginx 0.7.27 or newer required with try_files support
    ###
    location @cache {
        if ( $scheme = 'https' ) {
            rewrite ^(.*) http://$host$1 permanent; # redirect to http
        }
        if ( $request_method !~ ^(?:GET|HEAD)$ ) {
             return 405;
        }
        if ( $http_cookie ~ "DRUPAL_UID" ) {
             return 405;
        }
        error_page 405 = @drupal;
        add_header Expires "Tue, 24 Jan 1984 08:00:00 GMT";
        add_header Cache-Control "must-revalidate, post-check=0, pre-check=0";
        add_header X-Header "Boost Citrus 1.9";
        charset utf-8;
        try_files /cache/normal/$host${uri}_$args.html @drupal;
    }

It seems strange to me that this actually works, but, it does!

omega8cc’s picture

You can't rely on $scheme when you are using our currently recommended setup with local SSL proxy instead of Aegir HTTPS feature, because $scheme is here *always* http.

But it should be possible with this trick: http://drupalcode.org/project/octopus.git/commit/831e575

Note that it will skip Boost cache on every HTTPS request (as expected anyway) so you can still use redirect logic in your override.global.inc file. Note that we currently check also for OctopusNoCacheID cookie and skip Boost completely when it is present, and it is set automatically when there is ubercart/commerce profile used, or connection is over HTTPS, or certain URIs are accessed etc.

And since any URL set in override.global.inc as redirecting to HTTPS will be never cached by Boost, so the redirection should just work, always.

Here is the current location for Boost:

###
### Boost compatible cache check.
###
location @cache {
  if ( $request_method !~ ^(?:GET|HEAD)$ ) {
    set $nocache_details "Method";
    return 405;
  }
  if ( $sent_http_x_forwarded_proto = "https" ) {
    set $nocache_details "Proto";
    return 405;  
  }
  if ( $http_cookie ~ (?:DRUPAL_UID|OctopusNoCacheID) ) {
    set $nocache_details "Cookie";
    return 405;
  }
  if ( $args ~* "nocache=1" ) {
    set $nocache_details "Args";
    return 405;
  }
  error_page 405 = @drupal;
  add_header Expires "Tue, 24 Jan 1984 08:00:00 GMT";
  add_header Cache-Control "must-revalidate, post-check=0, pre-check=0";
  add_header X-Header "Boost Citrus 1.9";
  charset    utf-8;
  try_files  /cache/$device/$host${uri}_$args.html @drupal;
}
mrfelton’s picture

Your setup looks cleaner in some ways, but disables boost caching for ssl pages, which is very much undesired. The pages need to be encrypted, but not encrypted and slow!

omega8cc’s picture

This only makes our configuration really matching 1:1 with Boost's Apache default configuration, where HTTPS is by default never cached: #516670: Boost should consider skipping SSL requests.

But maybe we could do that better, and still allow to cache HTTPS with workarounds for redirects. But then I don't think we can hardcode anything for redirects on the Nginx level, it should be optional.

mrfelton’s picture

I don't think its a good default setting. Boost has an option in its configuration page to disable the cache for ssl pages, as well as providing a way to exclude specific paths. If people want to exclude boost on specific paths or ssl pages they should be able to use boost's own configuration for this.

I was trying to find a way to do it in a generic way, but was unsuccessful. My thinking was doing something like this:

location @cache {
        if ($do_http_redirect = '1') {
            rewrite ^(.*) http://$host$1 permanent; # redirect to http
        }
        if ($do_https_redirect = '1') {
             rewrite ^(.*) https://$host$1 permanent; # redirect to http
        }
        if ( $request_method !~ ^(?:GET|HEAD)$ ) {
             return 405;
        }
        if ( $http_cookie ~ "DRUPAL_UID" ) {
             return 405;
        }
        error_page 405 = @drupal;
        add_header Expires "Tue, 24 Jan 1984 08:00:00 GMT";
        add_header Cache-Control "must-revalidate, post-check=0, pre-check=0";
        add_header X-Header "Boost Citrus 1.9";
        charset utf-8;
        try_files /cache/normal/$host${uri}_$args.html @drupal;
    }

The thinking was that this would allow people to set $do_http_redirect or $do_https_redirect elsewhere in their vhost config based on path matching or some other paramters, and depending on the value of this the redirect would be performed. Something like:

  # Serve these pages only over https, bypassing the static cache.
   # Later on, we will redirect all other pages back to http.
   location ~* ^/(en/)?(donate|civicrm.*)$ {
     if ( $scheme = 'http' ) {
       set $do_https_redirect '1';
     }
     try_files $uri @cache;
   }
   set $do_http_redirect '1';

I couldn't get it working like this though. The variables didn't seem to be carrying over to the @cache section properly. You would also need to set those vars to default to 0, probably using map in nginx.conf.

omega8cc’s picture

Your configuration would look like below, but note that it will cause redirect loop for hostmaster site and all not specified URIs for all sites will be redirected HTTPS->HTTP, so you probably don't want to use this:

# Serve these pages only over https, bypassing the static cache.
# Later on, we will redirect all other pages back to http.
location ~* ^/(en/)?(donate|civicrm.*)$ {
  if ( $http_x_forwarded_proto = 'http' ) {
    rewrite ^ https://$host$request_uri? permanent;
  }
  try_files $uri @sslcache;
}
###
### Boost compatible sslcache check.
###
location @sslcache {
  if ( $request_method !~ ^(?:GET|HEAD)$ ) {
    set $nocache_details "Method";
    return 405;
  }
  if ( $http_cookie = "DRUPAL_UID" ) {
    set $nocache_details "Cookie";
    return 405;
  }
  if ( $args ~* "nocache=1" ) {
    set $nocache_details "Args";
    return 405;
  }
  error_page 405 = @drupal;
  add_header Expires "Tue, 24 Jan 1984 08:00:00 GMT";
  add_header Cache-Control "must-revalidate, post-check=0, pre-check=0";
  add_header X-Header "Boost Citrus 1.9 HTTPS";
  charset    utf-8;
  try_files  /cache/$device/$host${uri}_$args.html @drupal;
}
###
### Boost compatible cache check.
###
location @cache {
  if ( $http_x_forwarded_proto = 'https' ) {
    rewrite ^ http://$host$request_uri? permanent;
  }
  if ( $request_method !~ ^(?:GET|HEAD)$ ) {
    set $nocache_details "Method";
    return 405;
  }
  if ( $http_cookie = "DRUPAL_UID" ) {
    set $nocache_details "Cookie";
    return 405;
  }
  if ( $args ~* "nocache=1" ) {
    set $nocache_details "Args";
    return 405;
  }
  error_page 405 = @drupal;
  add_header Expires "Tue, 24 Jan 1984 08:00:00 GMT";
  add_header Cache-Control "must-revalidate, post-check=0, pre-check=0";
  add_header X-Header "Boost Citrus 1.9 HTTP";
  charset    utf-8;
  try_files  /cache/$device/$host${uri}_$args.html @drupal;
}
mrfelton’s picture

My setup in #1 actually works flawlessly (well, it's been in production for a couple of days and there have been no issues so far). The only difference I can see between that and yours in #6 is that you are using $http_x_forwarded_proto to check for https. My setup isn't using a ssl proxy. Is the ssl proxy setup something new in Barracuda-dev, or is this something specific to Octopus, which I'm not using either.

omega8cc’s picture

You need to replace:

if ( $scheme = 'http' ) {

with:

if ( $http_x_forwarded_proto = 'http' ) {

Also, you don't any maps to set default value of any variable, just do:

set $do_https_redirect '0';
if ( $http_x_forwarded_proto = 'http' ) {
  set $do_https_redirect '1';
}
omega8cc’s picture

Global HTTPS proxy was 'always' used in BOA, and enabled by default on install. It works by default both for Barracuda master instance and all Octopus instances and can be extended with: http://drupalcode.org/project/barracuda.git/blob/HEAD:/docs/SSL.txt

Of course if you are not using it and instead you are using Aegir built-in HTTPS feature, you should use $scheme and not $http_x_forwarded_proto.

mrfelton’s picture

Interesting (about the ssl proxy). Never knew that. I wonder if a more prominent section in the documentation would help make people aware of this feature. Would you consider the addition of an @sslcache block in the default nginx includes, to make it possible for people to use boost caching with https?

omega8cc’s picture

We already removed any no-cache settings for HTTPS, so you can use Boost to cache also HTTPS requests, so you don't need any extra location: http://drupalcode.org/project/barracuda.git/blob/HEAD:/aegir/conf/nginx_...

omega8cc’s picture

Note also that OctopusNoCacheID cookie is now used only when it is required to skip caching, but it is no longer related to HTTPS requests, as it was before: http://drupalcode.org/project/barracuda.git/blob/HEAD:/aegir/conf/global...

omega8cc’s picture

Status: Active » Fixed

Links to SSL related docs (plus some other) added on the project page.

Thanks!

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.