Test Failed
Pull Request — master (#67)
by Daniel
06:31
created

RefererUrlResolver   A

Complexity

Total Complexity 17

Size/Duplication

Total Lines 63
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 30
dl 0
loc 63
rs 10
c 0
b 0
f 0
wmc 17

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
B getUrlPrefix() 0 28 9
A concatPathToUrl() 0 3 1
A getAbsoluteUrl() 0 19 6
1
<?php
2
3
/*
4
 * This file is part of the Silverback API Components Bundle Project
5
 *
6
 * (c) Daniel West <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
declare(strict_types=1);
13
14
namespace Silverback\ApiComponentsBundle\Helper;
15
16
use Silverback\ApiComponentsBundle\Exception\InvalidArgumentException;
17
use Silverback\ApiComponentsBundle\Exception\UnparseableRequestHeaderException;
18
use Symfony\Component\HttpFoundation\RequestStack;
19
20
/**
21
 * @author Daniel West <[email protected]>
22
 */
23
class RefererUrlResolver
24
{
25
    private RequestStack $requestStack;
26
27
    public function __construct(RequestStack $requestStack)
28
    {
29
        $this->requestStack = $requestStack;
30
    }
31
32
    public function getAbsoluteUrl($path): string
33
    {
34
        if (false !== strpos($path, '://') || 0 === strpos($path, '//')) {
35
            return $path;
36
        }
37
38
        $request = $this->requestStack->getMasterRequest();
39
        if (!$request) {
40
            throw new InvalidArgumentException('To generate an absolute URL to the referrer, there must be a valid master request');
41
        }
42
43
        if (null !== ($origin = $request->headers->get('origin', null))) {
0 ignored issues
show
introduced by
The condition null !== $origin = $requ...rs->get('origin', null) is always true.
Loading history...
44
            return $this->concatPathToUrl($origin, $path, 'origin');
45
        }
46
        if (null !== ($referer = $request->headers->get('referer', null))) {
47
            return $this->concatPathToUrl($referer, $path, 'referer');
48
        }
49
50
        throw new UnparseableRequestHeaderException('To generate an absolute URL to the referrer, the request must have a `origin` or `referer` header present');
51
    }
52
53
    private function concatPathToUrl(string $origin, string $path, string $headerName): string
54
    {
55
        return $this->getUrlPrefix($origin, $headerName) . '/' . ltrim($path, '/');
56
    }
57
58
    private function getUrlPrefix(string $url, string $headerName): string
59
    {
60
        $defaults = [
61
            'host' => null,
62
            'scheme' => null,
63
            'port' => null,
64
        ];
65
66
        [
67
            'host' => $host,
68
            'scheme' => $scheme,
69
            'port' => $port
70
        ] = array_merge($defaults, parse_url($url) ?: []);
71
72
        if (null === $host) {
73
            throw new UnparseableRequestHeaderException(sprintf('Could not extract `host` while parsing the `%s` header', $headerName));
74
        }
75
76
        if (null === $scheme) {
77
            throw new UnparseableRequestHeaderException(sprintf('Could not extract `scheme` while parsing the `%s` header', $headerName));
78
        }
79
80
        $url = $scheme . '://' . $host;
81
        if ($port && (('https' === $scheme && 443 !== $port) || ('http' === $scheme && 80 !== $port))) {
82
            $url .= ':' . $port;
83
        }
84
85
        return $url;
86
    }
87
}
88