diff --git a/lib/Cake/Network/CakeResponse.php b/lib/Cake/Network/CakeResponse.php index 3e58d15b820..9abc839ba28 100644 --- a/lib/Cake/Network/CakeResponse.php +++ b/lib/Cake/Network/CakeResponse.php @@ -875,6 +875,38 @@ public function vary($cacheVariances = null) { return null; } +/** + * Sets the response Etag, Etags are a strong indicative that a response + * can be cached by a HTTP client. A bad way of generaing Etags is + * creating a hash of teh response output, instead generate a unique + * hash of the unique components that identifies a request, such as a + * modification time, a resource Id, and anything else you consider it + * makes it unique. + * + * Second parameter is used to instuct clients that the content has + * changed, but sematicallly, it can be used as the same thing. Think + * for instance of a page with a hit counter, two different page views + * are equivalent, but they differ by a few bytes. This leaves off to + * the Client the decision of using or not the cached page. + * + * If no parameters are passed, current Etag header is returned. + * + * @param string $hash the unique has that identifies this resposnse + * @param boolean $weak whether the response is semantically the same as + * other with th same hash or not + * @return string + **/ + public function etag($tag = null, $weak = false) { + if ($tag !== null) { + $this->_headers['Etag'] = sprintf('%s"%s"', ($weak) ? 'W/' : null, $tag); + } + if (isset($this->_headers['Etag'])) { + return $this->_headers['Etag']; + } + return null; + } + + /** * Returns a DateTime object initialized at the $time param and using UTC * as timezone diff --git a/lib/Cake/Test/Case/Network/CakeResponseTest.php b/lib/Cake/Test/Case/Network/CakeResponseTest.php index 60f225d4051..1579789de69 100644 --- a/lib/Cake/Test/Case/Network/CakeResponseTest.php +++ b/lib/Cake/Test/Case/Network/CakeResponseTest.php @@ -784,4 +784,25 @@ public function testVary() { $this->assertEquals(array('Accept-language', 'Accept-encoding'), $response->vary()); } +/** + * Tests getting/setting the Etag header + * + * @return void + */ + public function testEtag() { + $response = $this->getMock('CakeResponse', array('_sendHeader', '_sendContent')); + $response->etag('something'); + $this->assertEquals('"something"', $response->etag()); + $response->expects($this->at(1)) + ->method('_sendHeader')->with('Etag', '"something"'); + $response->send(); + + $response = $this->getMock('CakeResponse', array('_sendHeader', '_sendContent')); + $response->etag('something', true); + $this->assertEquals('W/"something"', $response->etag()); + $response->expects($this->at(1)) + ->method('_sendHeader')->with('Etag', 'W/"something"'); + $response->send(); + + } }