diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc
index 5300d76..a063d28 100644
--- a/core/includes/bootstrap.inc
+++ b/core/includes/bootstrap.inc
@@ -279,71 +279,6 @@ function drupal_get_path($type, $name) {
 }
 
 /**
- * Sets an HTTP response header for the current page.
- *
- * Note: When sending a Content-Type header, always include a 'charset' type,
- * too. This is necessary to avoid security bugs (e.g. UTF-7 XSS).
- *
- * @param $name
- *   The HTTP header name, or the special 'Status' header name.
- * @param $value
- *   The HTTP header value; if equal to FALSE, the specified header is unset.
- *   If $name is 'Status', this is expected to be a status code followed by a
- *   reason phrase, e.g. "404 Not Found".
- * @param $append
- *   Whether to append the value to an existing header or to replace it.
- *
- * @deprecated in Drupal 8.x-dev, will be removed before Drupal 8.0.
- *   Use \Symfony\Component\HttpFoundation\Response->headers->set().
- *   See https://www.drupal.org/node/2181523.
- */
-function _drupal_add_http_header($name, $value, $append = FALSE) {
-  // The headers as name/value pairs.
-  $headers = &drupal_static('drupal_http_headers', array());
-
-  $name_lower = strtolower($name);
-  _drupal_set_preferred_header_name($name);
-
-  if ($value === FALSE) {
-    $headers[$name_lower] = FALSE;
-  }
-  elseif (isset($headers[$name_lower]) && $append) {
-    // Multiple headers with identical names may be combined using comma (RFC
-    // 2616, section 4.2).
-    $headers[$name_lower] .= ',' . $value;
-  }
-  else {
-    $headers[$name_lower] = $value;
-  }
-}
-
-/**
- * Gets the HTTP response headers for the current page.
- *
- * @param $name
- *   An HTTP header name. If omitted, all headers are returned as name/value
- *   pairs. If an array value is FALSE, the header has been unset.
- *
- * @return
- *   A string containing the header value, or FALSE if the header has been set,
- *   or NULL if the header has not been set.
- *
- * @deprecated in Drupal 8.x-dev, will be removed before Drupal 8.0.
- *   Use \Symfony\Component\HttpFoundation\Response->headers->get().
- *   See https://www.drupal.org/node/2181523.
- */
-function drupal_get_http_header($name = NULL) {
-  $headers = &drupal_static('drupal_http_headers', array());
-  if (isset($name)) {
-    $name = strtolower($name);
-    return isset($headers[$name]) ? $headers[$name] : NULL;
-  }
-  else {
-    return $headers;
-  }
-}
-
-/**
  * Sets the preferred name for the HTTP header.
  *
  * Header names are case-insensitive, but for maximum compatibility they should
diff --git a/core/includes/common.inc b/core/includes/common.inc
index 7d33f07..006c58f 100644
--- a/core/includes/common.inc
+++ b/core/includes/common.inc
@@ -643,7 +643,7 @@ function drupal_process_attached(array $elements) {
           call_user_func_array('_drupal_add_html_head_link', $args);
           break;
         case 'http_header':
-          call_user_func_array('_drupal_add_http_header', $args);
+          // @todo Remove validation in https://www.drupal.org/node/2477223
           break;
         default:
           throw new \LogicException(sprintf('You are not allowed to use %s in #attached', $callback));
diff --git a/core/lib/Drupal/Core/Render/HtmlResponseAttachmentsProcessor.php b/core/lib/Drupal/Core/Render/HtmlResponseAttachmentsProcessor.php
index 26fef4e..fbaf47b 100644
--- a/core/lib/Drupal/Core/Render/HtmlResponseAttachmentsProcessor.php
+++ b/core/lib/Drupal/Core/Render/HtmlResponseAttachmentsProcessor.php
@@ -107,8 +107,7 @@ public function processAttachments(AttachmentsInterface $response) {
 
     $variables = $this->processAssetLibraries($attached, $placeholders);
 
-    // Handle all non-asset attachments. This populates drupal_get_html_head()
-    // and drupal_get_http_header().
+    // Handle all non-asset attachments. This populates drupal_get_html_head().
     $all_attached = ['#attached' => $attached];
     drupal_process_attached($all_attached);
 
@@ -120,9 +119,10 @@ public function processAttachments(AttachmentsInterface $response) {
     // Now replace the placeholders in the response content with the real data.
     $this->renderPlaceholders($response, $placeholders, $variables);
 
-    // Finally set the headers on the response.
-    $headers = drupal_get_http_header();
-    $this->setHeaders($response, $headers);
+    // Finally set the headers on the response if any bubbled.
+    if (!empty($attached['http_header'])) {
+      $this->setHeaders($response, $attached['http_header']);
+    }
 
     return $response;
   }
@@ -205,13 +205,17 @@ protected function renderPlaceholders(HtmlResponse $response, array $placeholder
    *   The headers to set.
    */
   protected function setHeaders(HtmlResponse $response, array $headers) {
-    foreach ($headers as $name => $value) {
+    foreach ($headers as $values) {
+      $name = $values[0];
+      $value = $values[1];
+      $append = !empty($values[2]);
+
       // Drupal treats the HTTP response status code like a header, even though
       // it really is not.
-      if ($name === 'status') {
+      if (strtolower($name) === 'status') {
         $response->setStatusCode($value);
       }
-      $response->headers->set($name, $value, FALSE);
+      $response->headers->set($name, $value, $append);
     }
   }
 
