Merge branch '3.0' into 3.1

* 3.0:
  [HttpKernel] Add listener that checks when request has both Forwarded and X-Forwarded-For
  [HttpKernel] Move conflicting origin IPs handling to catch block
  [travis] Fix deps=low/high patching
This commit is contained in:
Fabien Potencier 2016-06-30 11:40:26 +02:00
commit 080962f7ac
8 changed files with 119 additions and 25 deletions

View File

@ -1,19 +1,23 @@
<?php
if (4 > $_SERVER['argc']) {
echo "Usage: branch dir1 dir2 ... dirN\n";
echo "Usage: branch version dir1 dir2 ... dirN\n";
exit(1);
}
$dirs = $_SERVER['argv'];
array_shift($dirs);
$branch = array_shift($dirs);
$version = array_shift($dirs);
$packages = array();
$flags = PHP_VERSION_ID >= 50400 ? JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE : 0;
foreach ($dirs as $dir) {
if (!`git diff --name-only $branch...HEAD -- $dir`) {
if (!system("git diff --name-only $branch...HEAD -- $dir", $exitStatus)) {
if ($exitStatus) {
exit($exitStatus);
}
continue;
}
echo "$dir\n";
@ -32,7 +36,7 @@ foreach ($dirs as $dir) {
file_put_contents($dir.'/composer.json', $json);
passthru("cd $dir && tar -cf package.tar --exclude='package.tar' *");
$package->version = 'master' !== $branch ? $branch.'.x-dev' : 'dev-master';
$package->version = 'master' !== $version ? $version.'.x-dev' : 'dev-master';
$package->dist['type'] = 'tar';
$package->dist['url'] = 'file://'.__DIR__."/$dir/package.tar";

View File

@ -71,7 +71,7 @@ before_install:
install:
- if [[ ! $skip ]]; then COMPONENTS=$(find src/Symfony -mindepth 3 -type f -name phpunit.xml.dist -printf '%h\n'); fi
# Create local composer packages for each patched components and reference them in composer.json files when cross-testing components
- if [[ ! $skip && $deps ]]; then php .travis.php $TRAVIS_BRANCH $COMPONENTS; fi
- if [[ ! $skip && $deps ]]; then git fetch origin $TRAVIS_BRANCH && php .github/travis.php FETCH_HEAD $TRAVIS_BRANCH $COMPONENTS; fi
# For the master branch when deps=high, the version before master is checked out and tested with the locally patched components
- if [[ $deps = high && $TRAVIS_BRANCH = master ]]; then SYMFONY_VERSION=$(git ls-remote --heads | grep -o '/[1-9].*' | tail -n 1 | sed s/.//); else SYMFONY_VERSION=$(cat composer.json | grep '^ *"dev-master". *"[1-9]' | grep -o '[0-9.]*'); fi
- if [[ $deps = high && $TRAVIS_BRANCH = master ]]; then git fetch origin $SYMFONY_VERSION; git checkout -m FETCH_HEAD; COMPONENTS=$(find src/Symfony -mindepth 3 -type f -name phpunit.xml.dist -printf '%h\n'); ./phpunit install; fi

View File

@ -61,5 +61,9 @@
<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

@ -24,7 +24,7 @@
"symfony/config": "~2.8|~3.0",
"symfony/event-dispatcher": "~2.8|~3.0",
"symfony/http-foundation": "~3.1",
"symfony/http-kernel": "~3.1",
"symfony/http-kernel": "~3.1.2|~3.2",
"symfony/polyfill-mbstring": "~1.0",
"symfony/filesystem": "~2.8|~3.0",
"symfony/finder": "~2.8|~3.0",

View File

@ -0,0 +1,55 @@
<?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\HttpKernel\Event\GetResponseEvent;
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()) {
return;
}
$request = $event->getRequest();
if ($request::getTrustedProxies()) {
// This will throw an exception if the headers are inconsistent.
$request->getClientIps();
}
}
/**
* {@inheritdoc}
*/
public static function getSubscribedEvents()
{
return array(
KernelEvents::REQUEST => array(
array('onKernelRequest', 256),
),
);
}
}

View File

@ -67,6 +67,9 @@ class HttpKernel implements HttpKernelInterface, TerminableInterface
try {
return $this->handleRaw($request, $type);
} catch (\Exception $e) {
if ($e instanceof ConflictingHeadersException) {
$e = new BadRequestHttpException('The request headers contain conflicting information regarding the origin of this request.', $e);
}
if (false === $catch) {
$this->finishRequest($request, $type);
@ -119,13 +122,6 @@ 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

@ -0,0 +1,42 @@
<?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\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
{
/**
* @expectedException Symfony\Component\HttpFoundation\Exception\ConflictingHeadersException
*/
public function testListenerThrowsWhenMasterRequestHasInconsistentClientIps()
{
$dispatcher = new EventDispatcher();
$kernel = $this->getMock('Symfony\Component\HttpKernel\HttpKernelInterface');
$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');
$dispatcher->addListener(KernelEvents::REQUEST, array(new ValidateRequestListener(), 'onKernelRequest'));
$event = new GetResponseEvent($kernel, $request, HttpKernelInterface::MASTER_REQUEST);
$dispatcher->dispatch(KernelEvents::REQUEST, $event);
}
}

View File

@ -307,28 +307,21 @@ class HttpKernelTest extends \PHPUnit_Framework_TestCase
*/
public function testInconsistentClientIpsOnMasterRequests()
{
$kernel = $this->getHttpKernel(new EventDispatcher());
$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');
$dispatcher = new EventDispatcher();
$dispatcher->addListener(KernelEvents::REQUEST, function ($event) {
$event->getRequest()->getClientIp();
});
$kernel = $this->getHttpKernel($dispatcher);
$kernel->handle($request, $kernel::MASTER_REQUEST, false);
}
public function testInconsistentClientIpsOnSubRequests()
{
$kernel = $this->getHttpKernel(new EventDispatcher());
$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));
}
private function getHttpKernel(EventDispatcherInterface $eventDispatcher, $controller = null, RequestStack $requestStack = null, array $arguments = array())
{
if (null === $controller) {