Skip to content

Commit

Permalink
Initial version.
Browse files Browse the repository at this point in the history
  • Loading branch information
cj-clx committed Mar 11, 2016
1 parent 6ce8e15 commit d072ed2
Show file tree
Hide file tree
Showing 6 changed files with 176 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,5 @@ nytprof.out
*.o
*.bs
/_eumm/

/vendor/
20 changes: 20 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"name": "cxj/http-client-info",
"description": "Provide information about client making HTTP request.",
"type": "library",
"license": "MIT",
"authors": [
{
"name": "Chris Johnson",
"email": "cxjohnson@gmail.com"
}
],

"autoload": {
"psr-4": {
"Cxj\\Http\\": "src/"
}
},

"require": {}
}
4 changes: 4 additions & 0 deletions phpunit.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?php
error_reporting(E_ALL);

require_once('vendor/autoload.php');
10 changes: 10 additions & 0 deletions phpunit.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<phpunit colors="true" bootstrap="./phpunit.php">
<testsuites>
<testsuite>
<directory>./tests</directory>
</testsuite>
</testsuites>
<php>
<env name="APP_HOME" value="./tests"/>
</php>
</phpunit>
107 changes: 107 additions & 0 deletions src/ClientInfo.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
<?php
/**
* Retrieve information about web browser (client).
*
* @package Cxj\Http
* @author Chris Johnson <cxjohnson@gmail.com>
* @copyright 2016, Chris Johnson.
* @license MIT
*/

namespace Cxj\Http;

class ClientInfo
{
public function __construct()
{}

/**
* Attempts to return the IPv4 address of the client browser making
* this request.
*
* @return mixed|string - the IPv4 address or false if unable to determine.
*/
public function getIpV4Address()
{
$address = $this->extractAddress(FILTER_FLAG_IPV4);

return $address;
}

/**
* Attempts to return the IPv6 address of the client browser making
* this request.
*
* @return bool|string - the IPv6 address or false if unable to determine.
*/
public function getIpV6Address()
{
$address = $this->extractAddress(FILTER_FLAG_IPV6);

return $address;
}

/**
* @param $ipVersion
*
* @internal param array $headers
* @return bool|mixed
*/
protected function extractAddress($ipVersion)
{
$headers = $this->getHeaders();

// Get forwarded address if it exists. There are two possible headers
// which may contain it, X-Forwarded-For or HTTP_X_FORWARDED_FOR.

if (array_key_exists('X-Forwarded-For', $headers)
&& filter_var(
$headers['X-Forwarded-For'],
FILTER_VALIDATE_IP,
$ipVersion
)
) {
$address = $headers['X-Forwarded-For'];
}
elseif (array_key_exists('HTTP_X_FORWARDED_FOR', $headers)
&& filter_var(
$headers['HTTP_X_FORWARDED_FOR'],
FILTER_VALIDATE_IP,
$ipVersion
)
) {
$address = $headers['HTTP_X_FORWARDED_FOR'];
}
// No forwarded address found, it should be in REMOTE_ADDR.
else {
if (isset($_SERVER['REMOTE_ADDR'])) {
$address = filter_var(
$_SERVER['REMOTE_ADDR'],
FILTER_VALIDATE_IP,
$ipVersion
);
}
else {
$address = false;
}
}

return $address;
}

/**
* @return array HTTP headers.
*/
protected function getHeaders()
{
// Get headers if we can or else use the SERVER global.
if (function_exists('apache_request_headers')) {
$headers = apache_request_headers();
}
else {
$headers = $_SERVER;
}

return $headers;
}
}
33 changes: 33 additions & 0 deletions tests/ClientInfoTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php
/**
* PHPUnit tests for Cxj\Http\ClientInfo.
*
* @package cxj/http-client-info
* @author Chris Johnson <cxjohnson@gmail.com>
* @copyright 2016, Chris Johnson
* @license MIT
*/

namespace Cxj\Http;

/**
* Class ClientInfoTest
* @package Cxj\Http
*/
class ClientInfoTest extends \PHPUnit_Framework_TestCase
{
public function testConstructor()
{
$classname = 'Cxj\Http\ClientInfo';

// Get mock, without the constructor being called
$mock = $this->getMockBuilder($classname)
->disableOriginalConstructor()
->getMockForAbstractClass();

// now call the constructor
$reflectedClass = new \ReflectionClass($classname);
$constructor = $reflectedClass->getConstructor();
$constructor->invoke($mock, array());
}
}

0 comments on commit d072ed2

Please sign in to comment.