Commit 5058fa38 authored by webchick's avatar webchick
Browse files

Issue #1447736 by rbayliss, mikeytown2, effulgentsia, kim.pepper, Fabianx,...

Issue #1447736 by rbayliss, mikeytown2, effulgentsia, kim.pepper, Fabianx, boombatower: Adopt Guzzle library to replace drupal_http_request().
parent 7ac0584c
......@@ -13,6 +13,7 @@
"symfony/yaml": "2.1.*",
"twig/twig": "1.8.*",
"doctrine/common": "2.3.*",
"guzzle/http": "3.*",
"kriswallsmith/assetic": "1.1.*"
},
"minimum-stability": "alpha"
......
This diff is collapsed.
......@@ -79,6 +79,16 @@ public function build(ContainerBuilder $container) {
->addArgument(new Reference('database'))
->addArgument(new Reference('keyvalue'));
$container->register('http_client_simpletest_subscriber', 'Drupal\Core\Http\Plugin\SimpletestHttpRequestSubscriber');
$container->register('http_default_client', 'Guzzle\Http\Client')
->addArgument(NULL)
->addArgument(array(
'curl.CURLOPT_TIMEOUT' => 30.0,
'curl.CURLOPT_MAXREDIRS' => 3,
))
->addMethodCall('addSubscriber', array(new Reference('http_client_simpletest_subscriber')))
->addMethodCall('setUserAgent', array('Drupal (+http://drupal.org/)'));
// Register the EntityManager.
$container->register('plugin.manager.entity', 'Drupal\Core\Entity\EntityManager');
......
<?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']));
}
}
}
......@@ -5,6 +5,24 @@
* Install, update and uninstall functions for the aggregator module.
*/
/**
* Implements hook_requirements().
*/
function aggregator_requirements($phase) {
$t = get_t();
$has_curl = function_exists('curl_init');
$requirements = array();
$requirements['curl'] = array(
'title' => $t('cURL'),
'value' => $has_curl ? $t('Enabled') : $t('Not found'),
);
if (!$has_curl) {
$requirements['curl']['severity'] = REQUIREMENT_ERROR;
$requirements['curl']['description'] = $t('The Aggregator module could not be installed because the PHP <a href="@curl_url">cURL</a> library is not available.', array('@curl_url' => 'http://php.net/manual/curl.setup.php'));
}
return $requirements;
}
/**
* Implements hook_schema().
*/
......
......@@ -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_tags(array('content' => TRUE));
......
......@@ -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);
}
}
......@@ -162,14 +162,14 @@ public function loadClass($class)
*/
public function findFile($class)
{
if (isset($this->classMap[$class])) {
return $this->classMap[$class];
}
if ('\\' == $class[0]) {
$class = substr($class, 1);
}
if (isset($this->classMap[$class])) {
return $this->classMap[$class];
}
if (false !== $pos = strrpos($class, '\\')) {
// namespaced class name
$classPath = str_replace('\\', DIRECTORY_SEPARATOR, substr($class, 0, $pos)) . DIRECTORY_SEPARATOR;
......@@ -202,6 +202,6 @@ public function findFile($class)
return $file;
}
$this->classMap[$class] = false;
return $this->classMap[$class] = false;
}
}
......@@ -17,6 +17,10 @@
'Symfony\\Component\\DependencyInjection' => $vendorDir . '/symfony/dependency-injection/',
'Symfony\\Component\\ClassLoader' => $vendorDir . '/symfony/class-loader/',
'SessionHandlerInterface' => $vendorDir . '/symfony/http-foundation/Symfony/Component/HttpFoundation/Resources/stubs',
'Guzzle\\Stream' => $vendorDir . '/guzzle/stream/',
'Guzzle\\Parser' => $vendorDir . '/guzzle/parser/',
'Guzzle\\Http' => $vendorDir . '/guzzle/http/',
'Guzzle\\Common' => $vendorDir . '/guzzle/common/',
'Doctrine\\Common' => $vendorDir . '/doctrine/common/lib/',
'Assetic' => $vendorDir . '/kriswallsmith/assetic/src/',
);
......@@ -6,9 +6,15 @@
class ComposerAutoloaderInit
{
private static $loader;
public static function getLoader()
{
$loader = new \Composer\Autoload\ClassLoader();
if (null !== static::$loader) {
return static::$loader;
}
static::$loader = $loader = new \Composer\Autoload\ClassLoader();
$vendorDir = dirname(__DIR__);
$baseDir = dirname($vendorDir);
......
......@@ -3,7 +3,6 @@
"name": "twig/twig",
"version": "v1.8.3",
"version_normalized": "1.8.3.0",
"time": "2012-06-18 18:48:16",
"source": {
"type": "git",
"url": "git://github.com/fabpot/Twig.git",
......@@ -18,6 +17,7 @@
"require": {
"php": ">=5.2.4"
},
"time": "2012-06-18 18:48:16",
"type": "library",
"extra": {
"branch-alias": {
......@@ -25,6 +25,11 @@
}
},
"installation-source": "dist",
"autoload": {
"psr-0": {
"Twig_": "lib/"
}
},
"license": [
"BSD-3"
],
......@@ -46,19 +51,13 @@
"homepage": "http://twig.sensiolabs.org",
"keywords": [
"templating"
],
"autoload": {
"psr-0": {
"Twig_": "lib/"
}
}
]
},
{
"name": "symfony/class-loader",
"version": "v2.1.0-RC2",
"version_normalized": "2.1.0.0-RC2",
"target-dir": "Symfony/Component/ClassLoader",
"time": "2012-08-27 14:51:49",
"source": {
"type": "git",
"url": "https://github.com/symfony/ClassLoader",
......@@ -76,6 +75,7 @@
"require-dev": {
"symfony/finder": "2.1.*"
},
"time": "2012-08-27 14:51:49",
"type": "library",
"extra": {
"branch-alias": {
......@@ -83,6 +83,11 @@
}
},
"installation-source": "dist",
"autoload": {
"psr-0": {
"Symfony\\Component\\ClassLoader": ""
}
},
"license": [
"MIT"
],
......@@ -101,19 +106,13 @@
}
],
"description": "Symfony ClassLoader Component",
"homepage": "http://symfony.com",
"autoload": {
"psr-0": {
"Symfony\\Component\\ClassLoader": ""
}
}
"homepage": "http://symfony.com"
},
{
"name": "symfony/dependency-injection",
"version": "v2.1.0-RC2",
"version_normalized": "2.1.0.0-RC2",
"target-dir": "Symfony/Component/DependencyInjection",
"time": "2012-08-28 06:54:42",
"source": {
"type": "git",
"url": "https://github.com/symfony/DependencyInjection",
......@@ -136,6 +135,7 @@
"symfony/yaml": "v2.1.0-RC2",
"symfony/config": "v2.1.0-RC2"
},
"time": "2012-08-28 06:54:42",
"type": "library",
"extra": {
"branch-alias": {
......@@ -143,6 +143,11 @@
}
},
"installation-source": "dist",
"autoload": {
"psr-0": {
"Symfony\\Component\\DependencyInjection": ""
}
},
"license": [
"MIT"
],
......@@ -161,18 +166,12 @@
}
],
"description": "Symfony DependencyInjection Component",
"homepage": "http://symfony.com",
"autoload": {
"psr-0": {
"Symfony\\Component\\DependencyInjection": ""
}
}
"homepage": "http://symfony.com"
},
{
"name": "doctrine/common",
"version": "2.3.0-RC2",
"version_normalized": "2.3.0.0-RC2",
"time": "2012-08-29 13:06:32",
"source": {
"type": "git",
"url": "https://github.com/doctrine/common",
......@@ -187,6 +186,7 @@
"require": {
"php": ">=5.3.2"
},
"time": "2012-08-29 13:06:32",
"type": "library",
"extra": {
"branch-alias": {
......@@ -194,6 +194,11 @@
}
},
"installation-source": "dist",
"autoload": {
"psr-0": {
"Doctrine\\Common": "lib/"
}
},
"license": [
"MIT"
],
......@@ -237,19 +242,13 @@
"eventmanager",
"annotations",
"persistence"
],
"autoload": {
"psr-0": {
"Doctrine\\Common": "lib/"
}
}
]
},
{
"name": "symfony/http-foundation",
"version": "v2.1.0-RC2",
"version_normalized": "2.1.0.0-RC2",
"target-dir": "Symfony/Component/HttpFoundation",
"time": "2012-08-22 12:48:41",
"source": {
"type": "git",
"url": "https://github.com/symfony/HttpFoundation",
......@@ -264,6 +263,7 @@
"require": {
"php": ">=5.3.3"
},
"time": "2012-08-22 12:48:41",
"type": "library",
"extra": {
"branch-alias": {
......@@ -271,6 +271,12 @@
}
},
"installation-source": "dist",
"autoload": {
"psr-0": {
"Symfony\\Component\\HttpFoundation": "",
"SessionHandlerInterface": "Symfony/Component/HttpFoundation/Resources/stubs"
}
},
"license": [
"MIT"
],
......@@ -289,20 +295,13 @@
}
],
"description": "Symfony HttpFoundation Component",
"homepage": "http://symfony.com",
"autoload": {
"psr-0": {
"Symfony\\Component\\HttpFoundation": "",
"SessionHandlerInterface": "Symfony/Component/HttpFoundation/Resources/stubs"
}
}
"homepage": "http://symfony.com"
},
{
"name": "symfony/event-dispatcher",
"version": "v2.1.0-RC2",
"version_normalized": "2.1.0.0-RC2",
"target-dir": "Symfony/Component/EventDispatcher",
"time": "2012-08-22 12:48:41",
"source": {
"type": "git",
"url": "https://github.com/symfony/EventDispatcher",
......@@ -324,6 +323,7 @@
"symfony/dependency-injection": "v2.1.0-RC2",
"symfony/http-kernel": "v2.1.0-RC2"
},
"time": "2012-08-22 12:48:41",
"type": "library",
"extra": {
"branch-alias": {
......@@ -331,6 +331,11 @@
}
},
"installation-source": "dist",
"autoload": {
"psr-0": {
"Symfony\\Component\\EventDispatcher": ""
}
},
"license": [
"MIT"
],
......@@ -349,19 +354,13 @@
}
],
"description": "Symfony EventDispatcher Component",
"homepage": "http://symfony.com",
"autoload": {
"psr-0": {
"Symfony\\Component\\EventDispatcher": ""
}
}
"homepage": "http://symfony.com"
},
{
"name": "symfony/http-kernel",
"version": "v2.1.0-RC2",
"version_normalized": "2.1.0.0-RC2",
"target-dir": "Symfony/Component/HttpKernel",
"time": "2012-08-28 07:00:18",
"source": {
"type": "git",
"url": "https://github.com/symfony/HttpKernel",
......@@ -396,6 +395,7 @@
"symfony/dependency-injection": "v2.1.0-RC2",
"symfony/finder": "v2.1.0-RC2"
},
"time": "2012-08-28 07:00:18",
"type": "library",
"extra": {
"branch-alias": {
......@@ -403,6 +403,11 @@
}
},
"installation-source": "dist",
"autoload": {
"psr-0": {
"Symfony\\Component\\HttpKernel": ""
}
},
"license": [
"MIT"
],
......@@ -421,19 +426,13 @@
}
],
"description": "Symfony HttpKernel Component",
"homepage": "http://symfony.com",
"autoload": {
"psr-0": {
"Symfony\\Component\\HttpKernel": ""
}
}
"homepage": "http://symfony.com"
},
{
"name": "symfony/routing",
"version": "v2.1.0-RC2",
"version_normalized": "2.1.0.0-RC2",
"target-dir": "Symfony/Component/Routing",
"time": "2012-08-28 06:54:42",
"source": {
"type": "git",
"url": "https://github.com/symfony/Routing",
......@@ -459,6 +458,7 @@
"symfony/yaml": "v2.1.0-RC2",
"doctrine/common": ">=2.2,<2.4-dev"
},
"time": "2012-08-28 06:54:42",
"type": "library",
"extra": {
"branch-alias": {
......@@ -466,6 +466,11 @@
}
},
"installation-source": "dist",
"autoload": {
"psr-0": {
"Symfony\\Component\\Routing": ""
}
},
"license": [
"MIT"
],
......@@ -484,19 +489,13 @@
}
],
"description": "Symfony Routing Component",
"homepage": "http://symfony.com",
"autoload": {
"psr-0": {
"Symfony\\Component\\Routing": ""
}
}
"homepage": "http://symfony.com"
},
{
"name": "symfony/yaml",
"version": "v2.1.0-RC2",
"version_normalized": "2.1.0.0-RC2",
"target-dir": "Symfony/Component/Yaml",
"time": "2012-08-22 12:48:41",
"source": {
"type": "git",
"url": "https://github.com/symfony/Yaml",
......@@ -511,6 +510,7 @@
"require": {
"php": ">=5.3.3"
},
"time": "2012-08-22 12:48:41",
"type": "library",
"extra": {
"branch-alias": {
......@@ -518,6 +518,11 @@
}
},
"installation-source": "dist",
"autoload": {
"psr-0": {
"Symfony\\Component\\Yaml": ""
}
},
"license": [
"MIT"
],
......@@ -536,19 +541,13 @@
}
],
"description": "Symfony Yaml Component",
"homepage": "http://symfony.com",
"autoload": {
"psr-0": {
"Symfony\\Component\\Yaml": ""
}
}
"homepage": "http://symfony.com"
},
{
"name": "symfony/process",
"version": "v2.1.0-RC2",
"version_normalized": "2.1.0.0-RC2",
"target-dir": "Symfony/Component/Process",
"time": "2012-08-26 06:13:51",
"source": {
"type": "git",
"url": "https://github.com/symfony/Process",
......@@ -563,6 +562,7 @@
"require": {