Skip to content

Commit

Permalink
[HttpKernel] Move request-stashing behavior to the Kernel class
Browse files Browse the repository at this point in the history
Previously, HttpKernel performed request-stashing.  By moving this to the Kernel class, the request is now available immediately after the kernel becomes aware of it.  If the kernel is allowed to boot lazily (during the first call to handle()), this also allows an actual master Request to be available during booting.

The old "request" service definition (with a bogus class name) can be replaced with a factory-aware definition that retrieves the request directly from the kernel.
  • Loading branch information
jmikola authored and fabpot committed Dec 9, 2010
1 parent 2ff474f commit 7eea488
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 2 deletions.
Expand Up @@ -37,7 +37,7 @@
your front controller (app.php) so that it passes an instance of
YourRequestClass to the Kernel.
-->
<service id="request" class="WillNeverBeCalled" />
<service id="request" factory-service="kernel" factory-method="getRequest" shared="false" />

<service id="response" class="%response.class%" shared="false" />
</services>
Expand Down
21 changes: 20 additions & 1 deletion src/Symfony/Component/HttpKernel/Kernel.php
Expand Up @@ -45,6 +45,7 @@ abstract class Kernel implements HttpKernelInterface, \Serializable
protected $booted;
protected $name;
protected $startTime;
protected $request;

const VERSION = '2.0.0-DEV';

Expand Down Expand Up @@ -174,11 +175,29 @@ public function reboot()
*/
public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = true)
{
$masterRequest = HttpKernelInterface::MASTER_REQUEST === $type ? $request : $this->request;

$this->request = $request;

if (false === $this->booted) {
$this->boot();
}

return $this->container->get('http_kernel')->handle($request, $type, $catch);
$response = $this->container->get('http_kernel')->handle($this->request, $type, $catch);

$this->request = $masterRequest;

return $response;
}

/**
* Gets the current request.
*
* @return Request
*/
public function getRequest()
{
return $this->request;
}

/**
Expand Down
63 changes: 63 additions & 0 deletions tests/Symfony/Tests/Component/HttpKernel/KernelTest.php
Expand Up @@ -12,6 +12,8 @@
namespace Symfony\Tests\Component\HttpKernel;

use Symfony\Component\HttpKernel\Kernel;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\DependencyInjection\Loader\LoaderInterface;

class KernelTest extends \PHPUnit_Framework_TestCase
Expand All @@ -22,6 +24,57 @@ public function testGetSafeName()

$this->assertEquals('foo', $kernel->getSafeName());
}

public function testHandleSetsTheRequest()
{
$masterRequest = Request::create('/');
$subRequest = Request::create('/');

$httpKernel = $this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernel')
->disableOriginalConstructor()
->setMethods(array('handle'))
->getMock();

$httpKernel->expects($this->at(0))
->method('handle')
->with($masterRequest);

$httpKernel->expects($this->at(1))
->method('handle')
->with($subRequest);

$container = $this->getMockBuilder('Symfony\Component\DependencyInjection\Container')
->disableOriginalConstructor()
->setMethods(array('get'))
->getMock();

$container->expects($this->exactly(2))
->method('get')
->with('http_kernel')
->will($this->returnValue($httpKernel));

$kernel = $this->getMockBuilder('Symfony\Tests\Component\HttpKernel\KernelForTest')
->setConstructorArgs(array('dev', true, '-foo-'))
->setMethods(array('boot'))
->getMock();

$kernel->setContainer($container);

$testCase = $this;
$bootCallback = function() use ($masterRequest, $kernel, $testCase) {
$kernel->setBooted(true);
$testCase->assertSame($masterRequest, $kernel->getRequest(), '->handle() sets the Request before booting');
};

$kernel->expects($this->once())
->method('boot')
->will($this->returnCallback($bootCallback));

$kernel->handle($masterRequest);
$kernel->handle($subRequest, HttpKernelInterface::SUB_REQUEST);

$this->assertSame($masterRequest, $kernel->getRequest(), '->handle() restores the master Request after handling a sub-request');
}
}

class KernelForTest extends Kernel
Expand All @@ -48,4 +101,14 @@ public function registerBundleDirs()
public function registerContainerConfiguration(LoaderInterface $loader)
{
}

public function setBooted($booted)
{
$this->booted = $booted;
}

public function setContainer($container)
{
$this->container = $container;
}
}

0 comments on commit 7eea488

Please sign in to comment.