Completed
Push — master ( 1b2d0a...89ea1a )
by Oscar
03:00
created

SaveResponse::canSave()   C

Complexity

Conditions 8
Paths 5

Size

Total Lines 22
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
c 3
b 0
f 0
dl 0
loc 22
rs 6.6037
cc 8
eloc 11
nc 5
nop 2
1
<?php
2
3
namespace Psr7Middlewares\Middleware;
4
5
use Psr7Middlewares\Utils;
6
use Psr\Http\Message\RequestInterface;
7
use Psr\Http\Message\ResponseInterface;
8
use Psr\Http\Message\StreamInterface;
9
use RuntimeException;
10
11
/**
12
 * Middleware to save the response into a file.
13
 */
14
class SaveResponse
15
{
16
    use Utils\FileTrait;
17
18
    /**
19
     * Execute the middleware.
20
     *
21
     * @param RequestInterface  $request
22
     * @param ResponseInterface $response
23
     * @param callable          $next
24
     *
25
     * @return ResponseInterface
26
     */
27
    public function __invoke(RequestInterface $request, ResponseInterface $response, callable $next)
28
    {
29
        $response = $next($request, $response);
30
31
        if ($this->canSave($request, $response)) {
32
            $path = $this->getFilename($request);
33
34
            //if it's gz compressed, append .gz
35
            if (strtolower($response->getHeaderLine('Content-Encoding')) === 'gzip') {
36
                $path .= '.gz';
37
            }
38
39
            self::writeStream($response->getBody(), $path);
40
        }
41
42
        return $response;
43
    }
44
45
    /**
46
     * Check whether the response can be saved or not.
47
     * 
48
     * @param RequestInterface  $request
49
     * @param ResponseInterface $response
50
     * 
51
     * @return bool
52
     */
53
    private function canSave(RequestInterface $request, ResponseInterface $response)
54
    {
55
        if ($request->getMethod() !== 'GET') {
56
            return false;
57
        }
58
59
        if ($response->getStatusCode() !== 200) {
60
            return false;
61
        }
62
63
        if (!$this->appendQuery && !empty($request->getUri()->getQuery())) {
64
            return false;
65
        }
66
67
        $cacheControl = $response->getHeaderLine('Cache-Control');
68
69
        if ($cacheControl && (stripos($cacheControl, 'no-cache') !== false || stripos($cacheControl, 'no-store') !== false)) {
70
            return false;
71
        }
72
73
        return true;
74
    }
75
76
    /**
77
     * Write the stream to the given path.
78
     *
79
     * @param StreamInterface $stream
80
     * @param string          $path
81
     */
82
    private static function writeStream(StreamInterface $stream, $path)
83
    {
84
        $dir = dirname($path);
85
86
        if (!is_dir($dir)) {
87
            mkdir($dir, 0777, true);
88
        }
89
90
        $handle = fopen($path, 'wb+');
91
92
        if (false === $handle) {
93
            throw new RuntimeException('Unable to write to designated path');
94
        }
95
96
        $stream->rewind();
97
98
        while (!$stream->eof()) {
99
            fwrite($handle, $stream->read(4096));
100
        }
101
102
        fclose($handle);
103
    }
104
}
105