Skip to content

Commit cd77610

Browse files
authored
Bugfixes with blacklist (#65)
* Bugfixes with blacklist * typo
1 parent d80a1b1 commit cd77610

File tree

2 files changed

+57
-37
lines changed

2 files changed

+57
-37
lines changed

spec/CachePluginSpec.php

+53-34
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
use Psr\Http\Message\RequestInterface;
1313
use Psr\Http\Message\ResponseInterface;
1414
use Psr\Http\Message\StreamInterface;
15+
use Psr\Http\Message\UriInterface;
1516

1617
class CachePluginSpec extends ObjectBehavior
1718
{
@@ -33,15 +34,16 @@ function it_is_a_plugin()
3334
$this->shouldImplement('Http\Client\Common\Plugin');
3435
}
3536

36-
function it_caches_responses(CacheItemPoolInterface $pool, CacheItemInterface $item, RequestInterface $request, ResponseInterface $response, StreamInterface $stream)
37+
function it_caches_responses(CacheItemPoolInterface $pool, CacheItemInterface $item, RequestInterface $request, UriInterface $uri, ResponseInterface $response, StreamInterface $stream)
3738
{
3839
$httpBody = 'body';
3940
$stream->__toString()->willReturn($httpBody);
4041
$stream->isSeekable()->willReturn(true);
4142
$stream->rewind()->shouldBeCalled();
4243

4344
$request->getMethod()->willReturn('GET');
44-
$request->getUri()->willReturn('/');
45+
$request->getUri()->willReturn($uri);
46+
$uri->__toString()->willReturn('https://example.com/');
4547
$request->getBody()->shouldBeCalled();
4648

4749
$response->getStatusCode()->willReturn(200);
@@ -50,7 +52,7 @@ function it_caches_responses(CacheItemPoolInterface $pool, CacheItemInterface $i
5052
$response->getHeader('Expires')->willReturn([])->shouldBeCalled();
5153
$response->getHeader('ETag')->willReturn([])->shouldBeCalled();
5254

53-
$pool->getItem('d20f64acc6e70b6079845f2fe357732929550ae1')->shouldBeCalled()->willReturn($item);
55+
$pool->getItem(Argument::any())->shouldBeCalled()->willReturn($item);
5456
$item->isHit()->willReturn(false);
5557
$item->expiresAfter(1060)->willReturn($item)->shouldBeCalled();
5658

@@ -70,17 +72,18 @@ function it_caches_responses(CacheItemPoolInterface $pool, CacheItemInterface $i
7072
$this->handleRequest($request, $next, function () {});
7173
}
7274

73-
function it_doesnt_store_failed_responses(CacheItemPoolInterface $pool, CacheItemInterface $item, RequestInterface $request, ResponseInterface $response)
75+
function it_doesnt_store_failed_responses(CacheItemPoolInterface $pool, CacheItemInterface $item, RequestInterface $request, UriInterface $uri, ResponseInterface $response)
7476
{
7577
$request->getMethod()->willReturn('GET');
76-
$request->getUri()->willReturn('/');
78+
$request->getUri()->willReturn($uri);
79+
$uri->__toString()->willReturn('https://example.com/');
7780
$request->getBody()->shouldBeCalled();
7881

7982
$response->getStatusCode()->willReturn(400);
8083
$response->getHeader('Cache-Control')->willReturn([]);
8184
$response->getHeader('Expires')->willReturn([]);
8285

83-
$pool->getItem('d20f64acc6e70b6079845f2fe357732929550ae1')->shouldBeCalled()->willReturn($item);
86+
$pool->getItem(Argument::any())->shouldBeCalled()->willReturn($item);
8487
$item->isHit()->willReturn(false);
8588

8689
$next = function (RequestInterface $request) use ($response) {
@@ -90,10 +93,11 @@ function it_doesnt_store_failed_responses(CacheItemPoolInterface $pool, CacheIte
9093
$this->handleRequest($request, $next, function () {});
9194
}
9295

93-
function it_doesnt_store_post_requests_by_default(CacheItemPoolInterface $pool, CacheItemInterface $item, RequestInterface $request, ResponseInterface $response)
96+
function it_doesnt_store_post_requests_by_default(CacheItemPoolInterface $pool, CacheItemInterface $item, RequestInterface $request, UriInterface $uri, ResponseInterface $response)
9497
{
9598
$request->getMethod()->willReturn('POST');
96-
$request->getUri()->willReturn('/');
99+
$request->getUri()->willReturn($uri);
100+
$uri->__toString()->willReturn('https://example.com/');
97101

98102
$next = function (RequestInterface $request) use ($response) {
99103
return new FulfilledPromise($response->getWrappedObject());
@@ -106,6 +110,7 @@ function it_stores_post_requests_when_allowed(
106110
CacheItemPoolInterface $pool,
107111
CacheItemInterface $item,
108112
RequestInterface $request,
113+
UriInterface $uri,
109114
ResponseInterface $response,
110115
StreamFactory $streamFactory,
111116
StreamInterface $stream
@@ -122,7 +127,8 @@ function it_stores_post_requests_when_allowed(
122127
$stream->rewind()->shouldBeCalled();
123128

124129
$request->getMethod()->willReturn('POST');
125-
$request->getUri()->willReturn('/post');
130+
$request->getUri()->willReturn($uri);
131+
$uri->__toString()->willReturn('https://example.com/');
126132
$request->getBody()->willReturn($stream);
127133

128134
$response->getStatusCode()->willReturn(200);
@@ -131,7 +137,7 @@ function it_stores_post_requests_when_allowed(
131137
$response->getHeader('Expires')->willReturn([])->shouldBeCalled();
132138
$response->getHeader('ETag')->willReturn([])->shouldBeCalled();
133139

134-
$pool->getItem('e4311a9af932c603b400a54efab21b6d7dea7a90')->shouldBeCalled()->willReturn($item);
140+
$pool->getItem(Argument::any())->shouldBeCalled()->willReturn($item);
135141
$item->isHit()->willReturn(false);
136142
$item->expiresAfter(1060)->willReturn($item)->shouldBeCalled();
137143

@@ -171,15 +177,16 @@ function it_does_not_allow_invalid_request_methods(
171177
->during('__construct', [$pool, $streamFactory, ['methods' => ['GET', 'head', 'POST']]]);
172178
}
173179

174-
function it_calculate_age_from_response(CacheItemPoolInterface $pool, CacheItemInterface $item, RequestInterface $request, ResponseInterface $response, StreamInterface $stream)
180+
function it_calculate_age_from_response(CacheItemPoolInterface $pool, CacheItemInterface $item, RequestInterface $request, UriInterface $uri, ResponseInterface $response, StreamInterface $stream)
175181
{
176182
$httpBody = 'body';
177183
$stream->__toString()->willReturn($httpBody);
178184
$stream->isSeekable()->willReturn(true);
179185
$stream->rewind()->shouldBeCalled();
180186

181187
$request->getMethod()->willReturn('GET');
182-
$request->getUri()->willReturn('/');
188+
$request->getUri()->willReturn($uri);
189+
$uri->__toString()->willReturn('https://example.com/');
183190
$request->getBody()->shouldBeCalled();
184191

185192
$response->getStatusCode()->willReturn(200);
@@ -189,7 +196,7 @@ function it_calculate_age_from_response(CacheItemPoolInterface $pool, CacheItemI
189196
$response->getHeader('Expires')->willReturn([]);
190197
$response->getHeader('ETag')->willReturn([]);
191198

192-
$pool->getItem('d20f64acc6e70b6079845f2fe357732929550ae1')->shouldBeCalled()->willReturn($item);
199+
$pool->getItem(Argument::any())->shouldBeCalled()->willReturn($item);
193200
$item->isHit()->willReturn(false);
194201

195202
$item->set($this->getCacheItemMatcher([
@@ -210,7 +217,7 @@ function it_calculate_age_from_response(CacheItemPoolInterface $pool, CacheItemI
210217
$this->handleRequest($request, $next, function () {});
211218
}
212219

213-
function it_saves_etag(CacheItemPoolInterface $pool, CacheItemInterface $item, RequestInterface $request, ResponseInterface $response, StreamInterface $stream)
220+
function it_saves_etag(CacheItemPoolInterface $pool, CacheItemInterface $item, RequestInterface $request, UriInterface $uri, ResponseInterface $response, StreamInterface $stream)
214221
{
215222
$httpBody = 'body';
216223
$stream->__toString()->willReturn($httpBody);
@@ -219,14 +226,15 @@ function it_saves_etag(CacheItemPoolInterface $pool, CacheItemInterface $item, R
219226
$request->getBody()->shouldBeCalled();
220227

221228
$request->getMethod()->willReturn('GET');
222-
$request->getUri()->willReturn('/');
229+
$request->getUri()->willReturn($uri);
230+
$uri->__toString()->willReturn('https://example.com/');
223231
$response->getStatusCode()->willReturn(200);
224232
$response->getBody()->willReturn($stream);
225233
$response->getHeader('Cache-Control')->willReturn([]);
226234
$response->getHeader('Expires')->willReturn([]);
227235
$response->getHeader('ETag')->willReturn(['foo_etag']);
228236

229-
$pool->getItem('d20f64acc6e70b6079845f2fe357732929550ae1')->shouldBeCalled()->willReturn($item);
237+
$pool->getItem(Argument::any())->shouldBeCalled()->willReturn($item);
230238
$item->isHit()->willReturn(false);
231239
$item->expiresAfter(1060)->willReturn($item);
232240

@@ -246,20 +254,21 @@ function it_saves_etag(CacheItemPoolInterface $pool, CacheItemInterface $item, R
246254
$this->handleRequest($request, $next, function () {});
247255
}
248256

249-
function it_adds_etag_and_modfied_since_to_request(CacheItemPoolInterface $pool, CacheItemInterface $item, RequestInterface $request, ResponseInterface $response, StreamInterface $stream)
257+
function it_adds_etag_and_modfied_since_to_request(CacheItemPoolInterface $pool, CacheItemInterface $item, RequestInterface $request, UriInterface $uri, ResponseInterface $response, StreamInterface $stream)
250258
{
251259
$httpBody = 'body';
252260

253261
$request->getMethod()->willReturn('GET');
254-
$request->getUri()->willReturn('/');
262+
$request->getUri()->willReturn($uri);
263+
$uri->__toString()->willReturn('https://example.com/');
255264
$request->getBody()->shouldBeCalled();
256265

257266
$request->withHeader('If-Modified-Since', 'Thursday, 01-Jan-70 01:18:31 GMT')->shouldBeCalled()->willReturn($request);
258267
$request->withHeader('If-None-Match', 'foo_etag')->shouldBeCalled()->willReturn($request);
259268

260269
$response->getStatusCode()->willReturn(304);
261270

262-
$pool->getItem('d20f64acc6e70b6079845f2fe357732929550ae1')->shouldBeCalled()->willReturn($item);
271+
$pool->getItem(Argument::any())->shouldBeCalled()->willReturn($item);
263272
$item->isHit()->willReturn(true, false);
264273
$item->get()->willReturn([
265274
'response' => $response,
@@ -276,15 +285,16 @@ function it_adds_etag_and_modfied_since_to_request(CacheItemPoolInterface $pool,
276285
$this->handleRequest($request, $next, function () {});
277286
}
278287

279-
function it_servces_a_cached_response(CacheItemPoolInterface $pool, CacheItemInterface $item, RequestInterface $request, ResponseInterface $response, StreamInterface $stream, StreamFactory $streamFactory)
288+
function it_servces_a_cached_response(CacheItemPoolInterface $pool, CacheItemInterface $item, RequestInterface $request, UriInterface $uri, ResponseInterface $response, StreamInterface $stream, StreamFactory $streamFactory)
280289
{
281290
$httpBody = 'body';
282291

283292
$request->getMethod()->willReturn('GET');
284-
$request->getUri()->willReturn('/');
293+
$request->getUri()->willReturn($uri);
294+
$uri->__toString()->willReturn('https://example.com/');
285295
$request->getBody()->shouldBeCalled();
286296

287-
$pool->getItem('d20f64acc6e70b6079845f2fe357732929550ae1')->shouldBeCalled()->willReturn($item);
297+
$pool->getItem(Argument::any())->shouldBeCalled()->willReturn($item);
288298
$item->isHit()->willReturn(true);
289299
$item->get()->willReturn([
290300
'response' => $response,
@@ -305,12 +315,13 @@ function it_servces_a_cached_response(CacheItemPoolInterface $pool, CacheItemInt
305315
$this->handleRequest($request, $next, function () {});
306316
}
307317

308-
function it_serves_and_resaved_expired_response(CacheItemPoolInterface $pool, CacheItemInterface $item, RequestInterface $request, ResponseInterface $response, StreamInterface $stream, StreamFactory $streamFactory)
318+
function it_serves_and_resaved_expired_response(CacheItemPoolInterface $pool, CacheItemInterface $item, RequestInterface $request, UriInterface $uri, ResponseInterface $response, StreamInterface $stream, StreamFactory $streamFactory)
309319
{
310320
$httpBody = 'body';
311321

312322
$request->getMethod()->willReturn('GET');
313-
$request->getUri()->willReturn('/');
323+
$request->getUri()->willReturn($uri);
324+
$uri->__toString()->willReturn('https://example.com/');
314325
$request->getBody()->shouldBeCalled();
315326

316327
$request->withHeader(Argument::any(), Argument::any())->willReturn($request);
@@ -323,7 +334,7 @@ function it_serves_and_resaved_expired_response(CacheItemPoolInterface $pool, Ca
323334
// Make sure we add back the body
324335
$response->withBody($stream)->willReturn($response)->shouldBeCalled();
325336

326-
$pool->getItem('d20f64acc6e70b6079845f2fe357732929550ae1')->shouldBeCalled()->willReturn($item);
337+
$pool->getItem(Argument::any())->shouldBeCalled()->willReturn($item);
327338
$item->isHit()->willReturn(true, true);
328339
$item->expiresAfter(1060)->willReturn($item)->shouldBeCalled();
329340
$item->get()->willReturn([
@@ -356,6 +367,7 @@ function it_caches_private_responses_when_allowed(
356367
CacheItemPoolInterface $pool,
357368
CacheItemInterface $item,
358369
RequestInterface $request,
370+
UriInterface $uri,
359371
ResponseInterface $response,
360372
StreamFactory $streamFactory,
361373
StreamInterface $stream
@@ -371,7 +383,8 @@ function it_caches_private_responses_when_allowed(
371383
$stream->rewind()->shouldBeCalled();
372384

373385
$request->getMethod()->willReturn('GET');
374-
$request->getUri()->willReturn('/');
386+
$request->getUri()->willReturn($uri);
387+
$uri->__toString()->willReturn('https://example.com/');
375388
$request->getBody()->shouldBeCalled();
376389

377390
$response->getStatusCode()->willReturn(200);
@@ -380,7 +393,7 @@ function it_caches_private_responses_when_allowed(
380393
$response->getHeader('Expires')->willReturn([])->shouldBeCalled();
381394
$response->getHeader('ETag')->willReturn([])->shouldBeCalled();
382395

383-
$pool->getItem('d20f64acc6e70b6079845f2fe357732929550ae1')->shouldBeCalled()->willReturn($item);
396+
$pool->getItem(Argument::any())->shouldBeCalled()->willReturn($item);
384397
$item->isHit()->willReturn(false);
385398
$item->expiresAfter(1060)->willReturn($item)->shouldBeCalled();
386399

@@ -404,29 +417,31 @@ function it_does_not_store_responses_of_requests_to_blacklisted_paths(
404417
CacheItemPoolInterface $pool,
405418
CacheItemInterface $item,
406419
RequestInterface $request,
420+
UriInterface $uri,
407421
ResponseInterface $response,
408422
StreamFactory $streamFactory,
409423
StreamInterface $stream
410424
) {
411425
$this->beConstructedThrough('clientCache', [$pool, $streamFactory, [
412426
'default_ttl' => 60,
413427
'cache_lifetime' => 1000,
414-
'blacklisted_paths' => ['\/foo']
428+
'blacklisted_paths' => ['@/foo@']
415429
]]);
416430

417431
$httpBody = 'body';
418432
$stream->__toString()->willReturn($httpBody);
419433
$stream->isSeekable()->willReturn(true);
420434

421435
$request->getMethod()->willReturn('GET');
422-
$request->getUri()->willReturn('/foo');
436+
$request->getUri()->willReturn($uri);
437+
$uri->__toString()->willReturn('https://example.com/foo');
423438
$request->getBody()->shouldBeCalled();
424439

425440
$response->getStatusCode()->willReturn(200);
426441
$response->getBody()->willReturn($stream);
427442
$response->getHeader('Cache-Control')->willReturn([])->shouldBeCalled();
428443

429-
$pool->getItem('231392a16d98e1cf631845c79b7d45f40bab08f3')->shouldBeCalled()->willReturn($item);
444+
$pool->getItem(Argument::any())->shouldBeCalled()->willReturn($item);
430445
$item->isHit()->willReturn(false);
431446

432447
$item->set($this->getCacheItemMatcher([
@@ -448,14 +463,15 @@ function it_stores_responses_of_requests_not_in_blacklisted_paths(
448463
CacheItemPoolInterface $pool,
449464
CacheItemInterface $item,
450465
RequestInterface $request,
466+
UriInterface $uri,
451467
ResponseInterface $response,
452468
StreamFactory $streamFactory,
453469
StreamInterface $stream
454470
) {
455471
$this->beConstructedThrough('clientCache', [$pool, $streamFactory, [
456472
'default_ttl' => 60,
457473
'cache_lifetime' => 1000,
458-
'blacklisted_paths' => ['\/foo']
474+
'blacklisted_paths' => ['@/foo@']
459475
]]);
460476

461477
$httpBody = 'body';
@@ -464,7 +480,8 @@ function it_stores_responses_of_requests_not_in_blacklisted_paths(
464480
$stream->rewind()->shouldBeCalled();
465481

466482
$request->getMethod()->willReturn('GET');
467-
$request->getUri()->willReturn('/');
483+
$request->getUri()->willReturn($uri);
484+
$uri->__toString()->willReturn('https://example.com/');
468485
$request->getBody()->shouldBeCalled();
469486

470487
$response->getStatusCode()->willReturn(200);
@@ -473,7 +490,7 @@ function it_stores_responses_of_requests_not_in_blacklisted_paths(
473490
$response->getHeader('Expires')->willReturn([])->shouldBeCalled();
474491
$response->getHeader('ETag')->willReturn([])->shouldBeCalled();
475492

476-
$pool->getItem('d20f64acc6e70b6079845f2fe357732929550ae1')->shouldBeCalled()->willReturn($item);
493+
$pool->getItem(Argument::any())->shouldBeCalled()->willReturn($item);
477494
$item->isHit()->willReturn(false);
478495
$item->expiresAfter(1060)->willReturn($item)->shouldBeCalled();
479496

@@ -498,6 +515,7 @@ function it_can_be_initialized_with_custom_cache_key_generator(
498515
CacheItemInterface $item,
499516
StreamFactory $streamFactory,
500517
RequestInterface $request,
518+
UriInterface $uri,
501519
ResponseInterface $response,
502520
StreamInterface $stream,
503521
SimpleGenerator $generator
@@ -513,7 +531,8 @@ function it_can_be_initialized_with_custom_cache_key_generator(
513531
$streamFactory->createStream(Argument::any())->willReturn($stream);
514532

515533
$request->getMethod()->willReturn('GET');
516-
$request->getUri()->willReturn('/');
534+
$request->getUri()->willReturn($uri);
535+
$uri->__toString()->willReturn('https://example.com/');
517536
$response->withBody(Argument::any())->willReturn($response);
518537

519538
$pool->getItem(Argument::any())->shouldBeCalled()->willReturn($item);

src/CachePlugin.php

+4-3
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ final class CachePlugin implements Plugin
6363
* we have to store the cache for a longer time than the server originally says it is valid for.
6464
* We store a cache item for $cache_lifetime + max age of the response.
6565
* @var array $methods list of request methods which can be cached
66-
* @var array $blacklisted_paths list of regex patterns of paths explicitly not to be cached
66+
* @var array $blacklisted_paths list of regex for URLs explicitly not to be cached
6767
* @var array $respect_response_cache_directives list of cache directives this plugin will respect while caching responses
6868
* @var CacheKeyGenerator $cache_key_generator an object to generate the cache key. Defaults to a new instance of SimpleGenerator
6969
* @var CacheListener[] $cache_listeners an array of objects to act on the response based on the results of the cache check.
@@ -280,8 +280,9 @@ protected function isCacheable(ResponseInterface $response)
280280
*/
281281
private function isCacheableRequest(RequestInterface $request)
282282
{
283-
foreach ($this->config['blacklisted_paths'] as $not_to_cache_path) {
284-
if (1 === preg_match('/'.$not_to_cache_path.'/', $request->getUri())) {
283+
$uri = $request->getUri()->__toString();
284+
foreach ($this->config['blacklisted_paths'] as $regex) {
285+
if (1 === preg_match($regex, $uri)) {
285286
return false;
286287
}
287288
}

0 commit comments

Comments
 (0)