From 52b17774c5ae26363202e66ac77e3d38c0360fed Mon Sep 17 00:00:00 2001 From: Mika Tuupola Date: Fri, 10 Feb 2017 12:01:00 +0700 Subject: [PATCH 01/16] Enable caching of POST requests when requested This is useful for example when using a HTTPlug based SoapClient. php-http/client-common#26 --- CHANGELOG.md | 6 +++++- spec/CachePluginSpec.php | 45 +++++++++++++++++++++++++++++++++++++++- src/CachePlugin.php | 10 ++++++++- 3 files changed, 58 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d6c3ed3..7df0c97 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,11 +1,15 @@ # Change Log +## 1.3.0 - unreleased +### Added + +- New `methods` setting which allows to configure the request methods which can be cached. ## 1.2.0 - 2016-08-16 ### Changed -- The default value for `default_ttl` is changed from `null` to `0`. +- The default value for `default_ttl` is changed from `null` to `0`. ### Fixed diff --git a/spec/CachePluginSpec.php b/spec/CachePluginSpec.php index 97afd55..4d0c895 100644 --- a/spec/CachePluginSpec.php +++ b/spec/CachePluginSpec.php @@ -85,7 +85,7 @@ function it_doesnt_store_failed_responses(CacheItemPoolInterface $pool, CacheIte $this->handleRequest($request, $next, function () {}); } - function it_doesnt_store_post_requests(CacheItemPoolInterface $pool, CacheItemInterface $item, RequestInterface $request, ResponseInterface $response) + function it_doesnt_store_post_requests_by_default(CacheItemPoolInterface $pool, CacheItemInterface $item, RequestInterface $request, ResponseInterface $response) { $request->getMethod()->willReturn('POST'); $request->getUri()->willReturn('/'); @@ -97,6 +97,49 @@ function it_doesnt_store_post_requests(CacheItemPoolInterface $pool, CacheItemIn $this->handleRequest($request, $next, function () {}); } + function it_stores_post_requests_when_allowed(CacheItemPoolInterface $pool, CacheItemInterface $item, RequestInterface $request, ResponseInterface $response, StreamFactory $streamFactory, StreamInterface $stream) + { + $this->beConstructedWith($pool, $streamFactory, [ + 'default_ttl' => 60, + 'cache_lifetime' => 1000, + 'methods' => ['GET', 'HEAD', 'POST'] + ]); + + $httpBody = 'hello=world'; + $stream->__toString()->willReturn($httpBody); + $stream->isSeekable()->willReturn(true); + $stream->rewind()->shouldBeCalled(); + + $request->getMethod()->willReturn('POST'); + $request->getUri()->willReturn('/post'); + $request->getBody()->willReturn($stream); + + $response->getStatusCode()->willReturn(200); + $response->getBody()->willReturn($stream); + $response->getHeader('Cache-Control')->willReturn(array())->shouldBeCalled(); + $response->getHeader('Expires')->willReturn(array())->shouldBeCalled(); + $response->getHeader('ETag')->willReturn(array())->shouldBeCalled(); + + $pool->getItem('e4311a9af932c603b400a54efab21b6d7dea7a90')->shouldBeCalled()->willReturn($item); + $item->isHit()->willReturn(false); + $item->expiresAfter(1060)->willReturn($item)->shouldBeCalled(); + + $item->set($this->getCacheItemMatcher([ + 'response' => $response->getWrappedObject(), + 'body' => $httpBody, + 'expiresAt' => 0, + 'createdAt' => 0, + 'etag' => [] + ]))->willReturn($item)->shouldBeCalled(); + + $pool->save(Argument::any())->shouldBeCalled(); + + $next = function (RequestInterface $request) use ($response) { + return new FulfilledPromise($response->getWrappedObject()); + }; + + $this->handleRequest($request, $next, function () {}); + } function it_calculate_age_from_response(CacheItemPoolInterface $pool, CacheItemInterface $item, RequestInterface $request, ResponseInterface $response, StreamInterface $stream) { diff --git a/src/CachePlugin.php b/src/CachePlugin.php index 5053aad..a54c050 100644 --- a/src/CachePlugin.php +++ b/src/CachePlugin.php @@ -64,7 +64,7 @@ public function handleRequest(RequestInterface $request, callable $next, callabl { $method = strtoupper($request->getMethod()); // if the request not is cachable, move to $next - if ($method !== 'GET' && $method !== 'HEAD') { + if (!in_array($method, $this->config['methods'])) { return $next($request); } @@ -225,6 +225,9 @@ private function getCacheControlDirective(ResponseInterface $response, $name) */ private function createCacheKey(RequestInterface $request) { + if ('POST' === $request->getMethod()) { + return hash($this->config['hash_algo'], $request->getMethod().' '.$request->getUri().' '.$request->getBody()); + } return hash($this->config['hash_algo'], $request->getMethod().' '.$request->getUri()); } @@ -273,12 +276,17 @@ private function configureOptions(OptionsResolver $resolver) 'default_ttl' => 0, 'respect_cache_headers' => true, 'hash_algo' => 'sha1', + 'methods' => ['GET', 'HEAD'], ]); $resolver->setAllowedTypes('cache_lifetime', ['int', 'null']); $resolver->setAllowedTypes('default_ttl', ['int', 'null']); $resolver->setAllowedTypes('respect_cache_headers', 'bool'); + $resolver->setAllowedTypes('methods', 'array'); $resolver->setAllowedValues('hash_algo', hash_algos()); + $resolver->setAllowedValues('methods', function ($value) { + return 0 === count(array_diff($value, ['GET', 'HEAD', 'POST'])); + }); } /** From e0c1c0ea76b38385cce9832d9884154bdddfdacd Mon Sep 17 00:00:00 2001 From: Mika Tuupola Date: Fri, 10 Feb 2017 16:30:11 +0700 Subject: [PATCH 02/16] Make StyleCI happy --- src/CachePlugin.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/CachePlugin.php b/src/CachePlugin.php index a54c050..3a8842a 100644 --- a/src/CachePlugin.php +++ b/src/CachePlugin.php @@ -205,7 +205,6 @@ private function getCacheControlDirective(ResponseInterface $response, $name) $headers = $response->getHeader('Cache-Control'); foreach ($headers as $header) { if (preg_match(sprintf('|%s=?([0-9]+)?|i', $name), $header, $matches)) { - // return the value for $name if it exists if (isset($matches[1])) { return $matches[1]; @@ -228,6 +227,7 @@ private function createCacheKey(RequestInterface $request) if ('POST' === $request->getMethod()) { return hash($this->config['hash_algo'], $request->getMethod().' '.$request->getUri().' '.$request->getBody()); } + return hash($this->config['hash_algo'], $request->getMethod().' '.$request->getUri()); } From 0a3b7c80d53308907b99350688ca994421531ec7 Mon Sep 17 00:00:00 2001 From: Mika Tuupola Date: Sat, 11 Feb 2017 12:58:34 +0700 Subject: [PATCH 03/16] PSR-2 and short array syntax --- spec/CachePluginSpec.php | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/spec/CachePluginSpec.php b/spec/CachePluginSpec.php index 4d0c895..7c897f5 100644 --- a/spec/CachePluginSpec.php +++ b/spec/CachePluginSpec.php @@ -97,8 +97,14 @@ function it_doesnt_store_post_requests_by_default(CacheItemPoolInterface $pool, $this->handleRequest($request, $next, function () {}); } - function it_stores_post_requests_when_allowed(CacheItemPoolInterface $pool, CacheItemInterface $item, RequestInterface $request, ResponseInterface $response, StreamFactory $streamFactory, StreamInterface $stream) - { + function it_stores_post_requests_when_allowed( + CacheItemPoolInterface $pool, + CacheItemInterface $item, + RequestInterface $request, + ResponseInterface $response, + StreamFactory $streamFactory, + StreamInterface $stream + ) { $this->beConstructedWith($pool, $streamFactory, [ 'default_ttl' => 60, 'cache_lifetime' => 1000, @@ -116,9 +122,9 @@ function it_stores_post_requests_when_allowed(CacheItemPoolInterface $pool, Cach $response->getStatusCode()->willReturn(200); $response->getBody()->willReturn($stream); - $response->getHeader('Cache-Control')->willReturn(array())->shouldBeCalled(); - $response->getHeader('Expires')->willReturn(array())->shouldBeCalled(); - $response->getHeader('ETag')->willReturn(array())->shouldBeCalled(); + $response->getHeader('Cache-Control')->willReturn([])->shouldBeCalled(); + $response->getHeader('Expires')->willReturn([])->shouldBeCalled(); + $response->getHeader('ETag')->willReturn([])->shouldBeCalled(); $pool->getItem('e4311a9af932c603b400a54efab21b6d7dea7a90')->shouldBeCalled()->willReturn($item); $item->isHit()->willReturn(false); From 8151701d0a7d50b4545afcd189ef48e01cb3a37a Mon Sep 17 00:00:00 2001 From: Mika Tuupola Date: Mon, 13 Feb 2017 10:59:43 +0700 Subject: [PATCH 04/16] Allow any valid request method as defined by RFC7230 Request method can contain any visible USASCII character except delimiters "(),/:;<=>?@[\]{} https://tools.ietf.org/html/rfc7230#section-3.1.1 https://tools.ietf.org/html/rfc7230#section-3.2.6 --- spec/CachePluginSpec.php | 17 +++++++++++++++++ src/CachePlugin.php | 3 ++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/spec/CachePluginSpec.php b/spec/CachePluginSpec.php index 7c897f5..e845af3 100644 --- a/spec/CachePluginSpec.php +++ b/spec/CachePluginSpec.php @@ -11,6 +11,7 @@ use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\StreamInterface; +use Symfony\Component\OptionsResolver\Exception\InvalidOptionsException; class CachePluginSpec extends ObjectBehavior { @@ -147,6 +148,22 @@ function it_stores_post_requests_when_allowed( $this->handleRequest($request, $next, function () {}); } + function it_does_not_allow_invalid_request_methods( + CacheItemPoolInterface $pool, + CacheItemInterface $item, + RequestInterface $request, + ResponseInterface $response, + StreamFactory $streamFactory, + StreamInterface $stream + ) { + $this + ->shouldThrow(InvalidOptionsException::class) + ->during('__construct', [$pool, $streamFactory, ['methods' => ['GET', 'HEAD', 'POST ']]]); + $this + ->shouldThrow(InvalidOptionsException::class) + ->during('__construct', [$pool, $streamFactory, ['methods' => ['GET', 'HEAD"', 'POST']]]); + } + function it_calculate_age_from_response(CacheItemPoolInterface $pool, CacheItemInterface $item, RequestInterface $request, ResponseInterface $response, StreamInterface $stream) { $httpBody = 'body'; diff --git a/src/CachePlugin.php b/src/CachePlugin.php index 3a8842a..fcf42b2 100644 --- a/src/CachePlugin.php +++ b/src/CachePlugin.php @@ -285,7 +285,8 @@ private function configureOptions(OptionsResolver $resolver) $resolver->setAllowedTypes('methods', 'array'); $resolver->setAllowedValues('hash_algo', hash_algos()); $resolver->setAllowedValues('methods', function ($value) { - return 0 === count(array_diff($value, ['GET', 'HEAD', 'POST'])); + $matches = preg_grep('/[^[:alnum:]!#$%&\'*\/+\-.^_`|~]/', $value); + return empty($matches); }); } From baf4fbd72e1b8e7db29990febc164292d2aaaa6a Mon Sep 17 00:00:00 2001 From: Mika Tuupola Date: Mon, 13 Feb 2017 11:28:15 +0700 Subject: [PATCH 05/16] Include request body in cache key calculation --- spec/CachePluginSpec.php | 12 +++++++++++- src/CachePlugin.php | 6 +----- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/spec/CachePluginSpec.php b/spec/CachePluginSpec.php index e845af3..12de5db 100644 --- a/spec/CachePluginSpec.php +++ b/spec/CachePluginSpec.php @@ -42,6 +42,8 @@ function it_caches_responses(CacheItemPoolInterface $pool, CacheItemInterface $i $request->getMethod()->willReturn('GET'); $request->getUri()->willReturn('/'); + $request->getBody()->shouldBeCalled(); + $response->getStatusCode()->willReturn(200); $response->getBody()->willReturn($stream); $response->getHeader('Cache-Control')->willReturn(array())->shouldBeCalled(); @@ -72,6 +74,8 @@ function it_doesnt_store_failed_responses(CacheItemPoolInterface $pool, CacheIte { $request->getMethod()->willReturn('GET'); $request->getUri()->willReturn('/'); + $request->getBody()->shouldBeCalled(); + $response->getStatusCode()->willReturn(400); $response->getHeader('Cache-Control')->willReturn(array()); $response->getHeader('Expires')->willReturn(array()); @@ -127,7 +131,7 @@ function it_stores_post_requests_when_allowed( $response->getHeader('Expires')->willReturn([])->shouldBeCalled(); $response->getHeader('ETag')->willReturn([])->shouldBeCalled(); - $pool->getItem('e4311a9af932c603b400a54efab21b6d7dea7a90')->shouldBeCalled()->willReturn($item); + $pool->getItem('e37195334979e7ca0dda534c48a02c7de8368d64')->shouldBeCalled()->willReturn($item); $item->isHit()->willReturn(false); $item->expiresAfter(1060)->willReturn($item)->shouldBeCalled(); @@ -173,6 +177,8 @@ function it_calculate_age_from_response(CacheItemPoolInterface $pool, CacheItemI $request->getMethod()->willReturn('GET'); $request->getUri()->willReturn('/'); + $request->getBody()->shouldBeCalled(); + $response->getStatusCode()->willReturn(200); $response->getBody()->willReturn($stream); $response->getHeader('Cache-Control')->willReturn(array('max-age=40')); @@ -207,6 +213,7 @@ function it_saves_etag(CacheItemPoolInterface $pool, CacheItemInterface $item, R $stream->__toString()->willReturn($httpBody); $stream->isSeekable()->willReturn(true); $stream->rewind()->shouldBeCalled(); + $request->getBody()->shouldBeCalled(); $request->getMethod()->willReturn('GET'); $request->getUri()->willReturn('/'); @@ -242,6 +249,7 @@ function it_adds_etag_and_modfied_since_to_request(CacheItemPoolInterface $pool, $request->getMethod()->willReturn('GET'); $request->getUri()->willReturn('/'); + $request->getBody()->shouldBeCalled(); $request->withHeader('If-Modified-Since', 'Thursday, 01-Jan-70 01:18:31 GMT')->shouldBeCalled()->willReturn($request); $request->withHeader('If-None-Match', 'foo_etag')->shouldBeCalled()->willReturn($request); @@ -271,6 +279,7 @@ function it_servces_a_cached_response(CacheItemPoolInterface $pool, CacheItemInt $request->getMethod()->willReturn('GET'); $request->getUri()->willReturn('/'); + $request->getBody()->shouldBeCalled(); $pool->getItem('d20f64acc6e70b6079845f2fe357732929550ae1')->shouldBeCalled()->willReturn($item); $item->isHit()->willReturn(true); @@ -299,6 +308,7 @@ function it_serves_and_resaved_expired_response(CacheItemPoolInterface $pool, Ca $request->getMethod()->willReturn('GET'); $request->getUri()->willReturn('/'); + $request->getBody()->shouldBeCalled(); $request->withHeader(Argument::any(), Argument::any())->willReturn($request); $request->withHeader(Argument::any(), Argument::any())->willReturn($request); diff --git a/src/CachePlugin.php b/src/CachePlugin.php index fcf42b2..3646f50 100644 --- a/src/CachePlugin.php +++ b/src/CachePlugin.php @@ -224,11 +224,7 @@ private function getCacheControlDirective(ResponseInterface $response, $name) */ private function createCacheKey(RequestInterface $request) { - if ('POST' === $request->getMethod()) { - return hash($this->config['hash_algo'], $request->getMethod().' '.$request->getUri().' '.$request->getBody()); - } - - return hash($this->config['hash_algo'], $request->getMethod().' '.$request->getUri()); + return hash($this->config['hash_algo'], $request->getMethod().' '.$request->getUri().$request->getBody()); } /** From 8d9d48c3a8ae50e9c1492281a00b45e3877f928d Mon Sep 17 00:00:00 2001 From: Mika Tuupola Date: Mon, 13 Feb 2017 20:46:16 +0700 Subject: [PATCH 06/16] Make StyleCI happy --- src/CachePlugin.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/CachePlugin.php b/src/CachePlugin.php index 3646f50..5589304 100644 --- a/src/CachePlugin.php +++ b/src/CachePlugin.php @@ -282,6 +282,7 @@ private function configureOptions(OptionsResolver $resolver) $resolver->setAllowedValues('hash_algo', hash_algos()); $resolver->setAllowedValues('methods', function ($value) { $matches = preg_grep('/[^[:alnum:]!#$%&\'*\/+\-.^_`|~]/', $value); + return empty($matches); }); } From 5b21d4bf9cc34f3d1f2b9310a26722c51b0fe634 Mon Sep 17 00:00:00 2001 From: Mika Tuupola Date: Mon, 13 Feb 2017 20:57:55 +0700 Subject: [PATCH 07/16] PHP 5.4 does not have ::class --- spec/CachePluginSpec.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/CachePluginSpec.php b/spec/CachePluginSpec.php index 12de5db..6822d32 100644 --- a/spec/CachePluginSpec.php +++ b/spec/CachePluginSpec.php @@ -161,10 +161,10 @@ function it_does_not_allow_invalid_request_methods( StreamInterface $stream ) { $this - ->shouldThrow(InvalidOptionsException::class) + ->shouldThrow("Symfony\Component\OptionsResolver\Exception\InvalidOptionsException") ->during('__construct', [$pool, $streamFactory, ['methods' => ['GET', 'HEAD', 'POST ']]]); $this - ->shouldThrow(InvalidOptionsException::class) + ->shouldThrow("Symfony\Component\OptionsResolver\Exception\InvalidOptionsException") ->during('__construct', [$pool, $streamFactory, ['methods' => ['GET', 'HEAD"', 'POST']]]); } From cfa6135b89477947a9eac2fd69daf0ab09b6dae7 Mon Sep 17 00:00:00 2001 From: Mika Tuupola Date: Tue, 14 Feb 2017 10:07:16 +0700 Subject: [PATCH 08/16] Mention RFC7230 which defines valid request methods --- src/CachePlugin.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/CachePlugin.php b/src/CachePlugin.php index 5589304..c1be359 100644 --- a/src/CachePlugin.php +++ b/src/CachePlugin.php @@ -281,6 +281,7 @@ private function configureOptions(OptionsResolver $resolver) $resolver->setAllowedTypes('methods', 'array'); $resolver->setAllowedValues('hash_algo', hash_algos()); $resolver->setAllowedValues('methods', function ($value) { + /* Any VCHAR, except delimiters. RFC7230 sections 3.1.1 and 3.2.6 */ $matches = preg_grep('/[^[:alnum:]!#$%&\'*\/+\-.^_`|~]/', $value); return empty($matches); From 8d8f8e92b54ca4356adc15756d976c5b92efb64a Mon Sep 17 00:00:00 2001 From: Mika Tuupola Date: Wed, 15 Feb 2017 16:43:50 +0700 Subject: [PATCH 09/16] Add new methods option to docblock --- src/CachePlugin.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/CachePlugin.php b/src/CachePlugin.php index c1be359..00acae5 100644 --- a/src/CachePlugin.php +++ b/src/CachePlugin.php @@ -45,6 +45,7 @@ final class CachePlugin implements Plugin * @var int $cache_lifetime (seconds) To support serving a previous stale response when the server answers 304 * we have to store the cache for a longer time than the server originally says it is valid for. * We store a cache item for $cache_lifetime + max age of the response. + * @var array $methods case insensitive list of request methods which can be cached. * } */ public function __construct(CacheItemPoolInterface $pool, StreamFactory $streamFactory, array $config = []) From fbc1dc728d41f49a5e5aa084ff4c0ac0db4dfb43 Mon Sep 17 00:00:00 2001 From: Mika Tuupola Date: Wed, 15 Feb 2017 17:30:17 +0700 Subject: [PATCH 10/16] Request methods are case sensitive --- src/CachePlugin.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/CachePlugin.php b/src/CachePlugin.php index 00acae5..06f3854 100644 --- a/src/CachePlugin.php +++ b/src/CachePlugin.php @@ -45,7 +45,7 @@ final class CachePlugin implements Plugin * @var int $cache_lifetime (seconds) To support serving a previous stale response when the server answers 304 * we have to store the cache for a longer time than the server originally says it is valid for. * We store a cache item for $cache_lifetime + max age of the response. - * @var array $methods case insensitive list of request methods which can be cached. + * @var array $methods case sensitive list of request methods which can be cached. * } */ public function __construct(CacheItemPoolInterface $pool, StreamFactory $streamFactory, array $config = []) From e94b74a3f6bd7dd4d49ddb31172e1c1f70e94ef2 Mon Sep 17 00:00:00 2001 From: Mika Tuupola Date: Fri, 17 Feb 2017 21:14:27 +0700 Subject: [PATCH 11/16] Do not allow lowercase request methods Technically RFC7230 allows lowercase request methods but consensus was they might be too confusing for users. --- spec/CachePluginSpec.php | 3 +++ src/CachePlugin.php | 6 +++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/spec/CachePluginSpec.php b/spec/CachePluginSpec.php index 6822d32..4dc3cfa 100644 --- a/spec/CachePluginSpec.php +++ b/spec/CachePluginSpec.php @@ -166,6 +166,9 @@ function it_does_not_allow_invalid_request_methods( $this ->shouldThrow("Symfony\Component\OptionsResolver\Exception\InvalidOptionsException") ->during('__construct', [$pool, $streamFactory, ['methods' => ['GET', 'HEAD"', 'POST']]]); + $this + ->shouldThrow("Symfony\Component\OptionsResolver\Exception\InvalidOptionsException") + ->during('__construct', [$pool, $streamFactory, ['methods' => ['GET', 'head', 'POST']]]); } function it_calculate_age_from_response(CacheItemPoolInterface $pool, CacheItemInterface $item, RequestInterface $request, ResponseInterface $response, StreamInterface $stream) diff --git a/src/CachePlugin.php b/src/CachePlugin.php index 06f3854..be012aa 100644 --- a/src/CachePlugin.php +++ b/src/CachePlugin.php @@ -45,7 +45,7 @@ final class CachePlugin implements Plugin * @var int $cache_lifetime (seconds) To support serving a previous stale response when the server answers 304 * we have to store the cache for a longer time than the server originally says it is valid for. * We store a cache item for $cache_lifetime + max age of the response. - * @var array $methods case sensitive list of request methods which can be cached. + * @var array $methods list of request methods which can be cached. * } */ public function __construct(CacheItemPoolInterface $pool, StreamFactory $streamFactory, array $config = []) @@ -282,8 +282,8 @@ private function configureOptions(OptionsResolver $resolver) $resolver->setAllowedTypes('methods', 'array'); $resolver->setAllowedValues('hash_algo', hash_algos()); $resolver->setAllowedValues('methods', function ($value) { - /* Any VCHAR, except delimiters. RFC7230 sections 3.1.1 and 3.2.6 */ - $matches = preg_grep('/[^[:alnum:]!#$%&\'*\/+\-.^_`|~]/', $value); + /* RFC7230 sections 3.1.1 and 3.2.6 except limited to uppercase characters. */ + $matches = preg_grep('/[^A-Z0-9!#$%&\'*\/+\-.^_`|~]/', $value); return empty($matches); }); From 65d819dd7bc3b9aa071fa0377f458b3026e37bcd Mon Sep 17 00:00:00 2001 From: Mika Tuupola Date: Fri, 17 Feb 2017 21:24:20 +0700 Subject: [PATCH 12/16] Add delimiter between uri and body Without delimiter the following requests would get the same cache key: POST /foo bar POST /foob ar --- spec/CachePluginSpec.php | 16 ++++++++-------- src/CachePlugin.php | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/spec/CachePluginSpec.php b/spec/CachePluginSpec.php index 4dc3cfa..be92917 100644 --- a/spec/CachePluginSpec.php +++ b/spec/CachePluginSpec.php @@ -50,7 +50,7 @@ function it_caches_responses(CacheItemPoolInterface $pool, CacheItemInterface $i $response->getHeader('Expires')->willReturn(array())->shouldBeCalled(); $response->getHeader('ETag')->willReturn(array())->shouldBeCalled(); - $pool->getItem('d20f64acc6e70b6079845f2fe357732929550ae1')->shouldBeCalled()->willReturn($item); + $pool->getItem('15a7c0e71475fda62536abd940c55a9d1749ce47')->shouldBeCalled()->willReturn($item); $item->isHit()->willReturn(false); $item->expiresAfter(1060)->willReturn($item)->shouldBeCalled(); @@ -80,7 +80,7 @@ function it_doesnt_store_failed_responses(CacheItemPoolInterface $pool, CacheIte $response->getHeader('Cache-Control')->willReturn(array()); $response->getHeader('Expires')->willReturn(array()); - $pool->getItem('d20f64acc6e70b6079845f2fe357732929550ae1')->shouldBeCalled()->willReturn($item); + $pool->getItem('15a7c0e71475fda62536abd940c55a9d1749ce47')->shouldBeCalled()->willReturn($item); $item->isHit()->willReturn(false); $next = function (RequestInterface $request) use ($response) { @@ -131,7 +131,7 @@ function it_stores_post_requests_when_allowed( $response->getHeader('Expires')->willReturn([])->shouldBeCalled(); $response->getHeader('ETag')->willReturn([])->shouldBeCalled(); - $pool->getItem('e37195334979e7ca0dda534c48a02c7de8368d64')->shouldBeCalled()->willReturn($item); + $pool->getItem('e4311a9af932c603b400a54efab21b6d7dea7a90')->shouldBeCalled()->willReturn($item); $item->isHit()->willReturn(false); $item->expiresAfter(1060)->willReturn($item)->shouldBeCalled(); @@ -189,7 +189,7 @@ function it_calculate_age_from_response(CacheItemPoolInterface $pool, CacheItemI $response->getHeader('Expires')->willReturn(array()); $response->getHeader('ETag')->willReturn(array()); - $pool->getItem('d20f64acc6e70b6079845f2fe357732929550ae1')->shouldBeCalled()->willReturn($item); + $pool->getItem('15a7c0e71475fda62536abd940c55a9d1749ce47')->shouldBeCalled()->willReturn($item); $item->isHit()->willReturn(false); $item->set($this->getCacheItemMatcher([ @@ -226,7 +226,7 @@ function it_saves_etag(CacheItemPoolInterface $pool, CacheItemInterface $item, R $response->getHeader('Expires')->willReturn(array()); $response->getHeader('ETag')->willReturn(array('foo_etag')); - $pool->getItem('d20f64acc6e70b6079845f2fe357732929550ae1')->shouldBeCalled()->willReturn($item); + $pool->getItem('15a7c0e71475fda62536abd940c55a9d1749ce47')->shouldBeCalled()->willReturn($item); $item->isHit()->willReturn(false); $item->expiresAfter(1060)->willReturn($item); @@ -259,7 +259,7 @@ function it_adds_etag_and_modfied_since_to_request(CacheItemPoolInterface $pool, $response->getStatusCode()->willReturn(304); - $pool->getItem('d20f64acc6e70b6079845f2fe357732929550ae1')->shouldBeCalled()->willReturn($item); + $pool->getItem('15a7c0e71475fda62536abd940c55a9d1749ce47')->shouldBeCalled()->willReturn($item); $item->isHit()->willReturn(true, false); $item->get()->willReturn([ 'response' => $response, @@ -284,7 +284,7 @@ function it_servces_a_cached_response(CacheItemPoolInterface $pool, CacheItemInt $request->getUri()->willReturn('/'); $request->getBody()->shouldBeCalled(); - $pool->getItem('d20f64acc6e70b6079845f2fe357732929550ae1')->shouldBeCalled()->willReturn($item); + $pool->getItem('15a7c0e71475fda62536abd940c55a9d1749ce47')->shouldBeCalled()->willReturn($item); $item->isHit()->willReturn(true); $item->get()->willReturn([ 'response' => $response, @@ -323,7 +323,7 @@ function it_serves_and_resaved_expired_response(CacheItemPoolInterface $pool, Ca // Make sure we add back the body $response->withBody($stream)->willReturn($response)->shouldBeCalled(); - $pool->getItem('d20f64acc6e70b6079845f2fe357732929550ae1')->shouldBeCalled()->willReturn($item); + $pool->getItem('15a7c0e71475fda62536abd940c55a9d1749ce47')->shouldBeCalled()->willReturn($item); $item->isHit()->willReturn(true, true); $item->expiresAfter(1060)->willReturn($item)->shouldBeCalled(); $item->get()->willReturn([ diff --git a/src/CachePlugin.php b/src/CachePlugin.php index be012aa..86e3958 100644 --- a/src/CachePlugin.php +++ b/src/CachePlugin.php @@ -225,7 +225,7 @@ private function getCacheControlDirective(ResponseInterface $response, $name) */ private function createCacheKey(RequestInterface $request) { - return hash($this->config['hash_algo'], $request->getMethod().' '.$request->getUri().$request->getBody()); + return hash($this->config['hash_algo'], $request->getMethod().' '.$request->getUri().' '.$request->getBody()); } /** From 10da16c82a88f5c88894ee487eb27075e9d3581e Mon Sep 17 00:00:00 2001 From: Mika Tuupola Date: Fri, 17 Feb 2017 21:39:22 +0700 Subject: [PATCH 13/16] Remove unneeded use statement --- spec/CachePluginSpec.php | 1 - 1 file changed, 1 deletion(-) diff --git a/spec/CachePluginSpec.php b/spec/CachePluginSpec.php index be92917..c74852f 100644 --- a/spec/CachePluginSpec.php +++ b/spec/CachePluginSpec.php @@ -11,7 +11,6 @@ use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\StreamInterface; -use Symfony\Component\OptionsResolver\Exception\InvalidOptionsException; class CachePluginSpec extends ObjectBehavior { From 9703885d7146f9c34d833158f64e3181147c34ac Mon Sep 17 00:00:00 2001 From: Mika Tuupola Date: Sun, 19 Feb 2017 11:26:25 +0700 Subject: [PATCH 14/16] Maintain cache key bc with v1.2.0 --- spec/CachePluginSpec.php | 14 +++++++------- src/CachePlugin.php | 7 ++++++- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/spec/CachePluginSpec.php b/spec/CachePluginSpec.php index c74852f..a3561fb 100644 --- a/spec/CachePluginSpec.php +++ b/spec/CachePluginSpec.php @@ -49,7 +49,7 @@ function it_caches_responses(CacheItemPoolInterface $pool, CacheItemInterface $i $response->getHeader('Expires')->willReturn(array())->shouldBeCalled(); $response->getHeader('ETag')->willReturn(array())->shouldBeCalled(); - $pool->getItem('15a7c0e71475fda62536abd940c55a9d1749ce47')->shouldBeCalled()->willReturn($item); + $pool->getItem('d20f64acc6e70b6079845f2fe357732929550ae1')->shouldBeCalled()->willReturn($item); $item->isHit()->willReturn(false); $item->expiresAfter(1060)->willReturn($item)->shouldBeCalled(); @@ -79,7 +79,7 @@ function it_doesnt_store_failed_responses(CacheItemPoolInterface $pool, CacheIte $response->getHeader('Cache-Control')->willReturn(array()); $response->getHeader('Expires')->willReturn(array()); - $pool->getItem('15a7c0e71475fda62536abd940c55a9d1749ce47')->shouldBeCalled()->willReturn($item); + $pool->getItem('d20f64acc6e70b6079845f2fe357732929550ae1')->shouldBeCalled()->willReturn($item); $item->isHit()->willReturn(false); $next = function (RequestInterface $request) use ($response) { @@ -188,7 +188,7 @@ function it_calculate_age_from_response(CacheItemPoolInterface $pool, CacheItemI $response->getHeader('Expires')->willReturn(array()); $response->getHeader('ETag')->willReturn(array()); - $pool->getItem('15a7c0e71475fda62536abd940c55a9d1749ce47')->shouldBeCalled()->willReturn($item); + $pool->getItem('d20f64acc6e70b6079845f2fe357732929550ae1')->shouldBeCalled()->willReturn($item); $item->isHit()->willReturn(false); $item->set($this->getCacheItemMatcher([ @@ -225,7 +225,7 @@ function it_saves_etag(CacheItemPoolInterface $pool, CacheItemInterface $item, R $response->getHeader('Expires')->willReturn(array()); $response->getHeader('ETag')->willReturn(array('foo_etag')); - $pool->getItem('15a7c0e71475fda62536abd940c55a9d1749ce47')->shouldBeCalled()->willReturn($item); + $pool->getItem('d20f64acc6e70b6079845f2fe357732929550ae1')->shouldBeCalled()->willReturn($item); $item->isHit()->willReturn(false); $item->expiresAfter(1060)->willReturn($item); @@ -258,7 +258,7 @@ function it_adds_etag_and_modfied_since_to_request(CacheItemPoolInterface $pool, $response->getStatusCode()->willReturn(304); - $pool->getItem('15a7c0e71475fda62536abd940c55a9d1749ce47')->shouldBeCalled()->willReturn($item); + $pool->getItem('d20f64acc6e70b6079845f2fe357732929550ae1')->shouldBeCalled()->willReturn($item); $item->isHit()->willReturn(true, false); $item->get()->willReturn([ 'response' => $response, @@ -283,7 +283,7 @@ function it_servces_a_cached_response(CacheItemPoolInterface $pool, CacheItemInt $request->getUri()->willReturn('/'); $request->getBody()->shouldBeCalled(); - $pool->getItem('15a7c0e71475fda62536abd940c55a9d1749ce47')->shouldBeCalled()->willReturn($item); + $pool->getItem('d20f64acc6e70b6079845f2fe357732929550ae1')->shouldBeCalled()->willReturn($item); $item->isHit()->willReturn(true); $item->get()->willReturn([ 'response' => $response, @@ -322,7 +322,7 @@ function it_serves_and_resaved_expired_response(CacheItemPoolInterface $pool, Ca // Make sure we add back the body $response->withBody($stream)->willReturn($response)->shouldBeCalled(); - $pool->getItem('15a7c0e71475fda62536abd940c55a9d1749ce47')->shouldBeCalled()->willReturn($item); + $pool->getItem('d20f64acc6e70b6079845f2fe357732929550ae1')->shouldBeCalled()->willReturn($item); $item->isHit()->willReturn(true, true); $item->expiresAfter(1060)->willReturn($item)->shouldBeCalled(); $item->get()->willReturn([ diff --git a/src/CachePlugin.php b/src/CachePlugin.php index 86e3958..c761ec7 100644 --- a/src/CachePlugin.php +++ b/src/CachePlugin.php @@ -225,7 +225,12 @@ private function getCacheControlDirective(ResponseInterface $response, $name) */ private function createCacheKey(RequestInterface $request) { - return hash($this->config['hash_algo'], $request->getMethod().' '.$request->getUri().' '.$request->getBody()); + $body = (string) $request->getBody(); + if (!empty($body)) { + $body = ' ' . $body; + } + + return hash($this->config['hash_algo'], $request->getMethod().' '.$request->getUri().$body); } /** From 490da8bb24e12429a370275fb0f9535894de898f Mon Sep 17 00:00:00 2001 From: Mika Tuupola Date: Sun, 19 Feb 2017 11:37:39 +0700 Subject: [PATCH 15/16] Make StyleCI happy --- src/CachePlugin.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/CachePlugin.php b/src/CachePlugin.php index c761ec7..d5fa3f6 100644 --- a/src/CachePlugin.php +++ b/src/CachePlugin.php @@ -227,7 +227,7 @@ private function createCacheKey(RequestInterface $request) { $body = (string) $request->getBody(); if (!empty($body)) { - $body = ' ' . $body; + $body = ' ' . $body; } return hash($this->config['hash_algo'], $request->getMethod().' '.$request->getUri().$body); From 727cbf075ae286cfee4ae611c139d43f1605f99b Mon Sep 17 00:00:00 2001 From: Mika Tuupola Date: Sun, 19 Feb 2017 11:41:09 +0700 Subject: [PATCH 16/16] Make StyleCI happy --- src/CachePlugin.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/CachePlugin.php b/src/CachePlugin.php index d5fa3f6..66d38c6 100644 --- a/src/CachePlugin.php +++ b/src/CachePlugin.php @@ -227,7 +227,7 @@ private function createCacheKey(RequestInterface $request) { $body = (string) $request->getBody(); if (!empty($body)) { - $body = ' ' . $body; + $body = ' '.$body; } return hash($this->config['hash_algo'], $request->getMethod().' '.$request->getUri().$body);