diff --git a/core/composer.json b/core/composer.json
index eaf5983..287105a 100644
--- a/core/composer.json
+++ b/core/composer.json
@@ -13,6 +13,7 @@
     "symfony/yaml": "2.1.*",
     "twig/twig": "1.8.*",
     "doctrine/common": "2.3.*",
+    "guzzle/guzzle": "3.*",
     "kriswallsmith/assetic": "1.1.*"
   },
   "minimum-stability": "alpha"
diff --git a/core/includes/common.inc b/core/includes/common.inc
index 0f252ca..f325190 100644
--- a/core/includes/common.inc
+++ b/core/includes/common.inc
@@ -7,6 +7,7 @@
 use Drupal\Core\Cache\CacheBackendInterface;
 use Drupal\Core\Database\Database;
 use Drupal\Core\Template\Attribute;
+use Guzzle\Http\Message\RequestInterface;
 
 /**
  * @file
diff --git a/core/lib/Drupal/Core/Http/Plugin/SimpletestHttpRequestSubscriber.php b/core/lib/Drupal/Core/Http/Plugin/SimpletestHttpRequestSubscriber.php
new file mode 100644
index 0000000..6f5bfd1
--- /dev/null
+++ b/core/lib/Drupal/Core/Http/Plugin/SimpletestHttpRequestSubscriber.php
@@ -0,0 +1,42 @@
+<?php
+/**
+ * @file
+ * Contains Drupal\Core\Http\Plugin\SimpletestHttpRequestSubscriber
+ */
+
+namespace Drupal\Core\Http\Plugin;
+
+use Guzzle\Common\Event;
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
+
+/**
+ * Subscribe to HTTP requests and override the User-Agent header if the request
+ * is being dispatched from inside a simpletest.
+ */
+class SimpletestHttpRequestSubscriber implements EventSubscriberInterface {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function getSubscribedEvents()
+  {
+    return array('request.before_send' => 'onBeforeSendRequest');
+  }
+
+
+  /**
+   * Event callback for request.before_send
+   */
+  public function onBeforeSendRequest(Event $event) {
+    // If the database prefix is being used by SimpleTest to run the tests in a copied
+    // database then set the user-agent header to the database prefix so that any
+    // calls to other Drupal pages will run the SimpleTest prefixed database. The
+    // user-agent is used to ensure that multiple testing sessions running at the
+    // same time won't interfere with each other as they would if the database
+    // prefix were stored statically in a file or database variable.
+    $test_info = &$GLOBALS['drupal_test_info'];
+    if (!empty($test_info['test_run_id'])) {
+      $event['request']->setHeader('User-Agent', drupal_generate_test_ua($test_info['test_run_id']));
+    }
+  }
+}
diff --git a/core/modules/aggregator/aggregator.parser.inc b/core/modules/aggregator/aggregator.parser.inc
index bacaa84..67103ae 100644
--- a/core/modules/aggregator/aggregator.parser.inc
+++ b/core/modules/aggregator/aggregator.parser.inc
@@ -23,7 +23,6 @@ function aggregator_aggregator_parse($feed) {
 
   // Filter the input data.
   if (aggregator_parse_feed($feed->source_string, $feed)) {
-    $modified = empty($feed->http_headers['last-modified']) ? 0 : strtotime($feed->http_headers['last-modified']);
 
     // Prepare the channel data.
     foreach ($channel as $key => $value) {
@@ -35,14 +34,10 @@ function aggregator_aggregator_parse($feed) {
       $image[$key] = trim($value);
     }
 
-    $etag = empty($feed->http_headers['etag']) ? '' : $feed->http_headers['etag'];
-
     // Add parsed data to the feed object.
     $feed->link = !empty($channel['link']) ? $channel['link'] : '';
     $feed->description = !empty($channel['description']) ? $channel['description'] : '';
     $feed->image = !empty($image['url']) ? $image['url'] : '';
-    $feed->etag = $etag;
-    $feed->modified = $modified;
 
     // Clear the page and block caches.
     cache_invalidate(array('content' => TRUE));
diff --git a/core/modules/aggregator/lib/Drupal/aggregator/Plugin/aggregator/fetcher/DefaultFetcher.php b/core/modules/aggregator/lib/Drupal/aggregator/Plugin/aggregator/fetcher/DefaultFetcher.php
index bbe883c..2df801a 100644
--- a/core/modules/aggregator/lib/Drupal/aggregator/Plugin/aggregator/fetcher/DefaultFetcher.php
+++ b/core/modules/aggregator/lib/Drupal/aggregator/Plugin/aggregator/fetcher/DefaultFetcher.php
@@ -10,6 +10,7 @@
 use Drupal\aggregator\Plugin\FetcherInterface;
 use Drupal\Core\Annotation\Plugin;
 use Drupal\Core\Annotation\Translation;
+use Guzzle\Http\Exception\BadResponseException;
 
 /**
  * Defines a default fetcher implementation.
@@ -28,44 +29,31 @@ class DefaultFetcher implements FetcherInterface {
    * Implements Drupal\aggregator\Plugin\FetcherInterface::fetch().
    */
   function fetch(&$feed) {
+    $request = drupal_container()->get('http_default_client')->get($feed->url);
     $feed->source_string = FALSE;
 
     // Generate conditional GET headers.
-    $headers = array();
     if ($feed->etag) {
-      $headers['If-None-Match'] = $feed->etag;
+      $request->addHeader('If-None-Match', $feed->etag);
     }
     if ($feed->modified) {
-      $headers['If-Modified-Since'] = gmdate(DATE_RFC1123, $feed->modified);
+      $request->addHeader('If-Modified-Since', gmdate(DATE_RFC1123, $feed->modified));
     }
 
-    // Request feed.
-    $result = drupal_http_request($feed->url, array('headers' => $headers));
+    try {
+      $response = $request->send();
+      $feed->source_string = $response->getBody(TRUE);
+      $feed->etag = $response->getEtag();
+      $feed->modified = strtotime($response->getLastModified());
+      $feed->http_headers = $response->getHeaders();
 
-    // Process HTTP response code.
-    switch ($result->code) {
-      case 304:
-        break;
-      case 301:
-        $feed->url = $result->redirect_url;
-        // Do not break here.
-      case 200:
-      case 302:
-      case 307:
-        if (!isset($result->data)) {
-          $result->data = '';
-        }
-        if (!isset($result->headers)) {
-          $result->headers = array();
-        }
-        $feed->source_string = $result->data;
-        $feed->http_headers = $result->headers;
-        break;
-      default:
-        watchdog('aggregator', 'The feed from %site seems to be broken due to "%error".', array('%site' => $feed->title, '%error' => $result->code . ' ' . $result->error), WATCHDOG_WARNING);
-        drupal_set_message(t('The feed from %site seems to be broken because of error "%error".', array('%site' => $feed->title, '%error' => $result->code . ' ' . $result->error)));
+      return TRUE;
+    }
+    catch (BadResponseException $e) {
+      $response = $e->getResponse();
+      watchdog('aggregator', 'The feed from %site seems to be broken due to "%error".', array('%site' => $feed->title, '%error' => $response->getStatusCode() . ' ' . $response->getReasonPhrase()), WATCHDOG_WARNING);
+      drupal_set_message(t('The feed from %site seems to be broken because of error "%error".', array('%site' => $feed->title, '%error' => $response->getStatusCode() . ' ' . $response->getReasonPhrase())));
+      return FALSE;
     }
-
-    return !($feed->source_string === FALSE);
   }
 }
diff --git a/core/modules/system/system.module b/core/modules/system/system.module
index ea3dadc..d4e3e5b 100644
--- a/core/modules/system/system.module
+++ b/core/modules/system/system.module
@@ -10,6 +10,7 @@
 
 use Symfony\Component\HttpFoundation\JsonResponse;
 use Symfony\Component\HttpFoundation\Response;
+use Guzzle\Http\Exception\BadResponseException;
 
 /**
  * Maximum age of temporary files in seconds.
@@ -3639,17 +3640,20 @@ function system_retrieve_file($url, $destination = NULL, $managed = FALSE, $repl
       $path = $destination;
     }
   }
-  $result = drupal_http_request($url);
-  if ($result->code != 200) {
-    drupal_set_message(t('HTTP error @errorcode occurred when trying to fetch @remote.', array('@errorcode' => $result->code, '@remote' => $url)), 'error');
-    return FALSE;
+
+  try {
+    $result = drupal_container()->get('http_default_client')->get($url)->send();
+    $local = $managed ? file_save_data($result->getBody(TRUE), $path, $replace) : file_unmanaged_save_data($result->getBody(TRUE), $path, $replace);
+    if (!$local) {
+      drupal_set_message(t('@remote could not be saved to @path.', array('@remote' => $url, '@path' => $path)), 'error');
+    }
+    return $local;
   }
-  $local = $managed ? file_save_data($result->data, $path, $replace) : file_unmanaged_save_data($result->data, $path, $replace);
-  if (!$local) {
-    drupal_set_message(t('@remote could not be saved to @path.', array('@remote' => $url, '@path' => $path)), 'error');
+  catch (BadResponseException $e) {
+    $response = $e->getResponse();
+    drupal_set_message(t('HTTP error @errorcode occurred when trying to fetch @remote.', array('@errorcode' => $response->getStatusCode(), '@remote' => $url)), 'error');
+    return FALSE;
   }
-
-  return $local;
 }
 
 /**
