diff --git a/README.md b/README.md index 86b7bb37..6187d96f 100644 --- a/README.md +++ b/README.md @@ -351,8 +351,10 @@ $response-> noCache() // Tell the browser not to cache the response redirect($url, $code = 302) // Redirect to the specified URL dump($obj) // Dump an object - file($path, $filename = null) // Send a file - json($object, $jsonp_prefix = null) // Send an object as JSON or JSONP by providing padding prefix + file($path, $filename = null, $allow_caching = false) + // Send a file + json($object, $jsonp_prefix = null, $allow_caching = false) + // Send an object as JSON or JSONP by providing padding prefix $service-> sharedData() // Return the shared data collection diff --git a/src/Klein/Response.php b/src/Klein/Response.php index 5bae3aeb..81fe836e 100644 --- a/src/Klein/Response.php +++ b/src/Klein/Response.php @@ -74,20 +74,24 @@ public function dump($obj) * currently in the response body and replaces it with * the file's data * - * @param string $path The path of the file to send - * @param string $filename The file's name - * @param string $mimetype The MIME type of the file + * @param string $path The path of the file to send + * @param string $filename The file's name + * @param string $mimetype The MIME type of the file + * @param boolean $allow_caching Wether or not to allow response caching * @throws RuntimeException Thrown if the file could not be read * @return Response */ - public function file($path, $filename = null, $mimetype = null) + public function file($path, $filename = null, $mimetype = null, $allow_caching = false) { if ($this->sent) { throw new ResponseAlreadySentException('Response has already been sent'); } $this->body(''); - $this->noCache(); + + if (false === $allow_caching) { + $this->noCache(); + } if (null === $filename) { $filename = basename($path); @@ -141,14 +145,18 @@ public function file($path, $filename = null, $mimetype = null) * currently in the response body and replaces it with * the passed json encoded object * - * @param mixed $object The data to encode as JSON - * @param string $jsonp_prefix The name of the JSON-P function prefix + * @param mixed $object The data to encode as JSON + * @param string $jsonp_prefix The name of the JSON-P function prefix + * @param boolean $allow_caching Wether or not to allow response caching * @return Response */ - public function json($object, $jsonp_prefix = null) + public function json($object, $jsonp_prefix = null, $allow_caching = false) { $this->body(''); - $this->noCache(); + + if (false === $allow_caching) { + $this->noCache(); + } $json = json_encode($object); diff --git a/tests/Klein/Tests/ResponseTest.php b/tests/Klein/Tests/ResponseTest.php index 91540e87..c2a8c1d6 100644 --- a/tests/Klein/Tests/ResponseTest.php +++ b/tests/Klein/Tests/ResponseTest.php @@ -464,6 +464,14 @@ function ($request, $response, $service) use ($file_name, $file_mime) { $file_name, $this->klein_app->response()->headers()->get('Content-Disposition') ); + $this->assertEquals( + 'no-cache', + $this->klein_app->response()->headers()->get('Pragma') + ); + $this->assertEquals( + 'no-store, no-cache', + $this->klein_app->response()->headers()->get('Cache-Control') + ); } public function testFileSendLooseArgs() @@ -548,6 +556,47 @@ public function testFileSendCallsFastCGIFinishRequest() $response->file(__FILE__); } + public function testFileCacheable() + { + $file_name = 'testing'; + $file_mime = 'text/plain'; + + $this->klein_app->respond( + function ($request, $response, $service) use ($file_name, $file_mime) { + $response->file(__FILE__, $file_name, $file_mime, true); + } + ); + + $this->klein_app->dispatch(); + + // Expect our output to match our file + $this->expectOutputString( + file_get_contents(__FILE__) + ); + + // Assert headers were passed + $this->assertEquals( + $file_mime, + $this->klein_app->response()->headers()->get('Content-Type') + ); + $this->assertEquals( + filesize(__FILE__), + $this->klein_app->response()->headers()->get('Content-Length') + ); + $this->assertContains( + $file_name, + $this->klein_app->response()->headers()->get('Content-Disposition') + ); + $this->assertEquals( + null, + $this->klein_app->response()->headers()->get('Pragma') + ); + $this->assertEquals( + null, + $this->klein_app->response()->headers()->get('Cache-Control') + ); + } + public function testJSON() { // Create a test object to be JSON encoded/decoded @@ -624,4 +673,39 @@ function ($request, $response, $service) use ($test_object, $prefix) { $this->klein_app->response()->headers()->get('Content-Type') ); } + + public function testJSONCacheable() + { + // Create a test object to be JSON encoded/decoded + $test_object = array( + 'cheese', + ); + + $this->klein_app->respond( + function ($request, $response, $service) use ($test_object) { + $response->json($test_object, null, true); + } + ); + + $this->klein_app->dispatch(); + + // Expect our output to match our json encoded test object + $this->expectOutputString( + json_encode($test_object) + ); + + // Assert headers were passed + $this->assertEquals( + null, + $this->klein_app->response()->headers()->get('Pragma') + ); + $this->assertEquals( + null, + $this->klein_app->response()->headers()->get('Cache-Control') + ); + $this->assertEquals( + 'application/json', + $this->klein_app->response()->headers()->get('Content-Type') + ); + } }