diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc index a3a0f46..17b6591 100644 --- a/core/includes/bootstrap.inc +++ b/core/includes/bootstrap.inc @@ -548,9 +548,10 @@ function config_get_config_directory($type = CONFIG_ACTIVE_DIRECTORY) { * return the expected values. * * Most other parameters do not need to be passed in, but may be necessary in - * some cases; for example, if Drupal's ip_address() function needs to return - * anything but the standard localhost value ('127.0.0.1'), the command line - * script should pass in the desired value via the 'REMOTE_ADDR' key. + * some cases; for example, if Drupal::service('request')->getClientIP() + * needs to return anything but the standard localhost value ('127.0.0.1'), + * the command line script should pass in the desired value via the + * 'REMOTE_ADDR' key. * * @param $variables * (optional) An associative array of variables within $_SERVER that should @@ -561,7 +562,7 @@ function config_get_config_directory($type = CONFIG_ACTIVE_DIRECTORY) { * * @see conf_path() * @see request_uri() - * @see ip_address() + * @see \Symfony\Component\HttpFoundation\Request::getClientIP() */ function drupal_override_server_variables($variables = array()) { // Allow the provided URL to override any existing values in $_SERVER. @@ -1779,7 +1780,7 @@ function watchdog($type, $message, array $variables = NULL, $severity = WATCHDOG 'uid' => $user_uid, 'request_uri' => $base_root . request_uri(), 'referer' => isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '', - 'ip' => ip_address(), + 'ip' => Drupal::service('request')->getClientIP(), // Request time isn't accurate for long processes, use time() instead. 'timestamp' => time(), ); @@ -2043,7 +2044,7 @@ function drupal_hash_base64($data) { function drupal_anonymous_user() { $values = array( 'uid' => 0, - 'hostname' => ip_address(), + 'hostname' => Drupal::service('request')->getClientIP(), 'roles' => array( DRUPAL_ANONYMOUS_RID => DRUPAL_ANONYMOUS_RID, ), @@ -3054,52 +3055,6 @@ function arg($index = NULL, $path = NULL) { } /** - * Returns the IP address of the client machine. - * - * If Drupal is behind a reverse proxy, we use the X-Forwarded-For header - * instead of $_SERVER['REMOTE_ADDR'], which would be the IP address of - * the proxy server, and not the client's. The actual header name can be - * configured by the reverse_proxy_header variable. - * - * @return - * IP address of client machine, adjusted for reverse proxy and/or cluster - * environments. - */ -function ip_address() { - $ip_address = &drupal_static(__FUNCTION__); - - if (!isset($ip_address)) { - $ip_address = $_SERVER['REMOTE_ADDR']; - - if (settings()->get('reverse_proxy', 0)) { - $reverse_proxy_header = settings()->get('reverse_proxy_header', 'HTTP_X_FORWARDED_FOR'); - if (!empty($_SERVER[$reverse_proxy_header])) { - // If an array of known reverse proxy IPs is provided, then trust - // the XFF header if request really comes from one of them. - $reverse_proxy_addresses = settings()->get('reverse_proxy_addresses', array()); - - // Turn XFF header into an array. - $forwarded = explode(',', $_SERVER[$reverse_proxy_header]); - - // Trim the forwarded IPs; they may have been delimited by commas and spaces. - $forwarded = array_map('trim', $forwarded); - - // Tack direct client IP onto end of forwarded array. - $forwarded[] = $ip_address; - - // Eliminate all trusted IPs. - $untrusted = array_diff($forwarded, $reverse_proxy_addresses); - - // The right-most IP is the most specific we can trust. - $ip_address = array_pop($untrusted); - } - } - } - - return $ip_address; -} - -/** * Initializes and returns the class loader. * * The class loader is responsible for lazy-loading all PSR-0 compatible diff --git a/core/includes/install.core.inc b/core/includes/install.core.inc index d2e461e..7ed15e3 100644 --- a/core/includes/install.core.inc +++ b/core/includes/install.core.inc @@ -329,6 +329,10 @@ function install_begin_request(&$install_state) { if ($install_state['settings_verified']) { $kernel = new DrupalKernel('install', FALSE, drupal_classloader(), FALSE); $kernel->boot(); + // Set the request in the kernel to the new created Request above + // so it is available to the rest of the installation process. + $kernel->getContainer() + ->set('request', $request); } else { // @todo Move into a proper Drupal\Core\DependencyInjection\InstallContainerBuilder. @@ -2377,6 +2381,10 @@ function install_configure_form_submit($form, &$form_state) { if ($form_state['values']['update_status_module'][1]) { module_enable(array('file', 'update'), FALSE); + // The kernel has been rebuilt, so add request info again. + Drupal::getContainer() + ->set('request', Request::createFromGlobals()); + // Add the site maintenance account's email address to the list of // addresses to be notified when updates are available, if selected. if ($form_state['values']['update_status_module'][2]) { diff --git a/core/includes/module.inc b/core/includes/module.inc index 99eac78..a4a47b5 100644 --- a/core/includes/module.inc +++ b/core/includes/module.inc @@ -8,6 +8,7 @@ use Drupal\Component\Graph\Graph; use Drupal\Component\Utility\NestedArray; use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\HttpFoundation\Request; /** * Builds a list of bootstrap modules and enabled modules and themes. @@ -354,6 +355,8 @@ function module_enable($module_list, $enable_dependencies = TRUE) { // @todo install_begin_request() creates a container without a kernel. if ($kernel = drupal_container()->get('kernel', ContainerInterface::NULL_ON_INVALID_REFERENCE)) { $kernel->updateModules($module_filenames, $module_filenames); + // Kernel has been rebuilt so add the request info back. + Drupal::getContainer()->set('request', Request::createFromGlobals()); } // Refresh the schema to include it. @@ -512,6 +515,8 @@ function module_disable($module_list, $disable_dependents = TRUE) { // Update the kernel to exclude the disabled modules. $enabled = $module_handler->getModuleList(); drupal_container()->get('kernel')->updateModules($enabled, $enabled); + // Kernel has been rebuilt so add the request info back. + Drupal::getContainer()->set('request', Request::createFromGlobals()); // Update the theme registry to remove the newly-disabled module. drupal_theme_rebuild(); diff --git a/core/includes/session.inc b/core/includes/session.inc index 31e67a6..5c09535 100644 --- a/core/includes/session.inc +++ b/core/includes/session.inc @@ -173,7 +173,7 @@ function _drupal_session_write($sid, $value) { // Either ssid or sid or both will be added from $key below. $fields = array( 'uid' => $user->uid, - 'hostname' => ip_address(), + 'hostname' => Drupal::service('request')->getClientIP(), 'session' => $value, 'timestamp' => REQUEST_TIME, ); diff --git a/core/lib/Drupal/Core/CoreBundle.php b/core/lib/Drupal/Core/CoreBundle.php index 63037b6..4d89586 100644 --- a/core/lib/Drupal/Core/CoreBundle.php +++ b/core/lib/Drupal/Core/CoreBundle.php @@ -250,6 +250,9 @@ public function build(ContainerBuilder $container) { ->addArgument(new Reference('plugin.manager.entity')) ->addTag('paramconverter'); + $container->register('reverse_proxy_subscriber', 'Drupal\Core\EventSubscriber\ReverseProxySubscriber') + ->addArgument(new Reference('settings')) + ->addTag('event_subscriber'); $container->register('router_processor_subscriber', 'Drupal\Core\EventSubscriber\RouteProcessorSubscriber') ->addArgument(new Reference('content_negotiation')) ->addTag('event_subscriber'); @@ -305,7 +308,8 @@ public function build(ContainerBuilder $container) { ->register('transliteration', 'Drupal\Core\Transliteration\PHPTransliteration'); $container->register('flood', 'Drupal\Core\Flood\DatabaseBackend') - ->addArgument(new Reference('database')); + ->addArgument(new Reference('database')) + ->addArgument(new Reference('request')); $container->register('plugin.manager.condition', 'Drupal\Core\Condition\ConditionManager'); diff --git a/core/lib/Drupal/Core/EventSubscriber/ReverseProxySubscriber.php b/core/lib/Drupal/Core/EventSubscriber/ReverseProxySubscriber.php new file mode 100644 index 0000000..926d36d --- /dev/null +++ b/core/lib/Drupal/Core/EventSubscriber/ReverseProxySubscriber.php @@ -0,0 +1,63 @@ +settings = $settings; + } + + /** + * Passes reverse proxy settings to current request. + * + * @param \Symfony\Component\HttpKernel\Event\GetResponseEvent $event + * The Event to process. + */ + public function onKernelRequestReverseProxyCheck(GetResponseEvent $event) { + $request = $event->getRequest(); + if ($this->settings->get('reverse_proxy', 0)) { + $reverse_proxy_header = $this->settings->get('reverse_proxy_header', 'HTTP_X_FORWARDED_FOR'); + $request->setTrustedHeaderName($request::HEADER_CLIENT_IP, $reverse_proxy_header); + $reverse_proxy_addresses = $this->settings->get('reverse_proxy_addresses', array()); + $request->setTrustedProxies($reverse_proxy_addresses); + } + } + + /** + * Registers the methods in this class that should be listeners. + * + * @return array + * An array of event listener definitions. + */ + static function getSubscribedEvents() { + $events[KernelEvents::REQUEST][] = array('onKernelRequestReverseProxyCheck', 10); + return $events; + } +} diff --git a/core/lib/Drupal/Core/Flood/DatabaseBackend.php b/core/lib/Drupal/Core/Flood/DatabaseBackend.php index a7b05f4..0bc30d1 100644 --- a/core/lib/Drupal/Core/Flood/DatabaseBackend.php +++ b/core/lib/Drupal/Core/Flood/DatabaseBackend.php @@ -7,6 +7,7 @@ namespace Drupal\Core\Flood; +use Symfony\Component\HttpFoundation\Request; use Drupal\Core\Database\Connection; /** @@ -22,14 +23,24 @@ class DatabaseBackend implements FloodInterface { protected $connection; /** + * A request object. + * + * @var \Symfony\Component\HttpFoundation\Request + */ + protected $request; + + /** * Construct the DatabaseBackend. * * @param \Drupal\Core\Database\Connection $connection * The database connection which will be used to store the flood event * information. + * @param \Symfony\Component\HttpFoundation\Request $request + * The HttpRequest object representing the current request. */ - public function __construct(Connection $connection) { + public function __construct(Connection $connection, Request $request) { $this->connection = $connection; + $this->request = $request; } /** @@ -37,7 +48,7 @@ public function __construct(Connection $connection) { */ public function register($name, $window = 3600, $identifier = NULL) { if (!isset($identifier)) { - $identifier = ip_address(); + $identifier = $this->request->getClientIp(); } $this->connection->insert('flood') ->fields(array( @@ -54,7 +65,7 @@ public function register($name, $window = 3600, $identifier = NULL) { */ public function clear($name, $identifier = NULL) { if (!isset($identifier)) { - $identifier = ip_address(); + $identifier = $this->request->getClientIp(); } $this->connection->delete('flood') ->condition('event', $name) @@ -67,7 +78,7 @@ public function clear($name, $identifier = NULL) { */ public function isAllowed($name, $threshold, $window = 3600, $identifier = NULL) { if (!isset($identifier)) { - $identifier = ip_address(); + $identifier = $this->request->getClientIp(); } $number = $this->connection->select('flood', 'f') ->condition('event', $name) diff --git a/core/lib/Drupal/Core/Flood/MemoryBackend.php b/core/lib/Drupal/Core/Flood/MemoryBackend.php index 63b19da..13ab55a 100644 --- a/core/lib/Drupal/Core/Flood/MemoryBackend.php +++ b/core/lib/Drupal/Core/Flood/MemoryBackend.php @@ -7,22 +7,41 @@ namespace Drupal\Core\Flood; +use Symfony\Component\HttpFoundation\Request; + /** * Defines the memory flood backend. This is used for testing. */ class MemoryBackend implements FloodInterface { /** + * A request object. + * + * @var \Symfony\Component\HttpFoundation\Request + */ + protected $request; + + /** * An array holding flood events, keyed by event name and identifier. */ protected $events = array(); /** + * Construct the MemoryBackend. + * + * @param \Symfony\Component\HttpFoundation\Request $request + * The HttpRequest object representing the current request. + */ + public function __construct(Request $request) { + $this->request = $request; + } + + /** * Implements Drupal\Core\Flood\FloodInterface::register(). */ public function register($name, $window = 3600, $identifier = NULL) { if (!isset($identifier)) { - $identifier = ip_address(); + $identifier = $this->request->getClientIP(); } // We can't use REQUEST_TIME here, because that would not guarantee // uniqueness. @@ -35,7 +54,7 @@ public function register($name, $window = 3600, $identifier = NULL) { */ public function clear($name, $identifier = NULL) { if (!isset($identifier)) { - $identifier = ip_address(); + $identifier = $this->request->getClientIP(); } unset($this->events[$name][$identifier]); } @@ -45,7 +64,7 @@ public function clear($name, $identifier = NULL) { */ public function isAllowed($name, $threshold, $window = 3600, $identifier = NULL) { if (!isset($identifier)) { - $identifier = ip_address(); + $identifier = $this->request->getClientIP(); } $limit = microtime(true) - $window; $number = count(array_filter($this->events[$name][$identifier], function ($timestamp) use ($limit) { diff --git a/core/modules/action/tests/action_loop_test/action_loop_test.module b/core/modules/action/tests/action_loop_test/action_loop_test.module index 8c3b98d..dfc5226 100644 --- a/core/modules/action/tests/action_loop_test/action_loop_test.module +++ b/core/modules/action/tests/action_loop_test/action_loop_test.module @@ -69,7 +69,7 @@ function watchdog_skip_semaphore($type, $message, $variables = array(), $severit 'uid' => isset($user->uid) ? $user->uid : 0, 'request_uri' => $base_root . request_uri(), 'referer' => $_SERVER['HTTP_REFERER'], - 'ip' => ip_address(), + 'ip' => Drupal::service('request')->getClientIP(), 'timestamp' => REQUEST_TIME, ); diff --git a/core/modules/ban/ban.admin.inc b/core/modules/ban/ban.admin.inc index 0ea23fc..6def75e 100644 --- a/core/modules/ban/ban.admin.inc +++ b/core/modules/ban/ban.admin.inc @@ -85,7 +85,7 @@ function ban_ip_form_validate($form, &$form_state) { if (db_query("SELECT * FROM {ban_ip} WHERE ip = :ip", array(':ip' => $ip))->fetchField()) { form_set_error('ip', t('This IP address is already banned.')); } - elseif ($ip == ip_address()) { + elseif ($ip == Drupal::service('request')->getClientIP()) { form_set_error('ip', t('You may not ban your own IP address.')); } elseif (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_RES_RANGE) == FALSE) { diff --git a/core/modules/ban/lib/Drupal/ban/EventSubscriber/BanSubscriber.php b/core/modules/ban/lib/Drupal/ban/EventSubscriber/BanSubscriber.php index 7dc141c..8e24181 100644 --- a/core/modules/ban/lib/Drupal/ban/EventSubscriber/BanSubscriber.php +++ b/core/modules/ban/lib/Drupal/ban/EventSubscriber/BanSubscriber.php @@ -44,7 +44,7 @@ public function __construct(BanIpManager $manager) { */ public function onKernelRequestBannedIpCheck(GetResponseEvent $event) { // @todo convert this to Request::getClientIP(). - $ip = ip_address(); + $ip = $event->getRequest()->getClientIp(); if ($this->manager->isDenied($ip)) { $response = new Response('Sorry, ' . check_plain($ip) . ' has been banned.', 403); $event->setResponse($response); diff --git a/core/modules/ban/lib/Drupal/ban/Tests/IpAddressBlockingTest.php b/core/modules/ban/lib/Drupal/ban/Tests/IpAddressBlockingTest.php index 4b40572..b058f11 100644 --- a/core/modules/ban/lib/Drupal/ban/Tests/IpAddressBlockingTest.php +++ b/core/modules/ban/lib/Drupal/ban/Tests/IpAddressBlockingTest.php @@ -78,7 +78,7 @@ function testIPAddressValidation() { // manually. // TODO: On some systems this test fails due to a bug/inconsistency in cURL. // $edit = array(); - // $edit['ip'] = ip_address(); + // $edit['ip'] = \Drupal::service('request')->getClientIP(); // $this->drupalPost('admin/config/people/ban', $edit, t('Save')); // $this->assertText(t('You may not ban your own IP address.')); } diff --git a/core/modules/comment/lib/Drupal/comment/CommentStorageController.php b/core/modules/comment/lib/Drupal/comment/CommentStorageController.php index 77e441f..aa7df09 100644 --- a/core/modules/comment/lib/Drupal/comment/CommentStorageController.php +++ b/core/modules/comment/lib/Drupal/comment/CommentStorageController.php @@ -153,7 +153,7 @@ protected function preSave(EntityInterface $comment) { } // Add the values which aren't passed into the function. $comment->thread->value = $thread; - $comment->hostname->value = ip_address(); + $comment->hostname->value = \Drupal::service('request')->getClientIP(); } } diff --git a/core/modules/comment/lib/Drupal/comment/Tests/CommentLinksTest.php b/core/modules/comment/lib/Drupal/comment/Tests/CommentLinksTest.php index 7907464..1edce50 100644 --- a/core/modules/comment/lib/Drupal/comment/Tests/CommentLinksTest.php +++ b/core/modules/comment/lib/Drupal/comment/Tests/CommentLinksTest.php @@ -145,7 +145,7 @@ function setEnvironment(array $info) { 'uid' => 0, 'status' => COMMENT_PUBLISHED, 'subject' => $this->randomName(), - 'hostname' => ip_address(), + 'hostname' => \Drupal::service('request')->getClientIP(), 'langcode' => LANGUAGE_NOT_SPECIFIED, 'comment_body' => array(LANGUAGE_NOT_SPECIFIED => array($this->randomName())), )); diff --git a/core/modules/comment/lib/Drupal/comment/Tests/CommentNewIndicatorTest.php b/core/modules/comment/lib/Drupal/comment/Tests/CommentNewIndicatorTest.php index 8009f88..6d36525 100644 --- a/core/modules/comment/lib/Drupal/comment/Tests/CommentNewIndicatorTest.php +++ b/core/modules/comment/lib/Drupal/comment/Tests/CommentNewIndicatorTest.php @@ -52,7 +52,7 @@ public function testCommentNewCommentsIndicator() { 'uid' => $this->loggedInUser->uid, 'status' => COMMENT_PUBLISHED, 'subject' => $this->randomName(), - 'hostname' => ip_address(), + 'hostname' => \Drupal::service('request')->getClientIP(), 'langcode' => LANGUAGE_NOT_SPECIFIED, 'comment_body' => array(LANGUAGE_NOT_SPECIFIED => array($this->randomName())), )); diff --git a/core/modules/dblog/lib/Drupal/dblog/Tests/DBLogTest.php b/core/modules/dblog/lib/Drupal/dblog/Tests/DBLogTest.php index 1769605..17df6a1 100644 --- a/core/modules/dblog/lib/Drupal/dblog/Tests/DBLogTest.php +++ b/core/modules/dblog/lib/Drupal/dblog/Tests/DBLogTest.php @@ -137,7 +137,7 @@ private function generateLogEntries($count, $type = 'custom', $severity = WATCHD 'uid' => isset($this->big_user->uid) ? $this->big_user->uid : 0, 'request_uri' => $base_root . request_uri(), 'referer' => $_SERVER['HTTP_REFERER'], - 'ip' => ip_address(), + 'ip' => \Drupal::service('request')->getClientIP(), 'timestamp' => REQUEST_TIME, ); $message = 'Log entry added to test the dblog row limit. Entry #'; @@ -424,7 +424,7 @@ protected function testDBLogAddAndClear() { 'uid' => isset($this->big_user->uid) ? $this->big_user->uid : 0, 'request_uri' => $base_root . request_uri(), 'referer' => $_SERVER['HTTP_REFERER'], - 'ip' => ip_address(), + 'ip' => \Drupal::service('request')->getClientIP(), 'timestamp' => REQUEST_TIME, ); // Add a watchdog entry. diff --git a/core/modules/openid/openid.module b/core/modules/openid/openid.module index 6d31124..b23473b 100644 --- a/core/modules/openid/openid.module +++ b/core/modules/openid/openid.module @@ -1066,7 +1066,7 @@ function openid_verify_assertion_nonce($service, $response) { return TRUE; } else { - watchdog('openid', 'Nonce replay attempt blocked from @ip, nonce: @nonce.', array('@ip' => ip_address(), '@nonce' => $response['openid.response_nonce']), WATCHDOG_CRITICAL); + watchdog('openid', 'Nonce replay attempt blocked from @ip, nonce: @nonce.', array('@ip' => Drupal::service('request')->getClientIP(), '@nonce' => $response['openid.response_nonce']), WATCHDOG_CRITICAL); return FALSE; } } diff --git a/core/modules/simpletest/lib/Drupal/simpletest/TestBase.php b/core/modules/simpletest/lib/Drupal/simpletest/TestBase.php index 35af531..f0d8c08 100644 --- a/core/modules/simpletest/lib/Drupal/simpletest/TestBase.php +++ b/core/modules/simpletest/lib/Drupal/simpletest/TestBase.php @@ -7,6 +7,7 @@ namespace Drupal\simpletest; +use Symfony\Component\HttpFoundation\Request; use Drupal\Core\Database\Database; use Drupal\Component\Utility\Settings; use Drupal\Core\DependencyInjection\ContainerBuilder; @@ -907,6 +908,9 @@ protected function prepareEnvironment() { unset($GLOBALS['theme_key']); unset($GLOBALS['theme']); + // Add request info. + $this->container->set('request', Request::createFromGlobals()); + // Log fatal errors. ini_set('log_errors', 1); ini_set('error_log', $this->public_files_directory . '/error.log'); @@ -968,6 +972,8 @@ protected function rebuildContainer() { // DrupalKernel replaces the container in drupal_container() with a // different object, so we need to replace the instance on this test class. $this->container = drupal_container(); + // Add request info to the container. + $this->container->set('request', Request::createFromGlobals()); } /** diff --git a/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php b/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php index 9e8b097..f2e5be2 100644 --- a/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php +++ b/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php @@ -775,6 +775,10 @@ protected function setUp() { ), ); + // drupal_anonymous_user() should have a symfony request object available + // so build a testing kernel. + $this->rebuildContainer(); + // Replace the global $user session with an anonymous user to resemble a // regular installation. $user = drupal_anonymous_user(); diff --git a/core/modules/system/lib/Drupal/system/Tests/Bootstrap/IpAddressTest.php b/core/modules/system/lib/Drupal/system/Tests/Bootstrap/IpAddressTest.php deleted file mode 100644 index c062aa6..0000000 --- a/core/modules/system/lib/Drupal/system/Tests/Bootstrap/IpAddressTest.php +++ /dev/null @@ -1,111 +0,0 @@ - 'IP address and HTTP_HOST test', - 'description' => 'Get the IP address from the current visitor from the server variables, check hostname validation.', - 'group' => 'Bootstrap' - ); - } - - function setUp() { - $this->oldserver = $_SERVER; - - $this->remote_ip = '127.0.0.1'; - $this->proxy_ip = '127.0.0.2'; - $this->proxy2_ip = '127.0.0.3'; - $this->forwarded_ip = '127.0.0.4'; - $this->cluster_ip = '127.0.0.5'; - $this->untrusted_ip = '0.0.0.0'; - - drupal_static_reset('ip_address'); - - $_SERVER['REMOTE_ADDR'] = $this->remote_ip; - unset($_SERVER['HTTP_X_FORWARDED_FOR']); - unset($_SERVER['HTTP_X_CLUSTER_CLIENT_IP']); - - parent::setUp(); - } - - function tearDown() { - $_SERVER = $this->oldserver; - drupal_static_reset('ip_address'); - parent::tearDown(); - } - - /** - * Tests IP address and hostname. - */ - function testIPAddressHost() { - // Test the normal IP address. - $this->assertTrue( - ip_address() == $this->remote_ip, - 'Got remote IP address.' - ); - - // Proxy forwarding on but no proxy addresses defined. - $this->settingsSet('reverse_proxy', 1); - $this->assertTrue( - ip_address() == $this->remote_ip, - 'Proxy forwarding without trusted proxies got remote IP address.' - ); - - // Proxy forwarding on and proxy address not trusted. - $this->settingsSet('reverse_proxy_addresses', array($this->proxy_ip, $this->proxy2_ip)); - drupal_static_reset('ip_address'); - $_SERVER['REMOTE_ADDR'] = $this->untrusted_ip; - $this->assertTrue( - ip_address() == $this->untrusted_ip, - 'Proxy forwarding with untrusted proxy got remote IP address.' - ); - - // Proxy forwarding on and proxy address trusted. - $_SERVER['REMOTE_ADDR'] = $this->proxy_ip; - $_SERVER['HTTP_X_FORWARDED_FOR'] = $this->forwarded_ip; - drupal_static_reset('ip_address'); - $this->assertTrue( - ip_address() == $this->forwarded_ip, - 'Proxy forwarding with trusted proxy got forwarded IP address.' - ); - - // Multi-tier architecture with comma separated values in header. - $_SERVER['REMOTE_ADDR'] = $this->proxy_ip; - $_SERVER['HTTP_X_FORWARDED_FOR'] = implode(', ', array($this->untrusted_ip, $this->forwarded_ip, $this->proxy2_ip)); - drupal_static_reset('ip_address'); - $this->assertTrue( - ip_address() == $this->forwarded_ip, - 'Proxy forwarding with trusted 2-tier proxy got forwarded IP address.' - ); - - // Custom client-IP header. - $this->settingsSet('reverse_proxy_header', 'HTTP_X_CLUSTER_CLIENT_IP'); - $_SERVER['HTTP_X_CLUSTER_CLIENT_IP'] = $this->cluster_ip; - drupal_static_reset('ip_address'); - $this->assertTrue( - ip_address() == $this->cluster_ip, - 'Cluster environment got cluster client IP.' - ); - - // Verifies that drupal_valid_http_host() prevents invalid characters. - $this->assertFalse(drupal_valid_http_host('security/.drupal.org:80'), 'HTTP_HOST with / is invalid'); - $this->assertFalse(drupal_valid_http_host('security\\.drupal.org:80'), 'HTTP_HOST with \\ is invalid'); - $this->assertFalse(drupal_valid_http_host('security<.drupal.org:80'), 'HTTP_HOST with < is invalid'); - $this->assertFalse(drupal_valid_http_host('security..drupal.org:80'), 'HTTP_HOST with .. is invalid'); - // IPv6 loopback address - $this->assertTrue(drupal_valid_http_host('[::1]:80'), 'HTTP_HOST containing IPv6 loopback is valid'); - } -} diff --git a/core/modules/system/lib/Drupal/system/Tests/System/FloodTest.php b/core/modules/system/lib/Drupal/system/Tests/System/FloodTest.php index 6af396b..b3e8662 100644 --- a/core/modules/system/lib/Drupal/system/Tests/System/FloodTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/System/FloodTest.php @@ -55,7 +55,7 @@ function testMemoryBackend() { $window_expired = -1; $name = 'flood_test_cleanup'; - $flood = new \Drupal\Core\Flood\MemoryBackend; + $flood = new \Drupal\Core\Flood\MemoryBackend($this->kernel->getContainer()->get('request')); // Register expired event. $flood->register($name, $window_expired); // Verify event is not allowed. diff --git a/core/modules/user/user.module b/core/modules/user/user.module index bdf5862..200ac00 100644 --- a/core/modules/user/user.module +++ b/core/modules/user/user.module @@ -1324,7 +1324,7 @@ function user_login_authenticate_validate($form, &$form_state) { // The default identifier is a combination of uid and IP address. This // is less secure but more resistant to denial-of-service attacks that // could lock out all users with public user names. - $identifier = $account->uid . '-' . ip_address(); + $identifier = $account->uid . '-' . Drupal::service('request')->getClientIP(); } $form_state['flood_control_user_identifier'] = $identifier; diff --git a/core/update.php b/core/update.php index d24d6e0..a9c3908 100644 --- a/core/update.php +++ b/core/update.php @@ -338,6 +338,8 @@ function update_access_allowed() { $module_handler->setModuleList($module_filenames); $module_handler->reload(); drupal_container()->get('kernel')->updateModules($module_filenames, $module_filenames); + // Kernel has been rebuilt, retrieve the new one and set request info back. + Drupal::getContainer()->set('request', Request::createFromGlobals()); return user_access('administer software updates'); } catch (\Exception $e) {