Skip to content

Commit

Permalink
Fixing a couple bugs in CakeResponse::checkNotModified() and implemen…
Browse files Browse the repository at this point in the history
…ting conditional rendering in

RequestHandlerComponent
  • Loading branch information
lorenzo committed Jan 19, 2012
1 parent 28ee27e commit 979f7a2
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 2 deletions.
20 changes: 19 additions & 1 deletion lib/Cake/Controller/Component/RequestHandlerComponent.php
Expand Up @@ -95,7 +95,8 @@ class RequestHandlerComponent extends Component {
* @param array $settings Array of settings.
*/
public function __construct(ComponentCollection $collection, $settings = array()) {
parent::__construct($collection, $settings);
$default = array('checkHttpCache' => true);
parent::__construct($collection, $settings + $default);
$this->addInputType('xml', array(array($this, 'convertXml')));

$Controller = $collection->getController();
Expand Down Expand Up @@ -240,6 +241,23 @@ public function beforeRedirect($controller, $url, $status = null, $exit = true)
$this->_stop();
}

/**
* Checks if the response can be considered different according to the request
* headers, and the caching response headers. If it was not modified, then the
* render process is skipped. And the client will get a blank response with a
* "304 Not Modified" header.
*
* @params Controller $controller
* @return boolean false if the render process should be aborted
**/
public function beforeRender($controller) {
$shouldCheck = $this->settings['checkHttpCache'];
if ($shouldCheck && $this->response->checkNotModified($this->request)) {
$this->response->send();
return false;
}
}

/**
* Returns true if the current HTTP request is Ajax, false otherwise
*
Expand Down
6 changes: 5 additions & 1 deletion lib/Cake/Network/CakeResponse.php
Expand Up @@ -1034,7 +1034,11 @@ public function checkNotModified(CakeRequest $request) {
if ($modifiedSince) {
$timeMatches = strtotime($this->modified()) == strtotime($modifiedSince);
}
$notModified = (!isset($etagMatches) || $etagMatches) && (!isset($timeMatches) || $timeMatches);
$checks = compact('etagMatches', 'timeMatches');
if (empty($checks)) {
return false;
}
$notModified = !in_array(false, $checks, true);
if ($notModified) {
$this->notModified();
}
Expand Down
Expand Up @@ -824,4 +824,59 @@ public function testAddInputTypeException() {
$this->RequestHandler->addInputType('csv', array('I am not callable'));
}

/**
* Test checkNotModified method
*
* @return void
**/
public function testCheckNotModifiedByEtagStar() {
$_SERVER['HTTP_IF_NONE_MATCH'] = '*';
$RequestHandler = $this->getMock('RequestHandlerComponent', array('_stop'), array(&$this->Controller->Components));
$RequestHandler->response = $this->getMock('CakeResponse', array('notModified'));
$RequestHandler->response->etag('something');
$RequestHandler->response->expects($this->once())->method('notModified');
$this->assertFalse($RequestHandler->beforeRender($this->Controller));
}

/**
* Test checkNotModified method
*
* @return void
**/
public function testCheckNotModifiedByEtagExact() {
$_SERVER['HTTP_IF_NONE_MATCH'] = 'W/"something", "other"';
$RequestHandler = $this->getMock('RequestHandlerComponent', array('_stop'), array(&$this->Controller->Components));
$RequestHandler->response = $this->getMock('CakeResponse', array('notModified'));
$RequestHandler->response->etag('something', true);
$RequestHandler->response->expects($this->once())->method('notModified');
$this->assertFalse($RequestHandler->beforeRender($this->Controller));
}

/**
* Test checkNotModified method
*
* @return void
**/
public function testCheckNotModifiedByEtagAndTime() {
$_SERVER['HTTP_IF_NONE_MATCH'] = 'W/"something", "other"';
$_SERVER['HTTP_IF_MODIFIED_SINCE'] = '2012-01-01 00:00:00';
$RequestHandler = $this->getMock('RequestHandlerComponent', array('_stop'), array(&$this->Controller->Components));
$RequestHandler->response = $this->getMock('CakeResponse', array('notModified'));
$RequestHandler->response->etag('something', true);
$RequestHandler->response->modified('2012-01-01 00:00:00');
$RequestHandler->response->expects($this->once())->method('notModified');
$this->assertFalse($RequestHandler->beforeRender($this->Controller));
}

/**
* Test checkNotModified method
*
* @return void
**/
public function testCheckNotModifiedNoInfo() {
$RequestHandler = $this->getMock('RequestHandlerComponent', array('_stop'), array(&$this->Controller->Components));
$RequestHandler->response = $this->getMock('CakeResponse', array('notModified'));
$RequestHandler->response->expects($this->never())->method('notModified');
$this->assertNull($RequestHandler->beforeRender($this->Controller));
}
}

0 comments on commit 979f7a2

Please sign in to comment.