Completed
Pull Request — master (#125)
by
unknown
05:31
created

BasicNetworkResolver::getRemoteIp()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 4
c 1
b 0
f 0
nc 2
nop 0
dl 0
loc 7
ccs 0
cts 5
cp 0
crap 6
rs 10
1
<?php
2
declare(strict_types=1);
3
4
namespace Yiisoft\Yii\Web\NetworkResolver;
5
6
use Psr\Http\Message\ServerRequestInterface;
7
8
class BasicNetworkResolver implements NetworkResolverInterface
9
{
10
    protected const SCHEME_HTTPS = 'https';
11
12
    /**
13
     * @var ServerRequestInterface|null
14
     */
15
    private $serverRequest;
16
17
    private $protocolHeaders = [];
18
19
    public function getRemoteIp(): string
20
    {
21
        $ip = $this->getServerRequest()->getServerParams()['REMOTE_ADDR'] ?? null;
22
        if ($ip === null) {
23
            throw new \RuntimeException('Remote IP is not available!');
24
        }
25
        return (string)$ip;
26
    }
27
28
    public function getUserIp(): string
29
    {
30
        return $this->getRemoteIp();
31
    }
32
33
    /**
34
     * User's request scheme
35
     */
36 8
    public function getRequestScheme(): string
37
    {
38 8
        $request = $this->getServerRequest();
39 8
        foreach ($this->protocolHeaders as $header => $data) {
40 6
            if (!$request->hasHeader($header)) {
41 1
                continue;
42
            }
43 5
            $headerValue = $request->getHeader($header)[0];
44 5
            if (is_callable($data)) {
45
                return call_user_func($data, $headerValue, $header, $request);
46
            }
47 5
            $headerValue = strtolower($headerValue);
48 5
            foreach ($data as $protocol => $acceptedValues) {
49 5
                if (!in_array($headerValue, $acceptedValues)) {
50 1
                    continue;
51
                }
52 4
                return $protocol;
53
            }
54
        }
55 4
        return $request->getUri()->getScheme();
56
    }
57
58
    /**
59
     * User's connection security
60
     */
61
    public function isSecureConnection(): bool
62
    {
63
        return $this->getRequestScheme() === self::SCHEME_HTTPS;
64
    }
65
66 8
    public function withServerRequest(ServerRequestInterface $serverRequest)
67
    {
68 8
        $new = clone $this;
69 8
        $new->serverRequest = $serverRequest;
70 8
        return $new;
71
    }
72
73
    /**
74
     * @TODO: documentation
75
     * @param callable|array $protocolAndAcceptedValues
76
     * @return static
77
     */
78 6
    public function withNewProtocolHeader(string $header, $protocolAndAcceptedValues)
79
    {
80 6
        $new = clone $this;
81 6
        if (is_callable($protocolAndAcceptedValues)) {
82
            $new->protocolHeaders[$header] = $protocolAndAcceptedValues;
83 6
        } elseif (!is_array($protocolAndAcceptedValues)) {
84
            throw new \RuntimeException('$protocolAndAcceptedValues is not array nor callable!');
85 6
        } elseif (is_array($protocolAndAcceptedValues) && count($protocolAndAcceptedValues) === 0) {
86
            throw new \RuntimeException('$protocolAndAcceptedValues cannot be an empty array!');
87
        }
88 6
        $new->protocolHeaders[$header] = [];
89 6
        foreach ($protocolAndAcceptedValues as $protocol => $acceptedValues) {
90 6
            $new->protocolHeaders[$header][$protocol] = array_map('strtolower', (array)$acceptedValues);
91
        }
92 6
        return $new;
93
    }
94
95
96 8
    protected function getServerRequest(bool $throwIfNull = true): ?ServerRequestInterface
97
    {
98 8
        if ($this->serverRequest === null && $throwIfNull) {
99
            throw new \RuntimeException('The server request object is not set!');
100
        }
101 8
        return $this->serverRequest;
102
    }
103
}
104