I found that when the first user who visits a page is using HTTPS some links are then stored in HTTPS in the cached HTML page. For example, all the links to CSS files and pictures were using HTTPS in my case.

This behaviour may not lead to problems for people using a certificate validated by a SSL Certificate Authority but for people using an auto-signed certificate, web browsers over react. On my website, Chrome, Firefox and IE refuse to load CSS files and pictures until I accept the certificate, which alters the rendered pages...

I also have to add that accepting auto-signed certificates by my logged users is not a problem, because they know that I use this type of certificate, but anonymous users should never have to accept a SSL certificate since they use a HTTP URL.

Consequently, I decided to avoid caching of any page accessed by HTTPS by modifying the file boost.module :

function boost_init() {
  global $is_https, $_boost;        <-----  use of $is_https

  $_boost = array();

  // Make sure the page is/should be cached according to our current configuration.
  // Start with the quick checks
  if (   strpos($_SERVER['SCRIPT_FILENAME'], 'index.php') === FALSE
      || $_SERVER['SERVER_SOFTWARE'] === 'PHP CLI'
      || ($_SERVER['REQUEST_METHOD'] != 'GET' && $_SERVER['REQUEST_METHOD'] != 'HEAD')
      || isset($_GET['nocache'])
      || variable_get('maintenance_mode', 0)
      || defined('MAINTENANCE_MODE')
      || !empty($_SESSION['messages']) // do not cache pages with messages
      || $is_https // do not cache pages in https           <----- added to manage HTTPS
  ) {
    $_boost['cache_this'] = FALSE;
  }
  ...
}

Is my method correct? Should this be added to Boost?

Comments

ClaudeS-1’s picture

Priority: Normal » Critical

I've noticed the same thing, except Boost will even OVERWRITE a cached HTTP-generated file with an HTTPS-generated version, and will always serve this when you visit HTTP. So even if you visit HTTP first to create a valid cache file, it only takes one visitor to hit HTTPS to spoil the cache for all subsequent visitors.
I've only tested this by visiting the home page.

This breaks our site completely (no CSS/JS/images load because we don't have an SSL certificate)

- there is little on the web/here about Boost and HTTPS - what I've found is that there is an .htaccess rule which *should* make Boost skip creating a cached file if the request is over HTTPS

- The fix proposed here worked for me.

Needs looking into by Boost developers...

hyperglide’s picture

We are experiencing a similar issue. We do not make use of SSL pages however some of our images being served by the Media Module are not being shown as they are addressed by HTTPS.

Any known solutions?

#1066220: Image paths are being prefixed with HTTPS D6 Version Issue.

yan’s picture

I experienced the same problems as mentioned here and in
#1066220: Image paths are being prefixed with HTTPS

I'm using Drupal 6. The problem seems to be that I am using a self-signed certificate. That leads (some) browsers to not display images whose path starts with https. With this workaround I managed to prevent pages visited through https from beeing cached. But the problem is now, that users that visit my site through an encrypted connection get served uncached pages - that's very slow.

Thinking about this, wouldn't be a solution to create different static caches for both http and https? I noticed that this works fine for different themes depending on the subdomain (in my case a mobile site accessible through m.example.com). So I imagine that it would be possible to also have a separate cache for https visits. Am I wrong?

Apart from that: The module really cut loading times for anonymous visitors amazingly! Thanks a lot.

yan’s picture

Now the problem appeared although the option "Bypass the boost cache for ssl requests" is active and I excluded pages from caches when they're accessed through https:

$is_https_page = ((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') || (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https'));

if ($is_https_page) {
  return FALSE;
}
else {
  return TRUE;
}

What else could it be?

giorgio79’s picture

@yan are you using ellolo's code snippet as well?

Anonymous’s picture

The Rewrite rule

RewriteCond %{HTTPS} on [OR]

should turn off boost for all https pages and only present non-http content already. The modifications seem solid though, "if" a page was first visited through https then a cached version may be created but then served through http, that shouldn't happen and there should be some safeguards but I'll have to go back through the code as I'm sure that it's already been covered unless something has regressed.

Anonymous’s picture

Assigned: Unassigned »
giorgio79’s picture

Thanks Philip. I have the latest Boost dev, and I am getting this. Here is an example site of mine http://reviewcritical.com/

For some reason, some bots try https pages, and I have a self signed cert. Just like the op, http pages are cached with https links.

yan’s picture

@giorgio79 I'm not using that snippet.

anthony.bouch’s picture

I'm having a similar problem at the moment.

We're using an https connection for administrator/editor logins only. When all caches are cleared via the admin menu, but the first request is via https, then regular http visitors are missing 'some' images which have been included in the cached page with the https scheme (and yes, we're using a self-signed certificated since this is for admin access only - although this is the reason the 'regular' http visits with https requested images are being blocked by some browsers).

