Skip to content
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
16 changes: 8 additions & 8 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
* text=auto eol=lf

/tests export-ignore
.editorconfig export-ignore
.gitattributes export-ignore
.gitignore export-ignore
.php_cs export-ignore
.travis.yml export-ignore
phpcs.xml.dist export-ignore
phpunit.xml.dist export-ignore
/tests export-ignore
.editorconfig export-ignore
.gitattributes export-ignore
.gitignore export-ignore
.php-cs-fixer.php export-ignore
phpcs.xml.dist export-ignore
phpunit.xml.dist export-ignore
.phpstan.neon export-ignore
47 changes: 22 additions & 25 deletions .github/workflows/main.yaml
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
name: "testing"

on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
push:
branches: [ master ]
pull_request:
branches: [ master ]

jobs:
qa:
Expand All @@ -13,19 +13,19 @@ jobs:

steps:
- name: Checkout
uses: actions/checkout@v2
uses: actions/checkout@v4

- name: Validate composer.json and composer.lock
run: composer validate

- name: Cache Composer packages
id: composer-cache
uses: actions/cache@v2
uses: actions/cache@v4
with:
path: vendor
key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }}
restore-keys: |
${{ runner.os }}-php-
path: vendor
key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }}
restore-keys: |
${{ runner.os }}-php-

- name: Install dependencies
if: steps.composer-cache.outputs.cache-hit != 'true'
Expand All @@ -40,37 +40,34 @@ jobs:

strategy:
matrix:
php:
- 7.2
- 7.3
- 7.4
composer-args: [ "" ]
include:
- php: 8.0
composer-args: --ignore-platform-reqs
fail-fast: false
php:
- 7.2
- 7.3
- 7.4
- 8.0
- 8.1
- 8.2
- 8.3
- 8.4

steps:
- name: Checkout
uses: actions/checkout@v2
uses: actions/checkout@v4

- name: Install PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}

- name: Cache PHP dependencies
uses: actions/cache@v2
uses: actions/cache@v4
with:
path: vendor
key: ${{ runner.os }}-php-${{ matrix.php }}-composer-${{ hashFiles('**/composer.json') }}
restore-keys: ${{ runner.os }}-php-${{ matrix.php }}-composer-

- name: Install dependencies
run: composer install --prefer-dist --no-progress ${{ matrix.composer-args }}
run: composer install --prefer-dist --no-progress

- name: Tests
run: composer test

- name: Tests coverage
run: composer coverage
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@ vendor
composer.lock
coverage
*.cache
.idea
kit
10 changes: 10 additions & 0 deletions .php-cs-fixer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

return My\PhpCsFixerConfig::create()
->setFinder(
PhpCsFixer\Finder::create()
->files()
->name('*.php')
->in(__DIR__.'/src')
->in(__DIR__.'/tests')
);
5 changes: 5 additions & 0 deletions .phpstan.neon
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
parameters:
level: 8
paths:
- src
- tests
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).

## [2.1.0] - 2025-03-21
### Added
- Support for PHP 8.4
-
## [2.0.1] - 2020-12-02
### Added
- Support for PHP 8
Expand Down Expand Up @@ -93,6 +97,7 @@ First version
[#13]: https://github.com/middlewares/client-ip/issues/13
[#14]: https://github.com/middlewares/client-ip/issues/14

[2.1.0]: https://github.com/middlewares/client-ip/compare/v2.0.1...v2.1.0
[2.0.1]: https://github.com/middlewares/client-ip/compare/v2.0.0...v2.0.1
[2.0.0]: https://github.com/middlewares/client-ip/compare/v1.3.0...v2.0.0
[1.3.0]: https://github.com/middlewares/client-ip/compare/v1.2.0...v1.3.0
Expand Down
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
The MIT License (MIT)

Copyright (c) 2019
Copyright (c) 2019-2025

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
18 changes: 9 additions & 9 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,16 @@
},
"require": {
"php": "^7.2 || ^8.0",
"psr/http-server-middleware": "^1.0"
"psr/http-server-middleware": "^1"
},
"require-dev": {
"phpunit/phpunit": "^8|^9",
"laminas/laminas-diactoros": "^2.2",
"friendsofphp/php-cs-fixer": "^2.0",
"squizlabs/php_codesniffer": "^3.0",
"oscarotero/php-cs-fixer-config": "^1.0",
"middlewares/utils": "^3.1",
"phpstan/phpstan": "^0.12"
"phpunit/phpunit": "^8 || ^9",
"laminas/laminas-diactoros": "^2 || ^3",
"friendsofphp/php-cs-fixer": "^3",
"squizlabs/php_codesniffer": "^3",
"oscarotero/php-cs-fixer-config": "^2",
"middlewares/utils": "^2 || ^3 || ^4",
"phpstan/phpstan": "^1 || ^2"
},
"autoload": {
"psr-4": {
Expand All @@ -46,4 +46,4 @@
"coverage": "phpunit --coverage-text",
"coverage-html": "phpunit --coverage-html=coverage"
}
}
}
16 changes: 16 additions & 0 deletions phpcs.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?xml version="1.0"?>
<ruleset name="Middlewares coding standard">
<description>Middlewares coding standard</description>

