improved request - getUserHost() & getUserHostAddress

I changed Yii’s CHttpRequest class so it suit my needs

for security reasons ( XSS protection, someone can send malicious code thru the header "host" and you might echo it without notice ), i changed the method getUserHost() to this




	public function getUserHost()

	{

   		return isset($_SERVER['REMOTE_HOST']) ? (preg_match("/^[a-zA-Z0-9\.-]+$/",$_SERVER['REMOTE_HOST'])? $_SERVER['REMOTE_HOST']:null):null;

	}



also my need to get the real ip address even if the user is behind a proxy made me change the method getUserHostAddress() to this




	public function getUserHostAddress()

	{

    	switch(true){

        	case ($ip=getenv("HTTP_X_FORWARDED_FOR")):

            	break;

        	case ($ip=getenv("HTTP_CLIENT_IP")):

            	break;

        	default:

            	$ip=getenv("REMOTE_ADDR")?getenv("REMOTE_ADDR"):'127.0.0.1'; 

    	}

    	if (strpos($ip, ', ')>0) {

        	$ips = explode(', ', $ip);

        	$ip = $ips[0];

    	}

    	return $ip;

	}



i actually use this code, its about 10-20 times faster, but it doesnt work if you on a IIS server:




	public function getUserHostAddress()

	{

    	switch(true){

        	case isset($_SERVER["HTTP_X_FORWARDED_FOR"]):

            	$ip=$_SERVER["HTTP_X_FORWARDED_FOR"];

            	break;

        	case isset($_SERVER["HTTP_CLIENT_IP"]):

            	$ip=$_SERVER["HTTP_CLIENT_IP"];

            	break;

        	default:

            	$ip=$_SERVER["REMOTE_ADDR"]?$_SERVER["REMOTE_ADDR"]:'127.0.0.1'; 

    	}

    	if (strpos($ip, ', ')>0) {

        	$ips = explode(', ', $ip);

        	$ip = $ips[0];

    	}

    	return $ip;

	}



hope this helps someone

You can improve your function by adding $_SERVER["HTTP_X_FORWARDED"], $_SERVER["HTTP_X_CLUSTER_CLIENT_IP"], $_SERVER["HTTP_FORWARDED_FOR"] and $_SERVER["HTTP_FORWARDED"].

The first IP is not always the best choice, because it might be a local adress. You should always check the ip against a function like this to sort out private ip ranges.


function checkIP($ip)

{

        $ip=ip2long($ip);

        if($ip<=50331647) return false; // '0.0.0.0','2.255.255.255' or false

        $private = array (

                array(167772160, 184549375),    // '10.0.0.0','10.255.255.255'

                array(2130706432, 2147483647),  // '127.0.0.0','127.255.255.255'

                array(2851995648, 2852061183),  // '169.254.0.0','169.254.255.255'

                array(2886729728, 2887778303),  // '172.16.0.0','172.31.255.255'

                array(3221225984, 3221226239),  // '192.0.2.0','192.0.2.255'

                array(3232235520, 3232301055),  // '192.168.0.0','192.168.255.255'

                array(4294967040, 4294967295)   // '255.255.255.0','255.255.255.255'

        );

        foreach($private as $p) if($p[0]<=$ip&&$ip<=$p[1]) return false;

        return true;

}

thanks SOliver, nice work!