diff --git a/spec/CachePluginSpec.php b/spec/CachePluginSpec.php index 97afd55..9ad3e91 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,36 +97,42 @@ function it_doesnt_store_post_requests(CacheItemPoolInterface $pool, CacheItemIn $this->handleRequest($request, $next, function () {}); } - - function it_calculate_age_from_response(CacheItemPoolInterface $pool, CacheItemInterface $item, RequestInterface $request, ResponseInterface $response, StreamInterface $stream) + function it_stores_post_requests_when_allowed(CacheItemPoolInterface $pool, CacheItemInterface $item, RequestInterface $request, ResponseInterface $response, StreamFactory $streamFactory, StreamInterface $stream) { - $httpBody = 'body'; + $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('GET'); - $request->getUri()->willReturn('/'); + $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('max-age=40')); - $response->getHeader('Age')->willReturn(array('15')); - $response->getHeader('Expires')->willReturn(array()); - $response->getHeader('ETag')->willReturn(array()); + $response->getHeader('Cache-Control')->willReturn(array())->shouldBeCalled(); + $response->getHeader('Expires')->willReturn(array())->shouldBeCalled(); + $response->getHeader('ETag')->willReturn(array())->shouldBeCalled(); - $pool->getItem('d20f64acc6e70b6079845f2fe357732929550ae1')->shouldBeCalled()->willReturn($item); + $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(); - // 40-15 should be 25 + the default 1000 - $item->expiresAfter(1025)->willReturn($item)->shouldBeCalled(); - $pool->save($item)->shouldBeCalled(); + '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()); 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'])); + }); } /**