Completed
Push — master ( 9a342a...a162ae )
by Andrii
13:06
created

ClientIpMiddleware   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 72
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Importance

Changes 0
Metric Value
wmc 12
lcom 1
cbo 1
dl 0
loc 72
rs 10
c 0
b 0
f 0

7 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A process() 0 4 1
A prepare() 0 17 4
A getIp() 0 4 1
A getNewIp() 0 6 3
A setNewIp() 0 13 1
A getParam() 0 4 1
1
<?php
2
3
namespace hiapi\Core\Http\Psr15\Middleware;
4
5
use hiapi\legacy\lib\deps\cidr;
6
use Psr\Http\Message\ResponseInterface;
7
use Psr\Http\Message\ServerRequestInterface;
8
use Psr\Http\Server\MiddlewareInterface;
9
use Psr\Http\Server\RequestHandlerInterface;
10
11
class ClientIpMiddleware implements MiddlewareInterface
12
{
13
    public const ATTRIBUTE_NAME = 'client-ip';
14
    /**
15
     * @var array
16
     */
17
    private $nets;
18
19
    public $ipAttribute = self::ATTRIBUTE_NAME;
20
21
    public function __construct(array $nets)
22
    {
23
        $this->nets = $nets;
24
    }
25
26
    /**
27
     * @inheritDoc
28
     */
29
    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
30
    {
31
        return $handler->handle($this->prepare($request));
32
    }
33
34
    private function prepare(ServerRequestInterface $request): ServerRequestInterface
35
    {
36
        $oldip = $this->getIp($request);
37
        $request = $request->withAttribute($this->ipAttribute, $oldip);
38
39
        if (!cidr::matchBulk($oldip, $this->nets)) {
40
            return $request;
41
        }
42
43
44
        $newip = $this->getNewIp($request);
45
        if (empty($newip) || $newip == $oldip) {
46
            return $request;
47
        }
48
49
        return $this->setNewIp($request, $newip);
50
    }
51
52
    private function getIp(ServerRequestInterface $request): string
53
    {
54
        return $request->getServerParams()['REMOTE_ADDR'] ?? '';
55
    }
56
57
    private function getNewIp(ServerRequestInterface $request): string
58
    {
59
        $change = $request->getHeaderLine('X-User-Ip') ?: $this->getParam($request, 'auth_ip') ?? null;
60
61
        return filter_var($change, FILTER_VALIDATE_IP) ?: '';
62
    }
63
64
    private function setNewIp(ServerRequestInterface $request, string $ip)
65
    {
66
        /// legacy compatibility
67
        unset($_REQUEST['auth_ip']);
68
        $_SERVER['REMOTE_ADDR'] = $ip;
69
70
        # XXX TODO withServerParams NOT DEFINED !!!
71
        #$params = $request->getServerParams();
72
        #$params['REMOTE_ADDR'] = $ip;
73
        #return $request->withServerParams($params);
74
75
        return $request->withAttribute($this->ipAttribute, $ip);
76
    }
77
78
    public function getParam(ServerRequestInterface $request, string $name): ?string
79
    {
80
        return $request->getParsedBody()[$name] ?? $request->getQueryParams()[$name] ?? null;
81
    }
82
}
83