Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
100.00% |
23 / 23 |
|
100.00% |
2 / 2 |
CRAP | |
100.00% |
1 / 1 |
RequestServiceProvider | |
100.00% |
23 / 23 |
|
100.00% |
2 / 2 |
13 | |
100.00% |
1 / 1 |
register | |
100.00% |
12 / 12 |
|
100.00% |
1 / 1 |
5 | |||
createRequestWithoutPrefix | |
100.00% |
11 / 11 |
|
100.00% |
1 / 1 |
7 | |||
setTrustedProxies | n/a |
0 / 0 |
n/a |
0 / 0 |
1 |
1 | <?php |
2 | |
3 | declare(strict_types=1); |
4 | |
5 | namespace Engelsystem\Http; |
6 | |
7 | use Engelsystem\Config\Config; |
8 | use Engelsystem\Container\ServiceProvider; |
9 | use Illuminate\Support\Str; |
10 | use Symfony\Component\HttpFoundation\Request as SymfonyRequest; |
11 | |
12 | class RequestServiceProvider extends ServiceProvider |
13 | { |
14 | protected array $appUrl; |
15 | |
16 | public function register(): void |
17 | { |
18 | /** @var Config $config */ |
19 | $config = $this->app->get('config'); |
20 | $trustedProxies = $config->get('trusted_proxies', []); |
21 | $this->appUrl = parse_url($config->get('url') ?: ''); |
22 | |
23 | if (!is_array($trustedProxies)) { |
24 | $trustedProxies = empty($trustedProxies) ? [] : explode(',', preg_replace('~\s+~', '', $trustedProxies)); |
25 | } |
26 | |
27 | if (!empty($this->appUrl['path'])) { |
28 | Request::setFactory($this->createRequestWithoutPrefix(...)); |
29 | } |
30 | |
31 | /** @var Request $request */ |
32 | $request = $this->app->call([Request::class, 'createFromGlobals']); |
33 | $this->setTrustedProxies($request, $trustedProxies); |
34 | |
35 | $this->app->instance(Request::class, $request); |
36 | $this->app->instance(SymfonyRequest::class, $request); |
37 | $this->app->instance('request', $request); |
38 | } |
39 | |
40 | /** |
41 | * @param array $query GET parameters |
42 | * @param array $request POST parameters |
43 | * @param array $attributes Additional data |
44 | * @param array $cookies Cookies |
45 | * @param array $files Uploaded files |
46 | * @param array $server Server env |
47 | * @param mixed $content Request content |
48 | */ |
49 | public function createRequestWithoutPrefix( |
50 | array $query = [], |
51 | array $request = [], |
52 | array $attributes = [], |
53 | array $cookies = [], |
54 | array $files = [], |
55 | array $server = [], |
56 | mixed $content = null |
57 | ): Request { |
58 | if ( |
59 | !empty($this->appUrl['path']) |
60 | && !empty($server['REQUEST_URI']) |
61 | && Str::startsWith($server['REQUEST_URI'], $this->appUrl['path']) |
62 | ) { |
63 | $requestUri = Str::substr( |
64 | $server['REQUEST_URI'], |
65 | Str::length(rtrim($this->appUrl['path'], '/')) |
66 | ); |
67 | |
68 | // Reset paths which only contain the app path |
69 | if ($requestUri && !Str::startsWith($requestUri, '/')) { |
70 | $requestUri = $server['REQUEST_URI']; |
71 | } |
72 | |
73 | $server['REQUEST_URI'] = $requestUri ?: '/'; |
74 | } |
75 | |
76 | return new Request($query, $request, $attributes, $cookies, $files, $server, $content); |
77 | } |
78 | |
79 | /** |
80 | * Set the trusted Proxies |
81 | * |
82 | * Required for unit tests (static methods can't be mocked) |
83 | * @codeCoverageIgnore |
84 | */ |
85 | protected function setTrustedProxies( |
86 | Request $request, |
87 | array $proxies, |
88 | int $trustedHeadersSet = Request::HEADER_FORWARDED | Request::HEADER_X_FORWARDED_TRAEFIK |
89 | ): void { |
90 | $request->setTrustedProxies($proxies, $trustedHeadersSet); |
91 | } |
92 | } |