Completed
Pull Request — master (#125)
by
unknown
01:57
created

BasicNetworkResolver::withProtocolHeader()   B

Complexity

Conditions 8
Paths 6

Size

Total Lines 22
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 14
CRAP Score 8.3518

Importance

Changes 0
Metric Value
cc 8
eloc 17
c 0
b 0
f 0
nc 6
nop 2
dl 0
loc 22
rs 8.4444
ccs 14
cts 17
cp 0.8235
crap 8.3518
1
<?php
2
3
4
namespace Yiisoft\Yii\Web\Middleware;
5
6
7
use Psr\Http\Message\ResponseInterface;
8
use Psr\Http\Message\ServerRequestInterface;
9
use Psr\Http\Server\MiddlewareInterface;
10
use Psr\Http\Server\RequestHandlerInterface;
11
12
class BasicNetworkResolver implements MiddlewareInterface
13
{
14
    private const DEFAULT_PROTOCOL_AND_ACCEPTABLE_VALUES = [
15
        'http' => ['http'],
16
        'https' => ['https', 'on'],
17
    ];
18
19
    private $protocolHeaders = [];
20
21 14
    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
22
    {
23 14
        $newScheme = null;
24 14
        foreach ($this->protocolHeaders as $header => $data) {
25 10
            if (!$request->hasHeader($header)) {
26 1
                continue;
27
            }
28 9
            $headerValues = $request->getHeader($header);
29 9
            if (is_callable($data)) {
30 2
                $newScheme = call_user_func($data, $headerValues, $header, $request);
31 2
                if ($newScheme === null) {
32 1
                    continue;
33 1
                } elseif (!is_string($newScheme)) {
34
                    throw new \RuntimeException('The scheme is neither string nor null!');
35 1
                } elseif (strlen($newScheme) === 0) {
36
                    throw new \RuntimeException('The scheme cannot be an empty string!');
37
                }
38 1
                break;
39
            }
40 7
            $headerValue = strtolower($headerValues[0]);
41 7
            foreach ($data as $protocol => $acceptedValues) {
42 7
                if (!in_array($headerValue, $acceptedValues)) {
43 2
                    continue;
44
                }
45 6
                $newScheme = $protocol;
46 6
                break 2;
47
            }
48
        }
49 14
        $uri = $request->getUri();
50 14
        if ($newScheme !== null && $newScheme !== $uri->getScheme()) {
51 7
            $request = $request->withUri($uri->withScheme($newScheme));
52
        }
53 14
        return $handler->handle($request);
54
    }
55
56
    /**
57
     * @TODO: documentation
58
     * @param callable|array|null $protocolAndAcceptedValues
59
     * @return static
60
     */
61 12
    public function withProtocolHeader(string $header, $protocolAndAcceptedValues = null)
62
    {
63 12
        $new = clone $this;
64 12
        $header = strtolower($header);
65 12
        if ($protocolAndAcceptedValues === null) {
66 4
            $new->protocolHeaders[$header] = self::DEFAULT_PROTOCOL_AND_ACCEPTABLE_VALUES;
67 8
        } elseif (is_callable($protocolAndAcceptedValues)) {
68 2
            $new->protocolHeaders[$header] = $protocolAndAcceptedValues;
69 6
        } elseif (!is_array($protocolAndAcceptedValues)) {
70
            throw new \RuntimeException('$protocolAndAcceptedValues is not array nor callable!');
71 6
        } elseif (is_array($protocolAndAcceptedValues) && count($protocolAndAcceptedValues) === 0) {
72
            throw new \RuntimeException('$protocolAndAcceptedValues cannot be an empty array!');
73
        } else {
74 6
            $new->protocolHeaders[$header] = [];
75 6
            foreach ($protocolAndAcceptedValues as $protocol => $acceptedValues) {
76 6
                if (!is_string($protocol)) {
77
                    throw new \RuntimeException('The protocol must be type of string!');
78
                }
79 6
                $new->protocolHeaders[$header][$protocol] = array_map('strtolower', (array)$acceptedValues);
80
            }
81
        }
82 12
        return $new;
83
    }
84
85
    /**
86
     * @return static
87
     */
88 2
    public function withoutProtocolHeader(string $header)
89
    {
90 2
        $new = clone $this;
91 2
        unset($new->protocolHeaders[strtolower($header)]);
92 2
        return $new;
93
    }
94
95
    /**
96
     * @return static
97
     */
98 2
    public function withoutProtocolHeaders(?array $headers = null)
99
    {
100 2
        $new = clone $this;
101 2
        if ($headers === null) {
102 1
            $new->protocolHeaders = [];
103
        } else {
104 1
            foreach ($headers as $header) {
105 1
                $new = $new->withoutProtocolHeader($header);
106
            }
107
        }
108 2
        return $new;
109
    }
110
}
111