Passed
Pull Request — master (#134)
by Rustam
07:47
created

Router   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 58
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 30
dl 0
loc 58
ccs 29
cts 29
cp 1
rs 10
c 2
b 0
f 0
wmc 10

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 10 1
A process() 0 23 5
A isSameOrigin() 0 14 4
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Router\Middleware;
6
7
use Psr\Http\Message\ResponseFactoryInterface;
8
use Psr\Http\Message\ResponseInterface;
9
use Psr\Http\Message\ServerRequestInterface;
10
use Psr\Http\Server\MiddlewareInterface;
11
use Psr\Http\Server\RequestHandlerInterface;
12
use Yiisoft\Http\Header;
13
use Yiisoft\Http\Method;
14
use Yiisoft\Http\Status;
15
use Yiisoft\Middleware\Dispatcher\MiddlewareDispatcher;
16
use Yiisoft\Router\CurrentRoute;
17
use Yiisoft\Router\CurrentRouteInterface;
18
use Yiisoft\Router\UrlMatcherInterface;
19
20
final class Router implements MiddlewareInterface
21
{
22
    private UrlMatcherInterface $matcher;
23
    private ResponseFactoryInterface $responseFactory;
24
    private MiddlewareDispatcher $dispatcher;
25
    private CurrentRoute $currentRoute;
26
27 9
    public function __construct(
28
        UrlMatcherInterface $matcher,
29
        ResponseFactoryInterface $responseFactory,
30
        MiddlewareDispatcher $dispatcher,
31
        CurrentRouteInterface $currentRoute
32
    ) {
33 9
        $this->matcher = $matcher;
34 9
        $this->responseFactory = $responseFactory;
35 9
        $this->dispatcher = $dispatcher;
36 9
        $this->currentRoute = $currentRoute;
37 9
    }
38
39 9
    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
40
    {
41 9
        $result = $this->matcher->match($request);
42
43 9
        $this->currentRoute->setUri($request->getUri());
44
45 9
        if ($result->isMethodFailure()) {
46 3
            if ($request->getMethod() === Method::OPTIONS && $this->isSameOrigin($request)) {
47 1
                return $this->responseFactory->createResponse(Status::NO_CONTENT)
48 1
                    ->withHeader('Allow', implode(', ', $result->methods()));
49
            }
50 2
            return $this->responseFactory->createResponse(Status::METHOD_NOT_ALLOWED)
51 2
                ->withHeader('Allow', implode(', ', $result->methods()));
52
        }
53
54 6
        if (!$result->isSuccess()) {
55 1
            return $handler->handle($request);
56
        }
57
58 5
        $this->currentRoute->setRoute($result->route());
59 5
        $this->currentRoute->setArguments($result->arguments());
60
61 5
        return $result->withDispatcher($this->dispatcher)->process($request, $handler);
62
    }
63
64 2
    private function isSameOrigin(ServerRequestInterface $request): bool
65
    {
66 2
        $origin = $request->getHeaderLine(Header::ORIGIN);
67 2
        if ($origin === '') {
68 1
            return true;
69
        }
70
71 1
        $host = $request->getUri()->getHost();
72 1
        $port = $request->getUri()->getPort();
73 1
        if ($port === null) {
74 1
            $port = $request->getUri()->getScheme() === 'https' ? 443 : 80;
75
        }
76
77 1
        return $origin === "{$request->getUri()->getScheme()}://$host:$port";
78
    }
79
}
80