Passed
Push — trunk ( 670c99...1ca0ec )
by Christian
11:56 queued 12s
created

VarnishReverseProxyGateway::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 3
c 1
b 0
f 0
nc 1
nop 3
dl 0
loc 5
rs 10
1
<?php declare(strict_types=1);
2
3
namespace Shopware\Storefront\Framework\Cache\ReverseProxy;
4
5
use GuzzleHttp\Client;
6
use GuzzleHttp\Exception\ServerException;
7
use GuzzleHttp\Exception\TransferException;
8
use GuzzleHttp\Pool;
9
use GuzzleHttp\Psr7\Request;
10
use Shopware\Core\Framework\Plugin\Exception\DecorationPatternException;
11
use Symfony\Component\HttpFoundation\Response;
12
13
/**
14
 * @see https://github.com/varnish/varnish-modules/blob/master/src/vmod_xkey.vcc
15
 */
16
class VarnishReverseProxyGateway extends AbstractReverseProxyGateway
17
{
18
    /**
19
     * @var array<string>
20
     */
21
    private array $hosts;
22
23
    private Client $client;
24
25
    private int $concurrency;
26
27
    /**
28
     * @internal
29
     *
30
     * @param string[] $hosts
31
     */
32
    public function __construct(array $hosts, int $concurrency, Client $client)
33
    {
34
        $this->hosts = $hosts;
35
        $this->concurrency = $concurrency;
36
        $this->client = $client;
37
    }
38
39
    public function getDecorated(): AbstractReverseProxyGateway
40
    {
41
        throw new DecorationPatternException(self::class);
42
    }
43
44
    /**
45
     * @param array<string> $tags
46
     *
47
     * @deprecated tag:v6.5.0 - Parameter $response will be required reason:class-hierarchy-change
48
     */
49
    public function tag(array $tags, string $url/*, Response $response */): void
50
    {
51
        /** @var Response|null $response */
52
        $response = \func_num_args() === 3 ? func_get_arg(2) : null;
53
54
        if ($response === null) {
55
            throw new \InvalidArgumentException('Parameter $response is required for VarnishReverseProxyGateway');
56
        }
57
58
        $response->headers->set('xkey', implode(' ', $tags));
59
    }
60
61
    public function invalidate(array $tags): void
62
    {
63
        $list = [];
64
65
        foreach ($this->hosts as $host) {
66
            $list[] = new Request('PURGE', $host, ['xkey' => implode(' ', $tags)]);
67
        }
68
69
        $pool = new Pool($this->client, $list, [
70
            'concurrency' => $this->concurrency,
71
            'rejected' => function (TransferException $reason): void {
72
                if ($reason instanceof ServerException) {
73
                    throw new \RuntimeException(sprintf('BAN request failed to %s failed with error: %s', $reason->getRequest()->getUri()->__toString(), $reason->getMessage()), 0, $reason);
74
                }
75
76
                throw $reason;
77
            },
78
        ]);
79
80
        $pool->promise()->wait();
81
    }
82
83
    public function ban(array $urls): void
84
    {
85
        $list = [];
86
87
        foreach ($urls as $url) {
88
            foreach ($this->hosts as $host) {
89
                $list[] = new Request('PURGE', $host . $url);
90
            }
91
        }
92
93
        $pool = new Pool($this->client, $list, [
94
            'concurrency' => $this->concurrency,
95
            'rejected' => function (TransferException $reason): void {
96
                if ($reason instanceof ServerException) {
97
                    throw new \RuntimeException(sprintf('BAN request failed to %s failed with error: %s', $reason->getRequest()->getUri()->__toString(), $reason->getMessage()), 0, $reason);
98
                }
99
100
                throw $reason;
101
            },
102
        ]);
103
104
        $pool->promise()->wait();
105
    }
106
}
107