Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: replace request ip with Cf-Connecting-Ip value #284

Merged
merged 1 commit into from
Mar 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions config/laravelcloudflare.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,17 @@

'enabled' => (bool) env('LARAVEL_CLOUDFLARE_ENABLED', true),

/*
|--------------------------------------------------------------------------
| Replace current remote addr with Cf-Connecting-Ip header
|--------------------------------------------------------------------------
|
| This replace the request ip with the value of the Cf-Connecting-Ip header.
|
*/

'replace_ip' => (bool) env('LARAVEL_CLOUDFLARE_REPLACE_IP', true),

/*
|--------------------------------------------------------------------------
| Name of the cache to store values of the proxies
Expand Down
15 changes: 3 additions & 12 deletions src/CloudflareProxies.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,6 @@ class CloudflareProxies

/**
* Create a new instance of CloudflareProxies.
*
* @param \Illuminate\Contracts\Config\Repository $config
* @param \Illuminate\Http\Client\Factory $http
*/
public function __construct(Repository $config, HttpClient $http)
{
Expand All @@ -44,11 +41,8 @@ public function __construct(Repository $config, HttpClient $http)

/**
* Retrieve Cloudflare proxies list.
*
* @param int $type
* @return array
*/
public function load($type = self::IP_VERSION_ANY): array
public function load(int $type = self::IP_VERSION_ANY): array
{
$proxies = [];

Expand All @@ -66,14 +60,11 @@ public function load($type = self::IP_VERSION_ANY): array

/**
* Retrieve requested proxy list by name.
*
* @param string $name requet name
* @return array
*/
protected function retrieve($name): array
protected function retrieve(string $name): array
{
try {
$url = Str::of($this->config->get('laravelcloudflare.url'))->finish('/').$name;
$url = Str::of($this->config->get('laravelcloudflare.url', 'https://www.cloudflare.com/'))->finish('/').$name;

$response = Http::get($url)->throw();
} catch (\Exception $e) {
Expand Down
6 changes: 1 addition & 5 deletions src/Commands/Reload.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,8 @@ class Reload extends Command

/**
* Execute the console command.
*
* @param \Illuminate\Contracts\Cache\Factory $cache
* @param \Illuminate\Contracts\Config\Repository $config
* @return void
*/
public function handle(Cache $cache, Config $config)
public function handle(Cache $cache, Config $config): void
{
if (! (bool) $config->get('laravelcloudflare.enabled')) {
return;
Expand Down
6 changes: 1 addition & 5 deletions src/Commands/View.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,8 @@ class View extends Command

/**
* Execute the console command.
*
* @param \Illuminate\Contracts\Cache\Factory $cache
* @param \Illuminate\Contracts\Config\Repository $config
* @return void
*/
public function handle(Cache $cache, Config $config)
public function handle(Cache $cache, Config $config): void
{
$proxies = $cache->store()->get($config->get('laravelcloudflare.cache'), []);

Expand Down
4 changes: 1 addition & 3 deletions src/Facades/CloudflareProxies.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,8 @@ class CloudflareProxies extends Facade
{
/**
* Get the registered name of the component.
*
* @return string
*/
protected static function getFacadeAccessor()
protected static function getFacadeAccessor(): string
{
return \Monicahq\Cloudflare\CloudflareProxies::class;
}
Expand Down
33 changes: 26 additions & 7 deletions src/Http/Middleware/TrustProxies.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Monicahq\Cloudflare\Http\Middleware;

use Closure;
use Illuminate\Http\Middleware\TrustProxies as Middleware;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
Expand All @@ -11,12 +12,33 @@
class TrustProxies extends Middleware
{
/**
* Sets the trusted proxies on the request.
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @return void
* @throws \Symfony\Component\HttpKernel\Exception\HttpException
*/
public function handle(Request $request, Closure $next)
{
if (Config::get('laravelcloudflare.replace_ip') === true) {
$this->setRemoteAddr($request);
}

return parent::handle($request, $next);
}

/**
* Set RemoteAddr server value using Cf-Connecting-Ip header.
*/
protected function setTrustedProxyIpAddresses(Request $request)
protected function setRemoteAddr(Request $request): void
{
if (($ip = $request->header('Cf-Connecting-Ip')) !== null) {
$request->server->set('REMOTE_ADDR', $ip);
}
}

/**
* Sets the trusted proxies on the request.
*/
protected function setTrustedProxyIpAddresses(Request $request): void
{
if ((bool) Config::get('laravelcloudflare.enabled')) {
$this->setTrustedProxyCloudflare($request);
Expand All @@ -27,9 +49,6 @@ protected function setTrustedProxyIpAddresses(Request $request)

/**
* Sets the trusted proxies on the request to the value of Cloudflare ips.
*
* @param \Illuminate\Http\Request $request
* @return void
*/
protected function setTrustedProxyCloudflare(Request $request): void
{
Expand Down
8 changes: 2 additions & 6 deletions src/LaravelCloudflare.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Monicahq\Cloudflare;

use Closure;
use Monicahq\Cloudflare\Facades\CloudflareProxies;

final class LaravelCloudflare
Expand All @@ -15,8 +16,6 @@ final class LaravelCloudflare

/**
* Get the proxies addresses.
*
* @return array
*/
public static function getProxies(): array
{
Expand All @@ -29,11 +28,8 @@ public static function getProxies(): array

/**
* Set a callback that should be used when getting the proxies addresses.
*
* @param \Closure $callback
* @return void
*/
public static function getProxiesUsing($callback): void
public static function getProxiesUsing(?Closure $callback): void
{
static::$getProxiesCallback = $callback;
}
Expand Down
12 changes: 3 additions & 9 deletions src/TrustedProxyServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,16 @@ class TrustedProxyServiceProvider extends ServiceProvider
{
/**
* Bootstrap any package services.
*
* @return void
*/
public function boot()
public function boot(): void
{
$this->registerPublishing();
}

/**
* Register the package's publishable resources.
*
* @return void
*/
private function registerPublishing()
private function registerPublishing(): void
{
if ($this->app->runningInConsole()) {
$this->publishes([
Expand All @@ -32,10 +28,8 @@ private function registerPublishing()

/**
* Register any package services.
*
* @return void
*/
public function register()
public function register(): void
{
$this->mergeConfigFrom(
__DIR__.'/../config/laravelcloudflare.php', 'laravelcloudflare'
Expand Down
13 changes: 13 additions & 0 deletions tests/Unit/Http/Middleware/TrustProxiesTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Route;
use Monicahq\Cloudflare\Http\Middleware\TrustProxies;
use Monicahq\Cloudflare\LaravelCloudflare;
use Monicahq\Cloudflare\Tests\FeatureTestCase;
Expand Down Expand Up @@ -78,4 +79,16 @@ public function it_deactivates_middleware()
$this->assertEquals([], $proxies);
$this->assertFalse(Cache::has('cloudflare.proxies'));
}

/** @test */
public function it_sets_remote_addr()
{
$request = new Request();
$request->server->set('REMOTE_ADDR', '127.0.0.1');
$request->headers->set('Cf-Connecting-Ip', '127.0.1.1');

$this->app->make(TrustProxies::class)->handle($request, fn () => null);

$this->assertEquals('127.0.1.1', $request->ip());
}
}