useProxy = $useProxy; return $this; } /** * Checks proxy handling setting. * * @return bool Current setting value. */ public function getUseProxy() { return $this->useProxy; } /** * Set list of trusted proxy addresses * * @param array $trustedProxies * @return RemoteAddress */ public function setTrustedProxies(array $trustedProxies) { $this->trustedProxies = $trustedProxies; return $this; } /** * Set the header to introspect for proxy IPs * * @param string $header * @return RemoteAddress */ public function setProxyHeader($header = 'X-Forwarded-For') { $this->proxyHeader = $this->normalizeProxyHeader($header); return $this; } /** * Returns client IP address. * * @return string IP address. */ public function getIpAddress() { $ip = $this->getIpAddressFromProxy(); if ($ip) { return $ip; } // direct IP address if (isset($_SERVER['REMOTE_ADDR'])) { return $_SERVER['REMOTE_ADDR']; } return ''; } /** * Attempt to get the IP address for a proxied client * * @see http://tools.ietf.org/html/draft-ietf-appsawg-http-forwarded-10#section-5.2 * @return false|string */ protected function getIpAddressFromProxy() { if (!$this->useProxy || (isset($_SERVER['REMOTE_ADDR']) && !in_array($_SERVER['REMOTE_ADDR'], $this->trustedProxies)) ) { return false; } $header = $this->proxyHeader; if (!isset($_SERVER[$header]) || empty($_SERVER[$header])) { return false; } // Extract IPs $ips = explode(',', $_SERVER[$header]); // trim, so we can compare against trusted proxies properly $ips = array_map('trim', $ips); // remove trusted proxy IPs $ips = array_diff($ips, $this->trustedProxies); // Any left? if (empty($ips)) { return false; } // Since we've removed any known, trusted proxy servers, the right-most // address represents the first IP we do not know about -- i.e., we do // not know if it is a proxy server, or a client. As such, we treat it // as the originating IP. // @see http://en.wikipedia.org/wiki/X-Forwarded-For $ip = array_pop($ips); return $ip; } /** * Normalize a header string * * Normalizes a header string to a format that is compatible with * $_SERVER * * @param string $header * @return string */ protected function normalizeProxyHeader($header) { $header = strtoupper($header); $header = str_replace('-', '_', $header); if (0 !== strpos($header, 'HTTP_')) { $header = 'HTTP_' . $header; } return $header; } }