Passed
Push — master ( 39e14c...f97da3 )
by Caen
03:56 queued 14s
created

Router::shouldRenderSpecial()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 5
nc 1
nop 1
dl 0
loc 9
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Hyde\RealtimeCompiler\Routing;
4
5
use Desilva\Microserve\JsonResponse;
6
use Desilva\Microserve\Request;
7
use Desilva\Microserve\Response;
8
use Hyde\RealtimeCompiler\Actions\AssetFileLocator;
9
use Hyde\RealtimeCompiler\Concerns\SendsErrorResponses;
10
use Hyde\RealtimeCompiler\Models\FileObject;
11
12
class Router
13
{
14
    use SendsErrorResponses;
15
16
    protected Request $request;
17
18
    protected array $virtualRoutes = [
19
        '/ping',
20
    ];
21
22
    public function __construct(Request $request)
23
    {
24
        $this->request = $request;
25
    }
26
27
    public function handle(): Response
28
    {
29
        if ($this->shouldProxy($this->request)) {
30
            return $this->proxyStatic();
31
        }
32
33
        if (in_array($this->request->path, $this->virtualRoutes)) {
34
            if ($this->request->path === '/ping') {
35
                return new JsonResponse(200, 'OK', [
36
                    'server' => 'Hyde/RealtimeCompiler',
37
                ]);
38
            }
39
        }
40
41
        return PageRouter::handle($this->request);
42
    }
43
44
    /**
45
     * If the request is not for a web page, we assume it's
46
     * a static asset, which we instead want to proxy.
47
     */
48
    protected function shouldProxy(Request $request): bool
49
    {
50
        // Always proxy media files. This condition is just to improve performance
51
        // without having to check the file extension.
52
        if (str_starts_with($request->path, '/media/')) {
53
            return true;
54
        }
55
56
        // Get the requested file extension
57
        $extension = pathinfo($request->path)['extension'] ?? null;
58
59
        // If the extension is not set (pretty url), or is .html,
60
        // we assume it's a web page which we need to compile.
61
        if ($extension === null || $extension === 'html') {
62
            return false;
63
        }
64
65
        // The page is not a web page, so we assume it should be proxied.
66
        return true;
67
    }
68
69
    /**
70
     * Proxy a static file or return a 404.
71
     */
72
    protected function proxyStatic(): Response
73
    {
74
        $path = AssetFileLocator::find($this->request->path);
75
76
        if ($path === null) {
77
            return $this->notFound();
78
        }
79
80
        $file = new FileObject($path);
81
82
        return (new Response(200, 'OK', [
83
            'body' => $file->getStream(),
84
        ]))->withHeaders([
85
            'Content-Type'   => $file->getMimeType(),
86
            'Content-Length' => $file->getContentLength(),
87
        ]);
88
    }
89
}
90