[FrameworkBundle] fixed output buffering when an error occurs in a sub-request

This commit is contained in:
Fabien Potencier 2011-11-07 18:25:31 +01:00
parent 380c67efc8
commit c31c512466
2 changed files with 55 additions and 0 deletions

View File

@ -135,6 +135,7 @@ class HttpKernel extends BaseHttpKernel
$subRequest = $request->duplicate($options['query'], null, $options['attributes']);
}
$level = ob_get_level();
try {
$response = $this->handle($subRequest, HttpKernelInterface::SUB_REQUEST, false);
@ -156,6 +157,11 @@ class HttpKernel extends BaseHttpKernel
if (!$options['ignore_errors']) {
throw $e;
}
// let's clean up the output buffers that were created by the sub-request
while (ob_get_level() > $level) {
ob_get_clean();
}
}
}

View File

@ -166,4 +166,53 @@ class HttpKernelTest extends \PHPUnit_Framework_TestCase
array(HttpKernelInterface::SUB_REQUEST),
);
}
public function testExceptionInSubRequestsDoesNotMangleOutputBuffers()
{
$request = new Request();
$container = $this->getMock('Symfony\\Component\\DependencyInjection\\ContainerInterface');
$container
->expects($this->at(0))
->method('getParameter')
->with($this->equalTo('kernel.debug'))
->will($this->returnValue(false))
;
$container
->expects($this->at(1))
->method('has')
->with($this->equalTo('esi'))
->will($this->returnValue(false))
;
$container
->expects($this->at(2))
->method('get')
->with($this->equalTo('request'))
->will($this->returnValue($request))
;
$dispatcher = new EventDispatcher();
$resolver = $this->getMock('Symfony\\Component\\HttpKernel\\Controller\\ControllerResolverInterface');
$resolver->expects($this->once())
->method('getController')
->will($this->returnValue(function () {
ob_start();
echo 'bar';
throw new \RuntimeException();
}));
$resolver->expects($this->once())
->method('getArguments')
->will($this->returnValue(array()));
$kernel = new HttpKernel($dispatcher, $container, $resolver);
// simulate a main request with output buffering
ob_start();
echo 'Foo';
// simulate a sub-request with output buffering and an exception
$kernel->render('/');
$this->assertEquals('Foo', ob_get_clean());
}
}