diff --git a/includes/bootstrap.inc b/includes/bootstrap.inc
index d27f8d1..b2e0418 100644
--- a/includes/bootstrap.inc
+++ b/includes/bootstrap.inc
@@ -2345,8 +2345,8 @@ function _drupal_bootstrap_page_cache() {
     $cache = drupal_page_get_cache();
     // If there is a cached page, display it.
     if (is_object($cache)) {
-      header('X-Drupal-Cache: HIT');
       // Restore the metadata cached with the page.
+      $original_q = $_GET['q'];
       $_GET['q'] = $cache->data['path'];
       drupal_set_title($cache->data['title'], PASS_THROUGH);
       date_default_timezone_set(drupal_get_user_timezone());
@@ -2355,6 +2355,14 @@ function _drupal_bootstrap_page_cache() {
       if (variable_get('page_cache_invoke_hooks', TRUE)) {
         bootstrap_invoke_all('boot');
       }
+      if (variable_get('skip_cache', FALSE)) {
+        // restore original value of $_GET['q'] as is expected by
+        // language_initialize() and perhaps other bootsrap phases.
+        $_GET['q'] = $original_q;
+        header('X-Drupal-Cache: SKIP');
+        return;
+      }
+      header('X-Drupal-Cache: HIT');
       drupal_serve_page_from_cache($cache);
       // If the skipping of the bootstrap hooks is not enforced, call
       // hook_exit.
@@ -2443,7 +2451,9 @@ function _drupal_bootstrap_variables() {
  * Invokes hook_boot(), initializes locking system, and sends HTTP headers.
  */
 function _drupal_bootstrap_page_header() {
-  bootstrap_invoke_all('boot');
+  if (!variable_get('cache') || !variable_get('skip_cache', FALSE)) {
+    bootstrap_invoke_all('boot');
+  }
 
   if (!drupal_is_cli()) {
     ob_start();