<!-- display progress -->
<arg value="p"/>
<arg name="report" value="full"/>
<arg name="colors"/>

<!-- coding standard -->
<rule ref="PSR2"/>

<!-- Paths to check -->
<file>src</file>
<file>tests</file>
</ruleset>
33 changes: 33 additions & 0 deletions phpunit.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit bootstrap="vendor/autoload.php"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
backupGlobals="false"
backupStaticAttributes="false"
beStrictAboutOutputDuringTests="true"
beStrictAboutTestsThatDoNotTestAnything="true"
beStrictAboutTodoAnnotatedTests="true"
colors="true"
verbose="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false"
failOnWarning="true">
<testsuites>
<testsuite name="ClientIp test suite">
<directory>tests</directory>
</testsuite>
</testsuites>

<filter>
<whitelist addUncoveredFilesFromWhitelist="true" processUncoveredFilesFromWhitelist="true">
<directory>./src</directory>
<exclude>
<directory>./tests</directory>
<directory>./vendor</directory>
</exclude>
</whitelist>
</filter>
</phpunit>
10 changes: 7 additions & 3 deletions src/ClientIp.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,20 @@ class ClientIp implements MiddlewareInterface
private $attribute = 'client-ip';

/**
* @var array The trusted proxy headers
* @var string[] The trusted proxy headers
*/
private $proxyHeaders = [];

/**
* @var array The trusted proxy ips
* @var string[] The trusted proxy ips
*/
private $proxyIps = [];

/**
* Configure the proxy.
*
* @param array<string> $ips
* @param array<string> $headers
*/
public function proxy(
array $ips = [],
Expand Down Expand Up @@ -72,7 +75,7 @@ private function getIp(ServerRequestInterface $request): ?string
{
$localIp = $this->getLocalIp($request);

if (!empty($this->proxyIps) && !$this->isInProxiedIps($localIp)) {
if (!empty($this->proxyIps) && !empty($localIp) && !$this->isInProxiedIps($localIp)) {
// Local IP address does not point at a known proxy, do not attempt
// to read proxied IP address.
return $localIp;
Expand All @@ -98,6 +101,7 @@ private function isInProxiedIps(string $ip): bool
return true;
}
}

return false;
}

Expand Down
20 changes: 14 additions & 6 deletions tests/ClientIpTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@

class ClientIpTest extends TestCase
{
/**
* @return array<array<int,string|array<string,string>>>
*/
public function ipsProvider(): array
{
return [
Expand Down Expand Up @@ -38,8 +41,9 @@ public function ipsProvider(): array

/**
* @dataProvider ipsProvider
* @param array<string,string> $headers
*/
public function testClientIpProxy(array $headers, string $ip)
public function testClientIpProxy(array $headers, string $ip): void
{
$request = Factory::createServerRequest('GET', '/', ['REMOTE_ADDR' => '123.123.123.123']);

Expand All @@ -57,7 +61,7 @@ function ($request) {
$this->assertEquals($ip, (string) $response->getBody());
}

public function testClientIpNotProxy()
public function testClientIpNotProxy(): void
{
$request = Factory::createServerRequest('GET', '/', ['REMOTE_ADDR' => '123.123.123.123'])
->withHeader('X-Forwarded', '11.11.11.11');
Expand All @@ -72,7 +76,7 @@ function ($request) {
$this->assertEquals('123.123.123.123', (string) $response->getBody());
}

public function testClientIpV6NotProxy()
public function testClientIpV6NotProxy(): void
{
$request = Factory::createServerRequest('GET', '/', ['REMOTE_ADDR' => '[::1]'])
->withHeader('X-Forwarded', '2001:0db8:85a3:0000:0000:8a2e:0370:7334');
Expand All @@ -87,7 +91,7 @@ function ($request) {
$this->assertEquals('::1', (string) $response->getBody());
}

public function testCustomAttribute()
public function testCustomAttribute(): void
{
$request = Factory::createServerRequest('GET', '/', ['REMOTE_ADDR' => '123.123.123.123']);

Expand All @@ -101,6 +105,9 @@ function ($request) {
$this->assertEquals('123.123.123.123', (string) $response->getBody());
}

/**
* @return array<int,array<int, array<string, string>>>
*/
public function proxyProvider(): array
{
// 4.4.4.4 is IP spoofed by cleint
Expand All @@ -127,8 +134,9 @@ public function proxyProvider(): array

/**
* @dataProvider proxyProvider
* @param array<string,string> $headers
*/
public function testProxyIp(array $headers)
public function testProxyIp(array $headers): void
{
$request = Factory::createServerRequest('GET', '/', ['REMOTE_ADDR' => '1.1.1.1']);

Expand Down Expand Up @@ -173,7 +181,7 @@ function ($request) {
$this->assertEquals('1.1.1.1', (string) $response->getBody());
}

public function testNoRemoteAddr()
public function testNoRemoteAddr(): void
{
$request = Factory::createServerRequest('GET', '/');

Expand Down