summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDries Buytaert2008-06-26 11:29:20 (GMT)
committerDries Buytaert2008-06-26 11:29:20 (GMT)
commitdf4ebc0135163025be3d0531a78586002c084033 (patch)
treee0c60dbe678e7aa77b7723e6c259c3c4dc5bbd3a
parentdf8dcc79b1a6bd47778df977056be0db6b3d58af (diff)
- Patch #258397 by R.Muilwijk and myself: IP address detection improvements. Added support for clusters and wrote various IP address related tests.
-rw-r--r--includes/bootstrap.inc21
-rw-r--r--includes/bootstrap.test83
2 files changed, 99 insertions, 5 deletions
diff --git a/includes/bootstrap.inc b/includes/bootstrap.inc
index dda7848..6aca6d5 100644
--- a/includes/bootstrap.inc
+++ b/includes/bootstrap.inc
@@ -1160,16 +1160,20 @@ function language_default($property = NULL) {
/**
* 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.
+ * instead of $_SERVER['REMOTE_ADDR'], which would be the IP address of
+ * the proxy server, and not the client's. If Drupal is run in a cluster
+ * we use the X-Cluster-Client-Ip header instead.
*
+ * @param $reset
+ * Reset the current IP address saved in static.
* @return
- * IP address of client machine, adjusted for reverse proxy.
+ * IP address of client machine, adjusted for reverse proxy and/or cluster
+ * environments.
*/
-function ip_address() {
+function ip_address($reset = false) {
static $ip_address = NULL;
- if (!isset($ip_address)) {
+ if (!isset($ip_address) || $reset) {
$ip_address = $_SERVER['REMOTE_ADDR'];
if (variable_get('reverse_proxy', 0) && array_key_exists('HTTP_X_FORWARDED_FOR', $_SERVER)) {
// If an array of known reverse proxy IPs is provided, then trust
@@ -1181,6 +1185,13 @@ function ip_address() {
$ip_address = array_pop(explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']));
}
}
+
+ // When Drupal is run in a cluster environment, REMOTE_ADDR contains the IP
+ // address of a server in the cluster, while the IP address of the client is
+ // stored in HTTP_X_CLUSTER_CLIENT_IP.
+ if (array_key_exists('HTTP_X_CLUSTER_CLIENT_IP', $_SERVER)) {
+ $ip_address = $_SERVER['HTTP_X_CLUSTER_CLIENT_IP'];
+ }
}
return $ip_address;
diff --git a/includes/bootstrap.test b/includes/bootstrap.test
new file mode 100644
index 0000000..beb94ed
--- /dev/null
+++ b/includes/bootstrap.test
@@ -0,0 +1,83 @@
+<?php
+
+class BootstrapIPAddressTestCase extends DrupalWebTestCase {
+
+ /**
+ * Implementation of getInfo().
+ */
+ function getInfo() {
+ return array(
+ 'name' => t('IP address test'),
+ 'description' => t('Get the IP address from the current visitor from the server variables.'),
+ 'group' => t('Bootstrap')
+ );
+ }
+
+ /**
+ * Implementation of setUp().
+ */
+ function setUp() {
+ $this->oldserver = $_SERVER;
+
+ $this->remote_ip = '127.0.0.1';
+ $this->proxy_ip = '127.0.0.2';
+ $this->forwarded_ip = '127.0.0.3';
+ $this->cluster_ip = '127.0.0.4';
+ $this->untrusted_ip = '0.0.0.0';
+
+ $_SERVER['REMOTE_ADDR'] = $this->remote_ip;
+ unset($_SERVER['HTTP_X_FORWARDED_FOR']);
+ unset($_SERVER['HTTP_X_CLUSTER_CLIENT_IP']);
+
+ parent::setUp();
+ }
+
+ /**
+ * Implementation of tearDown().
+ */
+ function tearDown() {
+ $_SERVER = $this->oldserver;
+ parent::tearDown();
+ }
+
+ /**
+ * testIPAddress
+ */
+ function testIPAddress() {
+ // Test the normal IP address.
+ $this->assertTrue(
+ ip_address(true) == $this->remote_ip,
+ t('Got remote IP address')
+ );
+
+ // Proxy forwarding on but no proxy addresses defined.
+ variable_set('reverse_proxy', 1);
+ $this->assertTrue(
+ ip_address(true) == $this->remote_ip,
+ t('Proxy forwarding without trusted proxies got remote IP address')
+ );
+
+ // Proxy forwarding on and proxy address not trusted.
+ variable_set('reverse_proxy_addresses', array($this->proxy_ip));
+ $_SERVER['REMOTE_ADDR'] = $this->untrusted_ip;
+ $this->assertTrue(
+ ip_address(true) == $this->untrusted_ip,
+ t('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;
+ $this->assertTrue(
+ ip_address(true) == $this->forwarded_ip,
+ t('Proxy forwarding with trusted proxy got forwarded IP address')
+ );
+
+ // Cluster environment.
+ $_SERVER['HTTP_X_CLUSTER_CLIENT_IP'] = $this->cluster_ip;
+ $this->assertTrue(
+ ip_address(true) == $this->cluster_ip,
+ t('Cluster environment got cluster client IP')
+ );
+ }
+}