Skip to content
Browse files

Fix RedirectRoute by stopping execution.

If CakeResponse sends a Location header, it will stop execution.
This fixes issues with where a body would be sent with redirect headers.
Tests updated.

Fixes #2143
  • Loading branch information...
1 parent 7b169ed commit 841e7aa560d27f14c6f381a3548c8d8c74e4a463 @majna majna committed with markstory Oct 22, 2011
View
15 lib/Cake/Network/CakeResponse.php
@@ -351,6 +351,10 @@ public function send() {
foreach ($this->_headers as $header => $value) {
$this->_sendHeader($header, $value);
}
+
+ if (isset($this->_headers['Location'])) {
+ $this->_stop();
+ }
$this->_sendContent($this->_body);
}
@@ -662,4 +666,15 @@ public function download($filename) {
public function __toString() {
return (string)$this->_body;
}
+
+/**
+ * Stop execution of the current script. Wraps exit() making
+ * testing easier.
+ *
+ * @param integer|string $status see http://php.net/exit for values
+ * @return void
+ */
+ protected function _stop($status = 0) {
+ exit($status);
+ }
}
View
2 lib/Cake/Test/Case/Network/CakeResponseTest.php
@@ -209,7 +209,7 @@ public function testSendChangingContentType() {
*
*/
public function testSendWithLocation() {
- $response = $this->getMock('CakeResponse', array('_sendHeader', '_sendContent'));
+ $response = $this->getMock('CakeResponse', array('_sendHeader', '_sendContent', '_stop'));
$response->header('Location', 'http://www.example.com');
$response->expects($this->at(0))
->method('_sendHeader')->with('HTTP/1.1 302 Found');
View
16 lib/Cake/Test/Case/Routing/Route/RedirectRouteTest.php
@@ -45,44 +45,44 @@ public function setUp() {
*/
public function testParsing() {
$route = new RedirectRoute('/home', array('controller' => 'posts'));
- $route->response = $this->getMock('CakeResponse', array('_sendHeader'));
+ $route->response = $this->getMock('CakeResponse', array('_sendHeader', '_stop'));
$result = $route->parse('/home');
$this->assertEqual($route->response->header(), array('Location' => Router::url('/posts', true)));
$route = new RedirectRoute('/home', array('controller' => 'posts', 'action' => 'index'));
- $route->response = $this->getMock('CakeResponse', array('_sendHeader'));
+ $route->response = $this->getMock('CakeResponse', array('_sendHeader', '_stop'));
$result = $route->parse('/home');
$this->assertEqual($route->response->header(), array('Location' => Router::url('/posts', true)));
$this->assertEqual($route->response->statusCode(), 301);
$route = new RedirectRoute('/google', 'http://google.com');
- $route->response = $this->getMock('CakeResponse', array('_sendHeader'));
+ $route->response = $this->getMock('CakeResponse', array('_sendHeader', '_stop'));
$result = $route->parse('/google');
$this->assertEqual($route->response->header(), array('Location' => 'http://google.com'));
$route = new RedirectRoute('/posts/*', array('controller' => 'posts', 'action' => 'view'), array('status' => 302));
- $route->response = $this->getMock('CakeResponse', array('_sendHeader'));
+ $route->response = $this->getMock('CakeResponse', array('_sendHeader', '_stop'));
$result = $route->parse('/posts/2');
$this->assertEqual($route->response->header(), array('Location' => Router::url('/posts/view', true)));
$this->assertEqual($route->response->statusCode(), 302);
$route = new RedirectRoute('/posts/*', array('controller' => 'posts', 'action' => 'view'), array('persist' => true));
- $route->response = $this->getMock('CakeResponse', array('_sendHeader'));
+ $route->response = $this->getMock('CakeResponse', array('_sendHeader', '_stop'));
$result = $route->parse('/posts/2');
$this->assertEqual($route->response->header(), array('Location' => Router::url('/posts/view/2', true)));
$route = new RedirectRoute('/posts/*', '/test', array('persist' => true));
- $route->response = $this->getMock('CakeResponse', array('_sendHeader'));
+ $route->response = $this->getMock('CakeResponse', array('_sendHeader', '_stop'));
$result = $route->parse('/posts/2');
$this->assertEqual($route->response->header(), array('Location' => Router::url('/test', true)));
$route = new RedirectRoute('/my_controllers/:action/*', array('controller' => 'tags', 'action' => 'add'), array('persist' => true));
- $route->response = $this->getMock('CakeResponse', array('_sendHeader'));
+ $route->response = $this->getMock('CakeResponse', array('_sendHeader', '_stop'));
$result = $route->parse('/my_controllers/do_something/passme/named:param');
$this->assertEqual($route->response->header(), array('Location' => Router::url('/tags/add/passme/named:param', true)));
$route = new RedirectRoute('/my_controllers/:action/*', array('controller' => 'tags', 'action' => 'add'));
- $route->response = $this->getMock('CakeResponse', array('_sendHeader'));
+ $route->response = $this->getMock('CakeResponse', array('_sendHeader', '_stop'));
$result = $route->parse('/my_controllers/do_something/passme/named:param');
$this->assertEqual($route->response->header(), array('Location' => Router::url('/tags/add', true)));
}
View
2 lib/Cake/Test/Case/Routing/RouterTest.php
@@ -2458,7 +2458,7 @@ public function testPatternOnAction() {
public function testRouteRedirection() {
Router::redirect('/blog', array('controller' => 'posts'), array('status' => 302));
$this->assertEqual(count(Router::$routes), 1);
- Router::$routes[0]->response = $this->getMock('CakeResponse', array('_sendHeader'));
+ Router::$routes[0]->response = $this->getMock('CakeResponse', array('_sendHeader', '_stop'));
$this->assertEqual(Router::$routes[0]->options['status'], 302);
Router::parse('/blog');

0 comments on commit 841e7aa

Please sign in to comment.
Something went wrong with that request. Please try again.