Passed
Push — master ( 6a5936...88a431 )
by Mihail
12:09
created

GzipMiddleware   A

Complexity

Total Complexity 8

Size/Duplication

Total Lines 41
Duplicated Lines 0 %

Test Coverage

Coverage 20.83%

Importance

Changes 0
Metric Value
eloc 23
dl 0
loc 41
ccs 5
cts 24
cp 0.2083
rs 10
c 0
b 0
f 0
wmc 8

2 Methods

Rating   Name   Duplication   Size   Complexity  
A isAcceptable() 0 12 4
A process() 0 21 4
1
<?php
2
3
namespace Koded\Framework\Middleware;
4
5
use Psr\Http\Message\{ResponseInterface, ServerRequestInterface};
6
use Psr\Http\Server\{MiddlewareInterface, RequestHandlerInterface};
7
use function gzencode;
8
use function Koded\Http\create_stream;
9
use function str_contains;
10
11
class GzipMiddleware implements MiddlewareInterface
12
{
13
    private const ACCEPT_ENCODING = 'Accept-Encoding';
14
    private const CONTENT_ENCODING = 'Content-Encoding';
15
16 3
    public function process(
17
        ServerRequestInterface $request,
18
        RequestHandlerInterface $handler): ResponseInterface
19
    {
20 3
        $response = $handler->handle($request);
21 1
        if ($response->hasHeader(self::CONTENT_ENCODING)) {
22
            return $response;
23
        }
24 1
        if (!$response->getBody()->getSize()) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $response->getBody()->getSize() of type integer|null is loosely compared to false; this is ambiguous if the integer can be 0. You might want to explicitly use === null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
25 1
            return $response;
26
        }
27
        if (false === $this->isAcceptable($request->getHeaderLine(self::ACCEPT_ENCODING))) {
28
            return $response;
29
        }
30
        $response->getBody()->rewind();
31
        return $response
32
            ->withHeader(self::CONTENT_ENCODING, 'gzip')
33
            ->withAddedHeader('Vary', self::ACCEPT_ENCODING)
34
            ->withBody(create_stream(
35
                gzencode($response->getBody()->getContents(), 7),
36
                $response->getBody()->getMetadata('mode')
0 ignored issues
show
Bug introduced by
It seems like $response->getBody()->getMetadata('mode') can also be of type array and null; however, parameter $mode of Koded\Http\create_stream() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

36
                /** @scrutinizer ignore-type */ $response->getBody()->getMetadata('mode')
Loading history...
37
            ));
38
    }
39
40
    private function isAcceptable(string $encoding): bool
41
    {
42
        if (empty($encoding)) {
43
            return false;
44
        }
45
        if (str_contains($encoding, 'gzip')) {
46
            return true;
47
        }
48
        if (str_contains($encoding, '*')) {
49
            return true;
50
        }
51
        return false;
52
    }
53
}
54