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 @@ + '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; } /**