Skip to content

Commit

Permalink
Merge pull request #39 from ipinfo/soban/ip-selection-handler
Browse files Browse the repository at this point in the history
 Add optional IP selection handler
  • Loading branch information
UmanShahzad authored Jul 18, 2022
2 parents ae0b575 + 29f5990 commit c32ff47
Show file tree
Hide file tree
Showing 5 changed files with 120 additions and 2 deletions.
47 changes: 46 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ Default cache TTL and maximum size can be changed by setting values in the `$set

#### Using a different cache

It is possible to use a custom cache by creating a child class of the [CacheInterface](https://github.com/ipinfo/php/blob/master/src/cache/Interface.php) class and setting the the `cache` config value in `\config\services.php`. FYI this is known as [the Strategy Pattern](https://sourcemaking.com/design_patterns/strategy).
It is possible to use a custom cache by creating a child class of the [CacheInterface](https://github.com/ipinfo/php/blob/master/src/cache/CacheInterface.php) class and setting the the `cache` config value in `\config\services.php`. FYI this is known as [the Strategy Pattern](https://sourcemaking.com/design_patterns/strategy).

```php
'ipinfo' => [
Expand All @@ -141,6 +141,51 @@ It is possible to use a custom cache by creating a child class of the [CacheInte
],
```

### IP Selection Mechanism

By default, the IP from the incoming request is used.

Since the desired IP by your system may be in other locations, the IP selection mechanism is configurable and some alternative built-in options are available.

#### Using built-in ip selectors

##### DefaultIPSelector

A [DefaultIPSelector](https://github.com/ipinfo/php/blob/master/src/iphandler/DefaultIPSelector.php) is used by default if no IP selector is provided. It returns the source IP from the incoming request.

This selector can be set explicitly by setting the `ip_selector` config value in `\config\services.php`.

```php
'ipinfo' => [
'ip_selector' => new DefaultIPSelector(),
],
```

##### OriginatingIPSelector

A [OriginatingIPSelector](https://github.com/ipinfo/php/blob/master/src/iphandler/OriginatingIPSelector.php) selects an IP address by trying to extract it from the `X-Forwarded-For` header. This is not always the most reliable unless your proxy setup allows you to trust it. It will default to the source IP on the request if the header doesn't exist.

This selector can be set by setting the `ip_selector` config value in `\config\services.php`.

```php
'ipinfo' => [
'ip_selector' => new OriginatingIPSelector(),
],
```

#### Using a custom IP selector

In case a custom IP selector is required, you may implement the [IPHandlerInterface](https://github.com/ipinfo/php/blob/master/src/iphandler/IPHandlerInterface.php) interface and set the `ip_selector` config value in `\config\services.php`.

For example:

```php
'ipinfo' => [
...
'ip_selector' => new CustomIPSelector(),
],
```

### Internationalization

When looking up an IP address, the response object includes a `$request->ipinfo->country_name` property which includes the country name based on American English. It is possible to return the country name in other languages by telling the library to read from a custom file. To define a custom file, add the following to your app's `\config\services.php` file and replace `{{countries}}` with your own file path.
Expand Down
20 changes: 20 additions & 0 deletions src/iphandler/DefaultIPSelector.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

namespace ipinfo\ipinfolaravel\iphandler;

/**
* Implementation of the IPHandlerInterface used as default option. Retrieve IP from request.
*/
class DefaultIPSelector implements IPHandlerInterface
{

/**
* Selects default IP address from request.
* @param \Illuminate\Http\Request $request
* @return string IP address.
*/
public function getIP($request)
{
return $request->ip();
}
}
17 changes: 17 additions & 0 deletions src/iphandler/IPHandlerInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

namespace ipinfo\ipinfolaravel\iphandler;

/**
* Interface for handling the mechanism of IP retrieval.
*/
interface IPHandlerInterface
{

/**
* Get IP address.
* @param \Illuminate\Http\Request $request
* @return string IP address.
*/
public function getIP($request);
}
28 changes: 28 additions & 0 deletions src/iphandler/OriginatingIPSelector.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

namespace ipinfo\ipinfolaravel\iphandler;

/**
* Selects originating client IP from the request.
*/
class OriginatingIPSelector implements IPHandlerInterface
{

/**
* Selects originating client IP from request.
* @param \Illuminate\Http\Request $request
* @return string IP address.
*/
public function getIP($request)
{
$xForwardedFor = $request->headers->get('x-forwarded-for');
if (empty($xForwardedFor)) {
$ip = $request->ip();
} else {
$ips = explode(',', $xForwardedFor);
// trim as officially the space comes after each comma separator
$ip = trim($ips[0]);
}
return $ip;
}
}
10 changes: 9 additions & 1 deletion src/ipinfolaravel.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use Closure;
use ipinfo\ipinfo\IPinfo as IPinfoClient;
use ipinfo\ipinfolaravel\DefaultCache;
use ipinfo\ipinfolaravel\iphandler\DefaultIPSelector;

class ipinfolaravel
{
Expand All @@ -26,6 +27,12 @@ class ipinfolaravel
*/
public $filter = null;

/**
* Provides ip.
* @var ipinfo\ipinfolaravel\iphandler\IPHandlerInterface
*/
public $ip_selector = null;

const CACHE_MAXSIZE = 4096;
const CACHE_TTL = 60 * 24;

Expand All @@ -43,7 +50,7 @@ public function handle($request, Closure $next)
$details = null;
} else {
try {
$details = $this->ipinfo->getDetails($request->ip());
$details = $this->ipinfo->getDetails($this->ip_selector->getIP($request));
} catch (\Exception $e) {
$details = null;

Expand All @@ -70,6 +77,7 @@ public function configure()
$this->access_token = config('services.ipinfo.access_token', null);
$this->filter = config('services.ipinfo.filter', [$this, 'defaultFilter']);
$this->no_except = config('services.ipinfo.no_except', false);
$this->ip_selector = config('services.ipinfo.ip_selector', new DefaultIPSelector());

if ($custom_countries = config('services.ipinfo.countries_file', null)) {
$this->settings['countries_file'] = $custom_countries;
Expand Down

0 comments on commit c32ff47

Please sign in to comment.