ProcessETagHeadersMiddleware   A
last analyzed

Complexity

Total Complexity 7

Size/Duplication

Total Lines 54
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 3

Importance

Changes 0
Metric Value
wmc 7
lcom 0
cbo 3
dl 0
loc 54
rs 10
c 0
b 0
f 0

1 Method

Rating   Name   Duplication   Size   Complexity  
B handle() 0 42 7
1
<?php
2
3
namespace App\Ship\Middlewares\Http;
4
5
use App;
6
use App\Ship\Parents\Middlewares\Middleware;
7
use Closure;
8
use Illuminate\Http\Request;
9
use Symfony\Component\HttpKernel\Exception\PreconditionFailedHttpException;
10
11
/**
12
 * Class ProcessETagHeadersMiddleware
13
 *
14
 * @author  Johannes Schobel <[email protected]>
15
 */
16
class ProcessETagHeadersMiddleware extends Middleware
17
{
18
19
    /**
20
     * @param \Illuminate\Http\Request $request
21
     * @param \Closure                 $next
22
     *
23
     * @return mixed
24
     * @throws PreconditionFailedHttpException
25
     */
26
    public function handle(Request $request, Closure $next)
27
    {
28
        /*
29
         * This middleware will add the "ETag" HTTP Header to a Response. The ETag, in turn, is a
30
         * hash of the content that will be returned. The client may request an endpoint and provide an ETag in the
31
         * "If-None-Match" HTTP Header. If the calculated ETag and submitted ETag matches, the response is manipulated accordingly:
32
         * - the HTTP Status Code is set to 304 (not modified)
33
         * - the body content (i.e., the content that was supposed to be delivered) is removed --> the client receives an empty body
34
         */
35
36
        // the feature is disabled - so skip everything
37
        if (config('apiato.requests.use-etag', false) === false) {
38
            return $next($request);
39
        }
40
41
        // check, if an "if-none-match" header is supplied
42
        if ($request->hasHeader('if-none-match')) {
43
            // check, if the request method is GET or HEAD
44
            if ( ! ($request->method() == 'GET' || $request->method() == 'HEAD')) {
45
                throw new PreconditionFailedHttpException('HTTP Header IF-None-Match is only allowed for GET and HEAD Requests.');
46
            }
47
        }
48
49
        // everything is fine, just call the next middleware. We will process the ETag later on..
50
        $response = $next($request);
51
52
        // now we have processed the request and have a response that is sent back to the client.
53
        // calculate the etag of the content!
54
        $content = $response->getContent();
55
        $etag = md5($content);
56
        $response->headers->set('Etag', $etag);
57
58
        // now, lets check, if the request contains a "if-none-match" http header field
59
        if ($request->hasHeader('if-none-match')) {
60
            // now check, if the if-none-match etag is the same as the calculated etag!
61
            if ($request->header('if-none-match') == $etag) {
62
                $response->setStatusCode(304);
63
            }
64
        }
65
66
        return $response;
67
    }
68
69
}
70