If I clear all caches using drush cc all, and then make sure that the first visitor is a regular http connection - then all is well.

Please can you tell me where exactly you placed the php snipped in #4 above?

I also have:

if (isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) == 'on') {
$base_url = 'https://febits.akhua.net';
}
else {
$base_url = 'http://febits.akhua.net';
}

In my settings.php file.

And I have nginx configured to NOT request cached pages when the site is accessed via https - but still, I'm seeing https requested images in the cached Boost page for regular visitors (and again - this only happens when the cache is cleared via the admin logged in as https).

NOTE: I should add that the images affected appear to be only those that are served from rendered media tags embedded in the body of a post.

Thoughts?

Anonymous’s picture

Priority: Critical » Normal

NOTE: I should add that the images affected appear to be only those that are served from rendered media tags embedded in the body of a post.

You should therefore be looking in Drupal core for however the images are embedded, whether it be just vanilla Drupal or the Wysiwyg sections that upload images and reposition them in the comment blocks before saving the html to the database.

anthony.bouch’s picture

Hi Philip_Clarke

Thanks for the reply. I think you're right. This doesn't look like a Boost problem. Rather a Media module problem. I'm using the 2.x version of the Media module, and embedded media tags in the body of posts (not comments block). I'll also post to the Media module's issues page, and well as try to work out where the html is being cached. I've turned off Drupal page and block caching, as well as Boost (and made sure that there is no Views module caching) and I'm still seeing the problem.

UPDATE: The problem I'm experienced is documented by the Media module developers. Here's an update...

https://drupal.org/node/2037051

ahoeben’s picture

What if we make it an option Boost feature so that all boost-cached files are postprocessed to replace the https base_url with a http base_url?

Anonymous’s picture

Status: Active » Closed (works as designed)

Well it would work, but the whole issue is not really boost related. Some modules throw out https media embedded in non http served html, and it's not boost's job to fix them. You'd also have the scenario where if the page was intentionally https you'd get a pop up warning of non https embedded content.

The ability to serve only certain pages from the cache could mean that a careful owner could disable the https rules which is part of boost's flexibility but is not going to make it into core, and overall should be a project management style decision like forwarding all http requests to an https only site.

ahoeben’s picture

Point taken.

Just in case someone stumbles upon this issue through google, and wants to use my approach to fix this issue with boost as a last line of defense, here's what I did:

In boost_exit, after this:

  // Get the data to cache.
  $data = ob_get_contents();

I inserted this:

  // convert all https:// links to http:// links
  global $base_url;
  if(strpos($base_url, 'http:')==0) {
    $str_from = 'https://'.substr($base_url, 7);
    $str_to = $base_url;
  } else {
    $str_from = $base_url;
    $str_to = 'http://'.substr($base_url, 8);
  }
  $data = str_replace($str_from, $str_to, $data);

