diff --git a/library/Zend/Mvc/ResponseSender/AbstractResponseSender.php b/library/Zend/Mvc/ResponseSender/AbstractResponseSender.php index 71a998746dc..013e921c361 100644 --- a/library/Zend/Mvc/ResponseSender/AbstractResponseSender.php +++ b/library/Zend/Mvc/ResponseSender/AbstractResponseSender.php @@ -26,8 +26,6 @@ public function sendHeaders(SendResponseEvent $event) } $response = $event->getResponse(); - $status = $response->renderStatusLine(); - header($status); foreach ($response->getHeaders() as $header) { if ($header instanceof MultipleHeaderInterface) { @@ -37,6 +35,9 @@ public function sendHeaders(SendResponseEvent $event) header($header->toString()); } + $status = $response->renderStatusLine(); + header($status); + $event->setHeadersSent(); return $this; } diff --git a/tests/ZendTest/Mvc/ResponseSender/AbstractResponseSenderTest.php b/tests/ZendTest/Mvc/ResponseSender/AbstractResponseSenderTest.php index fff7fd7def3..be20615a815 100644 --- a/tests/ZendTest/Mvc/ResponseSender/AbstractResponseSenderTest.php +++ b/tests/ZendTest/Mvc/ResponseSender/AbstractResponseSenderTest.php @@ -11,6 +11,7 @@ namespace ZendTest\Mvc\ResponseSender; use PHPUnit_Framework_TestCase as TestCase; +use Zend\Http\Headers; use Zend\Http\Response; /** @@ -53,4 +54,34 @@ public function testSendHeadersTwoTimesSendsOnlyOnce() $responseSender->sendHeaders($mockSendResponseEvent); $this->assertEquals(array(), xdebug_get_headers()); } + + /** + * @runInSeparateProcess + */ + public function testSendHeadersSendsStatusLast() + { + if (!function_exists('xdebug_get_headers')) { + $this->markTestSkipped('Xdebug extension needed, skipped test'); + } + + $mockResponse = $this->getMock('Zend\Http\Response'); + $mockResponse->expects($this->once())->method('getHeaders')->will($this->returnValue(Headers::fromString('Location: example.com'))); + $mockResponse->expects($this->once())->method('renderStatusLine')->will($this->returnValue('X-Test: HTTP/1.1 202 Accepted')); + + $mockSendResponseEvent = $this->getMock('Zend\Mvc\ResponseSender\SendResponseEvent', array('getResponse')); + $mockSendResponseEvent->expects($this->any())->method('getResponse')->will($this->returnValue($mockResponse)); + + $responseSender = $this->getMockForAbstractClass('Zend\Mvc\ResponseSender\AbstractResponseSender'); + $responseSender->sendHeaders($mockSendResponseEvent); + + $sentHeaders = xdebug_get_headers(); + + $this->assertCount(2, $sentHeaders); + $this->assertEquals('Location: example.com', $sentHeaders[0]); + $this->assertEquals( + 'X-Test: HTTP/1.1 202 Accepted', + $sentHeaders[1], + 'Status header is sent last to prevent header() from overwriting the ZF status code when a Location header is used' + ); + } }