Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
1 / 1
CRAP
100.00% covered (success)
100.00%
1 / 1
ETagHandler
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
1 / 1
4
100.00% covered (success)
100.00%
1 / 1
 process
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
1 / 1
4
1<?php
2
3declare(strict_types=1);
4
5namespace Engelsystem\Middleware;
6
7use Illuminate\Support\Str;
8use Nyholm\Psr7\Stream;
9use Psr\Http\Message\ResponseInterface;
10use Psr\Http\Message\ServerRequestInterface;
11use Psr\Http\Server\MiddlewareInterface;
12use Psr\Http\Server\RequestHandlerInterface;
13use Symfony\Component\HttpFoundation\Response;
14
15class ETagHandler implements MiddlewareInterface
16{
17    /**
18     * Compare the response ETag to a requested If-None-Match header and send a 304 "not modified" if they match
19     */
20    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
21    {
22        $response = $handler->handle($request);
23
24        $etagMatch = $request->getHeader('If-None-Match');
25        $etag = $response->getHeader('ETag');
26
27        if (
28            !$etagMatch
29            || !$etag
30            || !Str::contains(implode(', ', $etagMatch), trim($etag[0], '"'))
31        ) {
32            return $response;
33        }
34
35        return $response
36            ->withStatus(Response::HTTP_NOT_MODIFIED)
37            ->withBody(Stream::create());
38    }
39}