Completed
Pull Request — master (#376)
by David
23:49 queued 08:53
created

HttpProxyClient::splitLongHeaderValue()   B

Complexity

Conditions 5
Paths 7

Size

Total Lines 31
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 30

Importance

Changes 0
Metric Value
dl 0
loc 31
ccs 0
cts 0
cp 0
rs 8.439
c 0
b 0
f 0
cc 5
eloc 20
nc 7
nop 3
crap 30
1
<?php
2
3
/*
4
 * This file is part of the FOSHttpCache package.
5
 *
6
 * (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace FOS\HttpCache\ProxyClient;
13
14
use Http\Discovery\MessageFactoryDiscovery;
15
use Http\Message\RequestFactory;
16
use Psr\Http\Message\UriInterface;
17
use Symfony\Component\OptionsResolver\OptionsResolver;
18
19
/**
20
 * Base class for HTTP based caching proxy client.
21
 *
22
 * @author David de Boer <[email protected]>
23
 */
24
abstract class HttpProxyClient implements ProxyClient
25
{
26
    /**
27
     * Dispatcher for invalidation HTTP requests.
28
     *
29
     * @var HttpDispatcher
30
     */
31
    private $httpDispatcher;
32
33
    /**
34
     * @var RequestFactory
35
     */
36
    private $requestFactory;
37
38
    /**
39
     * The options configured in the constructor argument or default values.
40
     *
41
     * @var array The resolved options
42
     */
43
    protected $options;
44
45
    /**
46
     * Constructor.
47
     *
48
     * The base class has no options.
49
     *
50
     * @param HttpDispatcher      $httpDispatcher Helper to send HTTP requests to caching proxy
51
     * @param array               $options        Options for this client
52
     * @param RequestFactory|null $messageFactory Factory for PSR-7 messages. If none supplied,
53
     *                                            a default one is created
54
     */
55 31
    public function __construct(
56
        HttpDispatcher $httpDispatcher,
57
        array $options = [],
58
        RequestFactory $messageFactory = null
59
    ) {
60 31
        $this->httpDispatcher = $httpDispatcher;
61 31
        $this->options = $this->configureOptions()->resolve($options);
62 31
        $this->requestFactory = $messageFactory ?: MessageFactoryDiscovery::find();
63 31
    }
64
65
    /**
66
     * {@inheritdoc}
67
     */
68 21
    public function flush()
69
    {
70 21
        return $this->httpDispatcher->flush();
71
    }
72
73
    /**
74
     * Get options resolver with default settings.
75
     *
76
     * @return OptionsResolver
77
     */
78 31
    protected function configureOptions()
79
    {
80 31
        return new OptionsResolver();
81
    }
82
83
    /**
84
     * Create a request and queue it with the HTTP dispatcher.
85
     *
86
     * @param string              $method
87
     * @param string|UriInterface $url
88
     * @param array               $headers
89
     * @param bool                $validateHost see HttpDispatcher::invalidate
90
     */
91 29
    protected function queueRequest($method, $url, array $headers, $validateHost = true)
92
    {
93 29
        $this->httpDispatcher->invalidate(
94 29
            $this->requestFactory->createRequest($method, $url, $headers),
95 29
            $validateHost
96
        );
97 29
    }
98
99
    /**
100
     * Make sure that the tags are valid.
101
     *
102
     * Reusable function for proxy clients.
103
     * Escapes `,` and `\n` (newline) characters.
104
     *
105
     * @param array $tags The tags to escape
106
     *
107
     * @return array Sane tags
108
     */
109
    protected function escapeTags(array $tags)
110
    {
111 4
        array_walk($tags, function (&$tag) {
112 4
            $tag = str_replace([',', "\n"], '_', $tag);
113 4
        });
114
115 4
        return $tags;
116
    }
117
118
    /**
119
     * Calculate how many tags fit into the header.
120
     *
121
     * This assumes that the tags are separated by one character.
122
     *
123
     * @param string[] $escapedTags
124
     *
125
     * @return int Number of tags per tag invalidation request
126
     */
127
    protected function determineTagsPerHeader($escapedTags)
128
    {
129
        if (mb_strlen(implode(',', $escapedTags)) < $this->options['header_length']) {
130
            return count($escapedTags);
131
        }
132
133
        /*
134
         * estimate the amount of tags to invalidate by dividing the max
135
         * header length by the largest tag (minus 1 for the implode character)
136
         */
137
        $tagsize = max(array_map('mb_strlen', $escapedTags));
138
139
        return floor($this->options['header_length'] / ($tagsize - 1)) ?: 1;
140
    }
141
}
142