diff --git a/.htaccess b/.htaccess index a69bdd4e8b24c518c3a55f5729e7ffa860a4cf5a..0c89072e93688d8ab0dfc0ddf9b0d4004b271d38 100644 --- a/.htaccess +++ b/.htaccess @@ -99,8 +99,7 @@ DirectoryIndex index.php index.html index.htm # Redirect common PHP files to their new locations. RewriteCond %{REQUEST_URI} ^(.*)?/(update.php) [OR] - RewriteCond %{REQUEST_URI} ^(.*)?/(install.php) [OR] - RewriteCond %{REQUEST_URI} ^(.*)?/(cron.php) + RewriteCond %{REQUEST_URI} ^(.*)?/(install.php) RewriteCond %{REQUEST_URI} !core RewriteRule ^ %1/core/%2 [L,QSA,R=301] diff --git a/core/INSTALL.txt b/core/INSTALL.txt index 5c0c7b24860bb3f25556d774a887652515d65fba..f7ee23ce30b0953192ed7de169fbc81fe306bb18 100644 --- a/core/INSTALL.txt +++ b/core/INSTALL.txt @@ -273,10 +273,10 @@ INSTALLATION It is also possible to run the cron tasks independent of site visits; this is recommended for most sites. To do this, you will need to set up an automated - process to visit the page cron.php on your site, which executes the cron + process to visit the page /cron on your site, which executes the cron tasks. - The URL of the cron.php page requires a "cron key" to protect against + The URL of the cron page requires a "cron key" to protect against unauthorized access. Your site's cron key is automatically generated during installation and is specific to your site. The full URL of the page, with the cron key, is available in the "Cron maintenance tasks" section of the Status @@ -284,13 +284,13 @@ INSTALLATION As an example for how to set up this automated process, you can use the crontab utility on Unix/Linux systems. The following crontab line uses the - wget command to visit the cron.php page, and runs each hour, on the hour: + wget command to visit the cron page, and runs each hour, on the hour: - 0 * * * * wget -O - -q -t 1 http://example.com/core/cron.php?cron_key=YOURKEY + 0 * * * * wget -O - -q -t 1 http://example.com/cron/YOURKEY - Replace the text "http://example.com/core/cron.php?cron_key=YOURKEY" in the - example with the full URL displayed under "Cron maintenance tasks" on the - "Status report" page. + Replace the text "http://example.com/cron/YOURKEY" in the example with the + full URL displayed under "Cron maintenance tasks" on the "Status report" + page. More information about cron maintenance tasks is available at http://drupal.org/cron, and sample cron shell scripts can be found in the diff --git a/core/cron.php b/core/cron.php deleted file mode 100644 index fa9aa14d4d4007d90c6f7d6c1a42a848d8c8e787..0000000000000000000000000000000000000000 --- a/core/cron.php +++ /dev/null @@ -1,29 +0,0 @@ -<?php - -/** - * @file - * Handles incoming requests to fire off regularly-scheduled tasks (cron jobs). - */ - -// Change the directory to the Drupal root. -chdir('..'); - -/** - * Root directory of Drupal installation. - */ -define('DRUPAL_ROOT', getcwd()); - -include_once DRUPAL_ROOT . '/core/includes/bootstrap.inc'; -drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL); - -if (!isset($_GET['cron_key']) || variable_get('cron_key', 'drupal') != $_GET['cron_key']) { - watchdog('cron', 'Cron could not run because an invalid key was used.', array(), WATCHDOG_NOTICE); - drupal_access_denied(); -} -elseif (variable_get('maintenance_mode', 0)) { - watchdog('cron', 'Cron could not run because the site is in maintenance mode.', array(), WATCHDOG_NOTICE); - drupal_access_denied(); -} -else { - drupal_cron_run(); -} diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc index 846146a3b589be5312e5cc21bf7272ac988c8339..8836b8c9f8260babfbf3057470bccc0f9051e7a0 100644 --- a/core/includes/bootstrap.inc +++ b/core/includes/bootstrap.inc @@ -626,7 +626,7 @@ function drupal_settings_initialize() { // '/index.php', whereas $_SERVER['PHP_SELF'] is '/index.php/foo'. if ($dir = rtrim(dirname($_SERVER['SCRIPT_NAME']), '\/')) { // Remove "core" directory if present, allowing install.php, update.php, - // cron.php and others to auto-detect a base path. + // and others to auto-detect a base path. $core_position = strrpos($dir, '/core'); if ($core_position !== FALSE && strlen($dir) - 5 == $core_position) { $base_path = substr($dir, 0, $core_position); diff --git a/core/modules/aggregator/aggregator.test b/core/modules/aggregator/aggregator.test index ddfcc0775b5ce60dd81c7a72565a96c7ef9fb095..f58fb65fae905a7a1c372628a2cf60fadd9cb6d7 100644 --- a/core/modules/aggregator/aggregator.test +++ b/core/modules/aggregator/aggregator.test @@ -801,11 +801,11 @@ class AggregatorCronTestCase extends AggregatorTestCase { $key = variable_get('cron_key', 'drupal'); $this->createSampleNodes(); $feed = $this->createFeed(); - $this->drupalGet($base_url . '/core/cron.php', array('external' => TRUE, 'query' => array('cron_key' => $key))); + $this->cronRun(); $this->assertEqual(5, db_query('SELECT COUNT(*) FROM {aggregator_item} WHERE fid = :fid', array(':fid' => $feed->fid))->fetchField(), 'Expected number of items in database.'); $this->removeFeedItems($feed); $this->assertEqual(0, db_query('SELECT COUNT(*) FROM {aggregator_item} WHERE fid = :fid', array(':fid' => $feed->fid))->fetchField(), 'Expected number of items in database.'); - $this->drupalGet($base_url . '/core/cron.php', array('external' => TRUE, 'query' => array('cron_key' => $key))); + $this->cronRun(); $this->assertEqual(5, db_query('SELECT COUNT(*) FROM {aggregator_item} WHERE fid = :fid', array(':fid' => $feed->fid))->fetchField(), 'Expected number of items in database.'); // Test feed locking when queued for update. @@ -816,7 +816,7 @@ class AggregatorCronTestCase extends AggregatorTestCase { 'queued' => REQUEST_TIME, )) ->execute(); - $this->drupalGet($base_url . '/core/cron.php', array('external' => TRUE, 'query' => array('cron_key' => $key))); + $this->cronRun(); $this->assertEqual(0, db_query('SELECT COUNT(*) FROM {aggregator_item} WHERE fid = :fid', array(':fid' => $feed->fid))->fetchField(), 'Expected number of items in database.'); db_update('aggregator_feed') ->condition('fid', $feed->fid) @@ -824,7 +824,7 @@ class AggregatorCronTestCase extends AggregatorTestCase { 'queued' => 0, )) ->execute(); - $this->drupalGet($base_url . '/core/cron.php', array('external' => TRUE, 'query' => array('cron_key' => $key))); + $this->cronRun(); $this->assertEqual(5, db_query('SELECT COUNT(*) FROM {aggregator_item} WHERE fid = :fid', array(':fid' => $feed->fid))->fetchField(), 'Expected number of items in database.'); } } diff --git a/core/modules/simpletest/drupal_web_test_case.php b/core/modules/simpletest/drupal_web_test_case.php index 23fa5269785cd7455b1381b5ddc7294d42c4f644..ac74fc8c6026ee5760110cb4e46030bfc990f5bf 100644 --- a/core/modules/simpletest/drupal_web_test_case.php +++ b/core/modules/simpletest/drupal_web_test_case.php @@ -2240,7 +2240,7 @@ protected function drupalPostAJAX($path, $edit, $triggering_element, $ajax_path * Runs cron in the Drupal installed by Simpletest. */ protected function cronRun() { - $this->drupalGet($GLOBALS['base_url'] . '/core/cron.php', array('external' => TRUE, 'query' => array('cron_key' => variable_get('cron_key', 'drupal')))); + $this->drupalGet('cron/' . variable_get('cron_key', 'drupal')); } /** diff --git a/core/modules/system/system.install b/core/modules/system/system.install index f0e36cc3ceffe1526942baed60a88665182617a5..5db229f3049237f40e985c53543547971ffdcf46 100644 --- a/core/modules/system/system.install +++ b/core/modules/system/system.install @@ -283,7 +283,7 @@ function system_requirements($phase) { } $description .= ' ' . $t('You can <a href="@cron">run cron manually</a>.', array('@cron' => url('admin/reports/status/run-cron'))); - $description .= '<br />' . $t('To run cron from outside the site, go to <a href="!cron">!cron</a>', array('!cron' => url($base_url . '/core/cron.php', array('external' => TRUE, 'query' => array('cron_key' => variable_get('cron_key', 'drupal')))))); + $description .= '<br />' . $t('To run cron from outside the site, go to <a href="!cron">!cron</a>', array('!cron' => url('cron/' . variable_get('cron_key', 'drupal')))); $requirements['cron'] = array( 'title' => $t('Cron maintenance tasks'), diff --git a/core/modules/system/system.module b/core/modules/system/system.module index 69ee2af250d21c87dfe187b911f5d204adb8cd45..34b6db2947ebdd99dd6da947d8621503c989463a 100644 --- a/core/modules/system/system.module +++ b/core/modules/system/system.module @@ -580,6 +580,13 @@ function system_element_info() { * Implements hook_menu(). */ function system_menu() { + $items['cron/%'] = array( + 'title' => 'Run cron', + 'page callback' => 'system_cron_page', + 'access callback' => 'system_cron_access', + 'access arguments' => array(1), + 'type' => MENU_CALLBACK, + ); $items['system/files'] = array( 'title' => 'File download', 'page callback' => 'file_download', @@ -1111,6 +1118,38 @@ function system_menu() { return $items; } +/** + * Page callback; Execute cron tasks. + * + * @see system_cron_access(). + */ +function system_cron_page() { + drupal_cron_run(); + + // Returning nothing causes no output to be generated. +} + +/** + * Access callback for system_cron(). + * + * @param string $key + * A hash to validate the page request origin. + * + * @see system_cron_page(). + */ +function system_cron_access($key) { + if ($key != variable_get('cron_key', 'drupal')) { + watchdog('cron', 'Cron could not run because an invalid key was used.', array(), WATCHDOG_NOTICE); + return FALSE; + } + elseif (variable_get('maintenance_mode', 0)) { + watchdog('cron', 'Cron could not run because the site is in maintenance mode.', array(), WATCHDOG_NOTICE); + return FALSE; + } + + return TRUE; +} + /** * Theme callback for the default batch page. */ diff --git a/core/modules/system/system.test b/core/modules/system/system.test index 1458ca742dfbb15f84cd138754d0d232bf621b52..30a270d1173ad61c5ca61a7bdff42219f8819ecc 100644 --- a/core/modules/system/system.test +++ b/core/modules/system/system.test @@ -789,14 +789,11 @@ class IPAddressBlockingTestCase extends DrupalWebTestCase { } class CronRunTestCase extends DrupalWebTestCase { - /** - * Implement getInfo(). - */ public static function getInfo() { return array( 'name' => 'Cron run', 'description' => 'Test cron run.', - 'group' => 'System' + 'group' => 'System', ); } @@ -811,17 +808,17 @@ class CronRunTestCase extends DrupalWebTestCase { global $base_url; // Run cron anonymously without any cron key. - $this->drupalGet($base_url . '/core/cron.php', array('external' => TRUE)); - $this->assertResponse(403); + $this->drupalGet('cron'); + $this->assertResponse(404); // Run cron anonymously with a random cron key. $key = $this->randomName(16); - $this->drupalGet($base_url . '/core/cron.php', array('external' => TRUE, 'query' => array('cron_key' => $key))); + $this->drupalGet('cron/' . $key); $this->assertResponse(403); // Run cron anonymously with the valid cron key. $key = variable_get('cron_key', 'drupal'); - $this->drupalGet($base_url . '/core/cron.php', array('external' => TRUE, 'query' => array('cron_key' => $key))); + $this->drupalGet('cron/' . $key); $this->assertResponse(200); } diff --git a/core/scripts/cron-curl.sh b/core/scripts/cron-curl.sh index 71f06b95b3c1317b7407c7cfc00e28eae2bb6756..b43193c1627538e6348a76d8a432e45a8ffce7dd 100644 --- a/core/scripts/cron-curl.sh +++ b/core/scripts/cron-curl.sh @@ -1,3 +1,3 @@ #!/bin/sh -curl --silent --compressed http://example.com/core/cron.php +curl --silent --compressed http://example.com/cron/YOURKEY diff --git a/core/scripts/cron-lynx.sh b/core/scripts/cron-lynx.sh index 36880d2996d9e50d1f086264bbe83d039978b726..46ac278c3906b8e2f787da16e2729be8999bf545 100644 --- a/core/scripts/cron-lynx.sh +++ b/core/scripts/cron-lynx.sh @@ -1,3 +1,3 @@ #!/bin/sh -/usr/bin/lynx -source http://example.com/core/cron.php > /dev/null 2>&1 +/usr/bin/lynx -source http://example.com/cron/YOURKEY > /dev/null 2>&1 diff --git a/core/scripts/drupal.sh b/core/scripts/drupal.sh index fb5e82c1061e09def2162c5145dd9edec2bb8ff3..b18f5a40d46d06c9122f7a4cc16c06a70e12f348 100755 --- a/core/scripts/drupal.sh +++ b/core/scripts/drupal.sh @@ -43,8 +43,8 @@ If the given path and file exists it will be executed directly, i.e. if URI is set to http://default/bar/foo.php and bar/foo.php exists, this script will be executed without - bootstrapping Drupal. To execute Drupal's cron.php, specify - http://default/core/cron.php as the URI. + bootstrapping Drupal. To execute Drupal's update.php, specify + http://default/core/update.php as the URI. To run this script without --root argument invoke it from the root directory