diff --git a/src/Illuminate/Http/Middleware/Cache.php b/src/Illuminate/Http/Middleware/Cache.php new file mode 100644 index 000000000000..2910cdca5bbd --- /dev/null +++ b/src/Illuminate/Http/Middleware/Cache.php @@ -0,0 +1,47 @@ +isMethodCacheable() || ! $response->getContent()) { + return $response; + } + + if (\is_string($options)) { + $parsedOptions = []; + foreach (explode(';', $options) as $opt) { + $data = explode('=', $opt, 2); + $parsedOptions[$data[0]] = $data[1] ?? true; + } + + $options = $parsedOptions; + } + + if (isset($options['etag']) && true === $options['etag']) { + $options['etag'] = md5($response->getContent()); + } + + $response->setCache($options); + $response->isNotModified($request); + + return $response; + } +} diff --git a/tests/Http/Middleware/CacheTest.php b/tests/Http/Middleware/CacheTest.php new file mode 100644 index 000000000000..6d865e973bdc --- /dev/null +++ b/tests/Http/Middleware/CacheTest.php @@ -0,0 +1,85 @@ +setMethod('PUT'); + + $response = (new Cache())->handle($request, function () { + return new Response('Hello Laravel'); + }, 'max_age=120;s_maxage=60'); + + $this->assertNull($response->getMaxAge()); + } + + public function testDoNotSetHeaderWhenNoContent() + { + $response = (new Cache())->handle(new Request(), function () { + return new Response(); + }, 'max_age=120;s_maxage=60'); + + $this->assertNull($response->getMaxAge()); + $this->assertNull($response->getEtag()); + } + + public function testAddHeaders() + { + $response = (new Cache())->handle(new Request(), function () { + return new Response('some content'); + }, 'max_age=100;s_maxage=200;etag=ABC'); + + $this->assertSame('"ABC"', $response->getEtag()); + $this->assertSame('max-age=100, public, s-maxage=200', $response->headers->get('Cache-Control')); + } + + public function testAddHeadersUsingArray() + { + $response = (new Cache())->handle(new Request(), function () { + return new Response('some content'); + }, ['max_age' => 100, 's_maxage' => 200, 'etag' => 'ABC']); + + $this->assertSame('"ABC"', $response->getEtag()); + $this->assertSame('max-age=100, public, s-maxage=200', $response->headers->get('Cache-Control')); + } + + public function testGenerateEtag() + { + $response = (new Cache())->handle(new Request(), function () { + return new Response('some content'); + }, 'etag;max_age=100;s_maxage=200'); + + $this->assertSame('"9893532233caff98cd083a116b013c0b"', $response->getEtag()); + $this->assertSame('max-age=100, public, s-maxage=200', $response->headers->get('Cache-Control')); + } + + public function testIsNotModified() + { + $request = new Request(); + $request->headers->set('If-None-Match', '"9893532233caff98cd083a116b013c0b"'); + + $response = (new Cache())->handle($request, function () { + return new Response('some content'); + }, 'etag;max_age=100;s_maxage=200'); + + $this->assertSame(304, $response->getStatusCode()); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testInvalidOption() + { + (new Cache())->handle(new Request(), function () { + return new Response('some content'); + }, 'invalid'); + } +}