(no patch because I don't expect this to get in)

jamescook’s picture

Status: Closed (works as designed) » Active

Thanks for that last tip, I reduced it to:

$data = str_replace("https:", "http:", $data);

(did I miss something - well I suppose there's a chance of pointing to an external https server).

I spent 6 hours or more going through the RewriteRules etc. etc. and couldn't fix this problem any other way.
I can't see how this is not a boost problem(?).

I'm not quite sure WHEN the boost code to cache a file is triggered. When I use https (with AND without the above str_replace code) the existing _.html file is always overwritten.

So even if the first visit is http:, a subsequent visit via https: will always regenerate the _.html file. If you do another https: visit, the _.html is regenerated again etc. Usually the cached files are not overwritten immediately, they remain in cache ...

There seems to be something wrong with the trigger the generates new/overwrites cache files in the case of https: visits. (should IMHO generate nothing).
The rewrite rules AFAICT do not trigger the rewrite, they just serve whatever the cache has. In the case of https: they DO seem to skip serving cached files.

The problem is the cached file becomes "corrupted" - contains the https: version for subsquent http: visits

Anonymous’s picture

Status: Active » Closed (cannot reproduce)

I'm not quite sure WHEN the boost code to cache a file is triggered.

At the very last moment before the page is sent to the browser, when ob_flush is used. Up until that point everything is done in memory and boost takes a duplicate of whatever was created by the other modules.

There seems to be something wrong with the trigger the generates new/overwrites cache files in the case of https: visits. (should IMHO generate nothing).

Which should be the case, a fresh copy should be served from the drupal installation and boost should be off.

In the rewrite rules there is a flag at the end of a line [S=n] where n = the number of rules that are skipped, so if a https page is visited then the rules don't bother looking for the cache. If there is and error somewhere then it is in the boost.module where for some reason the flag for https is not being set and then there would be a write to the disk. The way to debug this therefore would be to look in boost.module for the flag and then do a basic phpinfo when visiting via https (even with a self signed certificate) and then check that the flag boost is looking for exists. Possibly your server is not setting it, is it lighttpd/ nginix /apache 2.2 or 2.4.

jamescook’s picture

Version: 7.x-1.x-dev » 7.x-1.0-beta2

Thanks for your quick and thorough reply.

I debugged as you suggested. I'm on Apache/2.2.22 (Ubuntu).
Boost version actually 7.x.1.0-beta2.

I got rid of the blanket https to http conversions I inserted before in boost.module (it was causing insecure content messages when I DID want https: pages for contact forms etc.).

Finally(!) I inserted the code from the Issue OP:

|| $is_https // do not cache pages in https

etc.
(Maybe this code is in the .dev branch.)

Everything appears to be working fine, no files created on https access. Https requests chanelled to Drupal proper and not cached versions.

Now I have a self signed cert website, with https redirection for forms (Secure Login module).

Great!

jamix’s picture

Boost definitely should create separate cache files for pages accessed via HTTPS and HTTP. A page accessed via HTTPS has HTTPS links in it which may not be desired when this same page is accessed via HTTP.

That said, here's hopefully a cleaner solution to the problem that doesn't require hacking Boost:

function mymodule_init() {
  global $is_https;

  // Prevent caching of HTTPS pages.
  if ($is_https) {
    drupal_page_is_cacheable(FALSE);
  }
}
rdaniel2p’s picture

@jamix : where did you put this code ? in a new custom module ?

function mymodule_init() {
  global $is_https;
  // Prevent caching of HTTPS pages.
  if ($is_https) {
    drupal_page_is_cacheable(FALSE);
  }
}
Anonymous’s picture

It is strongly recommended not to use boost on a https site as any forms could private information, shop stock could change, and .htaccess also disables boost for https sites so there are multiple places to change.

erikwegner’s picture

In my case, the page is mainly accessed via http. But the boost cache is configured to be pre-build through cron runs. And the cron is run through cron.php, which is called with https to protect the cron-cookie.

So, there is no shop, no personal data, no live saving security needs involved here. Just a simple, secure call to cron. I am unsure, if the simple equation https == not(cacheable) fits my scenario.

Anonymous’s picture

boost is never built during cron runs, it is only cleaned out. The spider is a misnaming, instead it creates pages that are updated, edited, deleted during cron runs (a common misconception due to the name). Normally one would use an external program like wget (search this forum) to generate a cache. Then you would disable the .htaccess file section for https. You would not need to alter the boost module itself if you changed the .htaccess file and had wget creating the http content as long as it were identical to the https.

.htaccess is read before the PHP so if a cached file existed then it would be served without hitting the php.

But I will point out that in no way do "we" endorse this use of boost for https sites and that if you are unsure if it boost is suitable, from a security point of view it probably is not.