You are here

function cloudflare_boot in CloudFlare 7.2

Implementation of hook_boot().

Replace $_SERVER['REMOTE_ADDR'] with $_SERVER['HTTP_CF_CONNECTING_IP'] header Properly flag $_SERVER['HTTPS'] and set the base-url correctly if cloudflare is using flexible SSL

1 call to cloudflare_boot()
cloudflare.https.inc in ./cloudflare.https.inc

File

./cloudflare.module, line 12

Code

function cloudflare_boot() {

  // This function might be invoked twice if flexible SSL support is enabled
  // So make sure it is only ever run once.
  static $run_once = TRUE;
  if ($run_once) {
    $run_once = FALSE;
  }
  else {
    return;
  }

  // Only run if this is a CloudFlare request
  if (empty($_SERVER['HTTP_CF_RAY'])) {
    return;
  }
  global $base_url;
  global $conf;

  // Assign a proper IP address for end-client connecting via cloudflare using CF-Connecting-IP header
  if (variable_get('cloudflare_cf_connecting_ip', FALSE) && !empty($_SERVER['HTTP_CF_CONNECTING_IP'])) {
    if (variable_get('cloudflare_cf_connecting_ip') == 'trust') {
      $connecting_ip = $_SERVER['REMOTE_ADDR'];
      $_SERVER['ORIG_REMOTE_ADDR'] = $connecting_ip;
      $_SERVER['REMOTE_ADDR'] = $_SERVER['HTTP_CF_CONNECTING_IP'];
      $trusted = TRUE;
      $conf['reverse_proxy'] = FALSE;

      // Disable any furthur reverse proxy handling.
    }
    else {
      $trusted = FALSE;

      // If an array of known reverse proxy IPs is provided, then trust
      // the CF header if request really comes from one of them or from a cloudflare IP.
      $reverse_proxy_addresses = variable_get('reverse_proxy_addresses', array());
      $connecting_ip = $_SERVER['REMOTE_ADDR'];
      if (in_array($connecting_ip, $reverse_proxy_addresses) || cloudflare_ip_address_in_range($connecting_ip)) {
        $_SERVER['ORIG_REMOTE_ADDR'] = $connecting_ip;
        $_SERVER['REMOTE_ADDR'] = $_SERVER['HTTP_CF_CONNECTING_IP'];
        $trusted = TRUE;
        $conf['reverse_proxy'] = FALSE;

        // Disable any furthur reverse proxy handling.
      }
    }
  }
  else {
    $conf['reverse_proxy'] = TRUE;

    // Remove CloudFlare IP addresses from X-Forwarded-For header.
    // This ensures that the end-user IP address is never identified as a CloudFlare IP.
    $reverse_proxy_header = variable_get('reverse_proxy_header', 'HTTP_X_FORWARDED_FOR');
    if (!empty($_SERVER[$reverse_proxy_header])) {
      $forwarded = explode(',', $_SERVER[$reverse_proxy_header]);
      $forwarded = array_map('trim', $forwarded);
      $good_ips = array();
      foreach ($forwarded as $ip) {
        if (!cloudflare_ip_address_in_range($ip)) {
          $good_ips[] = $ip;
        }
      }
      $_SERVER[$reverse_proxy_header] = implode(',', $good_ips);
    }
  }
  drupal_static_reset('ip_address');

  // Properly flag the request as a HTTPS request if CloudFlare's flexible SSL is being used
  if (!empty($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https' && empty($_SERVER['HTTPS'])) {
    if ($trusted || in_array($connecting_ip, $reverse_proxy_addresses) || cloudflare_ip_address_in_range($connecting_ip, cloudflare_ip_ranges())) {
      global $cloudflare_ssl_handling;
      if ($cloudflare_ssl_handling) {
        $_SERVER['HTTPS'] = 'on';
        $conf['https'] = TRUE;
        if (substr($GLOBALS['base_url'], 0, 7) === "http://") {
          $GLOBALS['base_url'] = 'https://' . substr($GLOBALS['base_url'], 7);
          $GLOBALS['base_secure_url'] = $GLOBALS['base_url'];
          $GLOBALS['is_https'] = TRUE;
        }
      }
      else {
        $parts = pathinfo(drupal_get_filename('module', 'cloudflare'));
        $include = 'require_once("' . $parts['dirname'] . '/cloudflare.https.inc");';
        drupal_set_message("CloudFlare SSL Error: CloudFlare HTTPS handling is not properly enabled. Add the following to your settings.php:<br/> <code style='font-family: monospace;'>{$include}</code>", 'error');
      }
    }
  }

  // Check for AlwaysOnline spider and set appropriate cache-control headers
  if (!empty($_SERVER['HTTP_USER_AGENT']) && $_SERVER['HTTP_USER_AGENT'] == CLOUDFLARE_ALWAYSONLINE_USER_AGENT) {
    drupal_add_http_header('Cache-Control', 'public, max-age=86400');
    drupal_add_http_header('Vary', 'User-Agent');
  }
}