Merge branch '2.7' into 2.8
* 2.7: [HttpKernel] Inline ValidateRequestListener logic into HttpKernel fixed HttpKernel dependencies after #18688 Conflicts: src/Symfony/Component/HttpKernel/composer.json
This commit is contained in:
commit
77053e7944
@ -46,9 +46,5 @@
|
|||||||
<argument type="service" id="request_stack" />
|
<argument type="service" id="request_stack" />
|
||||||
<tag name="kernel.event_subscriber" />
|
<tag name="kernel.event_subscriber" />
|
||||||
</service>
|
</service>
|
||||||
|
|
||||||
<service id="validate_request_listener" class="Symfony\Component\HttpKernel\EventListener\ValidateRequestListener">
|
|
||||||
<tag name="kernel.event_subscriber" />
|
|
||||||
</service>
|
|
||||||
</services>
|
</services>
|
||||||
</container>
|
</container>
|
||||||
|
@ -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),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
@ -12,6 +12,7 @@
|
|||||||
namespace Symfony\Component\HttpKernel;
|
namespace Symfony\Component\HttpKernel;
|
||||||
|
|
||||||
use Symfony\Component\HttpKernel\Controller\ControllerResolverInterface;
|
use Symfony\Component\HttpKernel\Controller\ControllerResolverInterface;
|
||||||
|
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
|
||||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||||
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
|
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
|
||||||
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
|
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\GetResponseForControllerResultEvent;
|
||||||
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
|
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
|
||||||
use Symfony\Component\HttpKernel\Event\PostResponseEvent;
|
use Symfony\Component\HttpKernel\Event\PostResponseEvent;
|
||||||
|
use Symfony\Component\HttpFoundation\Exception\ConflictingHeadersException;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
use Symfony\Component\HttpFoundation\RequestStack;
|
use Symfony\Component\HttpFoundation\RequestStack;
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
@ -113,6 +115,13 @@ class HttpKernel implements HttpKernelInterface, TerminableInterface
|
|||||||
*/
|
*/
|
||||||
private function handleRaw(Request $request, $type = self::MASTER_REQUEST)
|
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);
|
$this->requestStack->push($request);
|
||||||
|
|
||||||
// request
|
// request
|
||||||
|
@ -1,67 +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\HttpFoundation\Request;
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
@ -271,6 +271,33 @@ class HttpKernelTest extends \PHPUnit_Framework_TestCase
|
|||||||
$kernel->handle($request, HttpKernelInterface::MASTER_REQUEST);
|
$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)
|
protected function getResolver($controller = null)
|
||||||
{
|
{
|
||||||
if (null === $controller) {
|
if (null === $controller) {
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
"require": {
|
"require": {
|
||||||
"php": ">=5.3.9",
|
"php": ">=5.3.9",
|
||||||
"symfony/event-dispatcher": "~2.6,>=2.6.7|~3.0.0",
|
"symfony/event-dispatcher": "~2.6,>=2.6.7|~3.0.0",
|
||||||
"symfony/http-foundation": "~2.5,>=2.5.4|~3.0.0",
|
"symfony/http-foundation": "~2.8.8|~3.0.8",
|
||||||
"symfony/debug": "~2.6,>=2.6.2",
|
"symfony/debug": "~2.6,>=2.6.2",
|
||||||
"psr/log": "~1.0"
|
"psr/log": "~1.0"
|
||||||
},
|
},
|
||||||
|
Reference in New Issue
Block a user