[HttpKernel] Inline ValidateRequestListener logic into HttpKernel

This commit is contained in:
Nicolas Grekas 2016-06-29 10:45:14 +02:00
parent eae78e208a
commit 9d3ae85301
7 changed files with 38 additions and 128 deletions

View File

@ -46,9 +46,5 @@
<argument type="service" id="request_stack" />
<tag name="kernel.event_subscriber" />
</service>
<service id="validate_request_listener" class="Symfony\Component\HttpKernel\EventListener\ValidateRequestListener">
<tag name="kernel.event_subscriber" />
</service>
</services>
</container>

View File

@ -23,7 +23,7 @@
"symfony/event-dispatcher": "~2.5",
"symfony/finder": "~2.0,>=2.0.5",
"symfony/http-foundation": "~2.4.9|~2.5,>=2.5.4",
"symfony/http-kernel": "~2.7,>=2.7.15",
"symfony/http-kernel": "~2.7",
"symfony/filesystem": "~2.3",
"symfony/routing": "~2.6,>2.6.4",
"symfony/security-core": "~2.6.13|~2.7.9|~2.8",

View File

@ -1,56 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\HttpKernel\EventListener;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Exception\ConflictingHeadersException;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\HttpKernel\KernelEvents;
/**
* Validates that the headers and other information indicating the
* client IP address of a request are consistent.
*
* @author Magnus Nordlander <magnus@fervo.se>
*/
class ValidateRequestListener implements EventSubscriberInterface
{
/**
* Performs the validation.
*
* @param GetResponseEvent $event
*/
public function onKernelRequest(GetResponseEvent $event)
{
if ($event->isMasterRequest()) {
try {
// This will throw an exception if the headers are inconsistent.
$event->getRequest()->getClientIps();
} catch (ConflictingHeadersException $e) {
throw new BadRequestHttpException('The request headers contain conflicting information regarding the origin of this request.', $e);
}
}
}
/**
* {@inheritdoc}
*/
public static function getSubscribedEvents()
{
return array(
KernelEvents::REQUEST => array(
array('onKernelRequest', 256),
),
);
}
}

View File

@ -12,6 +12,7 @@
namespace Symfony\Component\HttpKernel;
use Symfony\Component\HttpKernel\Controller\ControllerResolverInterface;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
@ -21,6 +22,7 @@ use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent;
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
use Symfony\Component\HttpKernel\Event\PostResponseEvent;
use Symfony\Component\HttpFoundation\Exception\ConflictingHeadersException;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Response;
@ -113,6 +115,13 @@ class HttpKernel implements HttpKernelInterface, TerminableInterface
*/
private function handleRaw(Request $request, $type = self::MASTER_REQUEST)
{
if (self::MASTER_REQUEST === $type && $request::getTrustedProxies()) {
try {
$request->getClientIps();
} catch (ConflictingHeadersException $e) {
throw new BadRequestHttpException('The request headers contain conflicting information regarding the origin of this request.', $e);
}
}
$this->requestStack->push($request);
// request

View File

@ -1,66 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\HttpKernel\Tests\EventListener;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\HttpFoundation\Exception\ConflictingHeadersException;
use Symfony\Component\HttpKernel\EventListener\ValidateRequestListener;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\HttpKernel\KernelEvents;
class ValidateRequestListenerTest extends \PHPUnit_Framework_TestCase
{
public function testListenerThrowsWhenMasterRequestHasInconsistentClientIps()
{
$dispatcher = new EventDispatcher();
$kernel = $this->getMock('Symfony\Component\HttpKernel\HttpKernelInterface');
$listener = new ValidateRequestListener();
$request = $this->getMock('Symfony\Component\HttpFoundation\Request');
$request->method('getClientIps')
->will($this->throwException(new ConflictingHeadersException()));
$dispatcher->addListener(KernelEvents::REQUEST, array($listener, 'onKernelRequest'));
$event = new GetResponseEvent($kernel, $request, HttpKernelInterface::MASTER_REQUEST);
$this->setExpectedException('Symfony\Component\HttpKernel\Exception\BadRequestHttpException');
$dispatcher->dispatch(KernelEvents::REQUEST, $event);
}
public function testListenerDoesNothingOnValidRequests()
{
$dispatcher = new EventDispatcher();
$kernel = $this->getMock('Symfony\Component\HttpKernel\HttpKernelInterface');
$listener = new ValidateRequestListener();
$request = $this->getMock('Symfony\Component\HttpFoundation\Request');
$request->method('getClientIps')
->willReturn(array('127.0.0.1'));
$dispatcher->addListener(KernelEvents::REQUEST, array($listener, 'onKernelRequest'));
$event = new GetResponseEvent($kernel, $request, HttpKernelInterface::MASTER_REQUEST);
$dispatcher->dispatch(KernelEvents::REQUEST, $event);
}
public function testListenerDoesNothingOnSubrequests()
{
$dispatcher = new EventDispatcher();
$kernel = $this->getMock('Symfony\Component\HttpKernel\HttpKernelInterface');
$listener = new ValidateRequestListener();
$request = $this->getMock('Symfony\Component\HttpFoundation\Request');
$request->method('getClientIps')
->will($this->throwException(new ConflictingHeadersException()));
$dispatcher->addListener(KernelEvents::REQUEST, array($listener, 'onKernelRequest'));
$event = new GetResponseEvent($kernel, $request, HttpKernelInterface::SUB_REQUEST);
$dispatcher->dispatch(KernelEvents::REQUEST, $event);
}
}

View File

@ -271,6 +271,33 @@ class HttpKernelTest extends \PHPUnit_Framework_TestCase
$kernel->handle($request, HttpKernelInterface::MASTER_REQUEST);
}
/**
* @expectedException Symfony\Component\HttpKernel\Exception\BadRequestHttpException
*/
public function testInconsistentClientIpsOnMasterRequests()
{
$kernel = new HttpKernel(new EventDispatcher(), $this->getResolver());
$request = new Request();
$request->setTrustedProxies(array('1.1.1.1'));
$request->server->set('REMOTE_ADDR', '1.1.1.1');
$request->headers->set('FORWARDED', '2.2.2.2');
$request->headers->set('X_FORWARDED_FOR', '3.3.3.3');
$kernel->handle($request, $kernel::MASTER_REQUEST, false);
}
public function testInconsistentClientIpsOnSubRequests()
{
$kernel = new HttpKernel(new EventDispatcher(), $this->getResolver());
$request = new Request();
$request->setTrustedProxies(array('1.1.1.1'));
$request->server->set('REMOTE_ADDR', '1.1.1.1');
$request->headers->set('FORWARDED', '2.2.2.2');
$request->headers->set('X_FORWARDED_FOR', '3.3.3.3');
$this->assertInstanceOf('Symfony\Component\HttpFoundation\Response', $kernel->handle($request, $kernel::SUB_REQUEST, false));
}
protected function getResolver($controller = null)
{
if (null === $controller) {

View File

@ -18,7 +18,7 @@
"require": {
"php": ">=5.3.9",
"symfony/event-dispatcher": "~2.6,>=2.6.7",
"symfony/http-foundation": "~2.7,>=2.7.15",
"symfony/http-foundation": "~2.7.15|~2.8.8",
"symfony/debug": "~2.6,>=2.6.2",
"psr/log": "~1.0"
},