update 1.0.8.0

Commits for version update
This commit is contained in:
Manish Verma
2016-10-17 12:02:27 +05:30
parent dec927987b
commit 76e85db070
9674 changed files with 495757 additions and 58922 deletions

View File

@@ -21,7 +21,7 @@ interface CacheClearerInterface
/**
* Clears any caches necessary.
*
* @param string $cacheDir The cache directory.
* @param string $cacheDir The cache directory
*/
public function clear($cacheDir);
}

View File

@@ -26,7 +26,7 @@ class ChainCacheClearer implements CacheClearerInterface
/**
* Constructs a new instance of ChainCacheClearer.
*
* @param array $clearers The initial clearers.
* @param array $clearers The initial clearers
*/
public function __construct(array $clearers = array())
{

View File

@@ -20,7 +20,7 @@ abstract class CacheWarmer implements CacheWarmerInterface
{
protected function writeCacheFile($file, $content)
{
$tmpFile = tempnam(dirname($file), basename($file));
$tmpFile = @tempnam(dirname($file), basename($file));
if (false !== @file_put_contents($tmpFile, $content) && @rename($tmpFile, $file)) {
@chmod($file, 0666 & ~umask());

View File

@@ -53,7 +53,12 @@ class FragmentRendererPass implements CompilerPassInterface
$class = $container->getParameterBag()->resolveValue($def->getClass());
$interface = 'Symfony\Component\HttpKernel\Fragment\FragmentRendererInterface';
if (!is_subclass_of($class, $interface)) {
if (!class_exists($class, false)) {
throw new \InvalidArgumentException(sprintf('Class "%s" used for service "%s" cannot be found.', $class, $id));
}
throw new \InvalidArgumentException(sprintf('Service "%s" must implement interface "%s".', $id, $interface));
}

View File

@@ -28,8 +28,8 @@ class DumpListener implements EventSubscriberInterface
private $dumper;
/**
* @param ClonerInterface $cloner Cloner service.
* @param DataDumperInterface $dumper Dumper service.
* @param ClonerInterface $cloner Cloner service
* @param DataDumperInterface $dumper Dumper service
*/
public function __construct(ClonerInterface $cloner, DataDumperInterface $dumper)
{

View File

@@ -96,10 +96,10 @@ class ExceptionListener implements EventSubscriberInterface
/**
* Clones the request for the exception.
*
* @param \Exception $exception The thrown exception.
* @param Request $request The original request.
* @param \Exception $exception The thrown exception
* @param Request $request The original request
*
* @return Request $request The cloned request.
* @return Request $request The cloned request
*/
protected function duplicateRequest(\Exception $exception, Request $request)
{

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

@@ -129,6 +129,8 @@ class InlineFragmentRenderer extends RoutableFragmentRenderer
}
$server['REMOTE_ADDR'] = '127.0.0.1';
unset($server['HTTP_IF_MODIFIED_SINCE']);
unset($server['HTTP_IF_NONE_MATCH']);
$subRequest = Request::create($uri, 'get', array(), $cookies, array(), $server);
if ($request->headers->has('Surrogate-Capability')) {

View File

@@ -37,7 +37,7 @@ class Esi implements SurrogateInterface
/**
* Constructor.
*
* @param array $contentTypes An array of content-type that should be parsed for ESI information.
* @param array $contentTypes An array of content-type that should be parsed for ESI information
* (default: text/html, text/xml, application/xhtml+xml, and application/xml)
*/
public function __construct(array $contentTypes = array('text/html', 'text/xml', 'application/xhtml+xml', 'application/xml'))

View File

@@ -580,6 +580,9 @@ class HttpCache implements HttpKernelInterface, TerminableInterface
*/
protected function store(Request $request, Response $response)
{
if (!$response->headers->has('Date')) {
$response->setDate(\DateTime::createFromFormat('U', time()));
}
try {
$this->store->write($request, $response);

View File

@@ -31,7 +31,7 @@ class Ssi implements SurrogateInterface
/**
* Constructor.
*
* @param array $contentTypes An array of content-type that should be parsed for SSI information.
* @param array $contentTypes An array of content-type that should be parsed for SSI information
* (default: text/html, text/xml, application/xhtml+xml, and application/xml)
*/
public function __construct(array $contentTypes = array('text/html', 'text/xml', 'application/xhtml+xml', 'application/xml'))

View File

@@ -38,7 +38,7 @@ class Store implements StoreInterface
public function __construct($root)
{
$this->root = $root;
if (!is_dir($this->root) && !@mkdir($this->root, 0777, true) && !is_dir($this->root)) {
if (!file_exists($this->root) && !@mkdir($this->root, 0777, true) && !is_dir($this->root)) {
throw new \RuntimeException(sprintf('Unable to create the store directory (%s).', $this->root));
}
$this->keyCache = new \SplObjectStorage();
@@ -52,22 +52,15 @@ class Store implements StoreInterface
{
// unlock everything
foreach ($this->locks as $lock) {
if (file_exists($lock)) {
@unlink($lock);
}
flock($lock, LOCK_UN);
fclose($lock);
}
$error = error_get_last();
if (1 === $error['type'] && false === headers_sent()) {
// send a 503
header('HTTP/1.0 503 Service Unavailable');
header('Retry-After: 10');
echo '503 Service Unavailable';
}
$this->locks = array();
}
/**
* Locks the cache for a given Request.
* Tries to lock the cache for a given Request, without blocking.
*
* @param Request $request A Request instance
*
@@ -75,21 +68,24 @@ class Store implements StoreInterface
*/
public function lock(Request $request)
{
$path = $this->getPath($this->getCacheKey($request).'.lck');
if (!is_dir(dirname($path)) && false === @mkdir(dirname($path), 0777, true) && !is_dir(dirname($path))) {
return false;
$key = $this->getCacheKey($request);
if (!isset($this->locks[$key])) {
$path = $this->getPath($key);
if (!file_exists(dirname($path)) && false === @mkdir(dirname($path), 0777, true) && !is_dir(dirname($path))) {
return $path;
}
$h = fopen($path, 'cb');
if (!flock($h, LOCK_EX | LOCK_NB)) {
fclose($h);
return $path;
}
$this->locks[$key] = $h;
}
$lock = @fopen($path, 'x');
if (false !== $lock) {
fclose($lock);
$this->locks[] = $path;
return true;
}
return !file_exists($path) ?: $path;
return true;
}
/**
@@ -101,17 +97,37 @@ class Store implements StoreInterface
*/
public function unlock(Request $request)
{
$file = $this->getPath($this->getCacheKey($request).'.lck');
$key = $this->getCacheKey($request);
return is_file($file) ? @unlink($file) : false;
if (isset($this->locks[$key])) {
flock($this->locks[$key], LOCK_UN);
fclose($this->locks[$key]);
unset($this->locks[$key]);
return true;
}
return false;
}
public function isLocked(Request $request)
{
$path = $this->getPath($this->getCacheKey($request).'.lck');
clearstatcache(true, $path);
$key = $this->getCacheKey($request);
return is_file($path);
if (isset($this->locks[$key])) {
return true; // shortcut if lock held by this process
}
if (!file_exists($path = $this->getPath($key))) {
return false;
}
$h = fopen($path, 'rb');
flock($h, LOCK_EX | LOCK_NB, $wouldBlock);
flock($h, LOCK_UN); // release the lock we just acquired
fclose($h);
return (bool) $wouldBlock;
}
/**
@@ -144,7 +160,7 @@ class Store implements StoreInterface
}
list($req, $headers) = $match;
if (is_file($body = $this->getPath($headers['x-content-digest'][0]))) {
if (file_exists($body = $this->getPath($headers['x-content-digest'][0]))) {
return $this->restoreResponse($headers, $body);
}
@@ -291,7 +307,7 @@ class Store implements StoreInterface
*/
private function getMetadata($key)
{
if (false === $entries = $this->load($key)) {
if (!$entries = $this->load($key)) {
return array();
}
@@ -307,7 +323,15 @@ class Store implements StoreInterface
*/
public function purge($url)
{
if (is_file($path = $this->getPath($this->getCacheKey(Request::create($url))))) {
$key = $this->getCacheKey(Request::create($url));
if (isset($this->locks[$key])) {
flock($this->locks[$key], LOCK_UN);
fclose($this->locks[$key]);
unset($this->locks[$key]);
}
if (file_exists($path = $this->getPath($key))) {
unlink($path);
return true;
@@ -327,7 +351,7 @@ class Store implements StoreInterface
{
$path = $this->getPath($key);
return is_file($path) ? file_get_contents($path) : false;
return file_exists($path) ? file_get_contents($path) : false;
}
/**
@@ -341,23 +365,36 @@ class Store implements StoreInterface
private function save($key, $data)
{
$path = $this->getPath($key);
if (!is_dir(dirname($path)) && false === @mkdir(dirname($path), 0777, true) && !is_dir(dirname($path))) {
return false;
}
$tmpFile = tempnam(dirname($path), basename($path));
if (false === $fp = @fopen($tmpFile, 'wb')) {
return false;
}
@fwrite($fp, $data);
@fclose($fp);
if (isset($this->locks[$key])) {
$fp = $this->locks[$key];
@ftruncate($fp, 0);
@fseek($fp, 0);
$len = @fwrite($fp, $data);
if (strlen($data) !== $len) {
@ftruncate($fp, 0);
if ($data != file_get_contents($tmpFile)) {
return false;
}
return false;
}
} else {
if (!file_exists(dirname($path)) && false === @mkdir(dirname($path), 0777, true) && !is_dir(dirname($path))) {
return false;
}
if (false === @rename($tmpFile, $path)) {
return false;
$tmpFile = tempnam(dirname($path), basename($path));
if (false === $fp = @fopen($tmpFile, 'wb')) {
return false;
}
@fwrite($fp, $data);
@fclose($fp);
if ($data != file_get_contents($tmpFile)) {
return false;
}
if (false === @rename($tmpFile, $path)) {
return false;
}
}
@chmod($path, 0666 & ~umask());

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;
@@ -61,6 +63,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);

View File

@@ -59,11 +59,11 @@ abstract class Kernel implements KernelInterface, TerminableInterface
protected $startTime;
protected $loadClassCache;
const VERSION = '3.0.7';
const VERSION_ID = 30007;
const VERSION = '3.0.9';
const VERSION_ID = 30009;
const MAJOR_VERSION = 3;
const MINOR_VERSION = 0;
const RELEASE_VERSION = 7;
const RELEASE_VERSION = 9;
const EXTRA_VERSION = '';
const END_OF_MAINTENANCE = '07/2016';

View File

@@ -27,7 +27,7 @@ interface KernelInterface extends HttpKernelInterface, \Serializable
/**
* Returns an array of bundles to register.
*
* @return BundleInterface[] An array of bundle instances.
* @return BundleInterface[] An array of bundle instances
*/
public function registerBundles();

View File

@@ -11,6 +11,7 @@
namespace Symfony\Component\HttpKernel\Profiler;
use Symfony\Component\HttpFoundation\Exception\ConflictingHeadersException;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\DataCollector\DataCollectorInterface;
@@ -168,9 +169,13 @@ class Profiler
$profile = new Profile(substr(hash('sha256', uniqid(mt_rand(), true)), 0, 6));
$profile->setTime(time());
$profile->setUrl($request->getUri());
$profile->setIp($request->getClientIp());
$profile->setMethod($request->getMethod());
$profile->setStatusCode($response->getStatusCode());
try {
$profile->setIp($request->getClientIp());
} catch (ConflictingHeadersException $e) {
$profile->setIp('Unknown');
}
$response->headers->set('X-Debug-Token', $profile->getToken());

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

@@ -3,7 +3,6 @@
namespace Symfony\Component\HttpKernel\Tests\Fixtures\ExtensionPresentBundle\Command;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\HttpKernel\Bundle;
/**
* This command has a required parameter on the constructor and will be ignored by the default Bundle implementation.

View File

@@ -197,6 +197,19 @@ class InlineFragmentRendererTest extends \PHPUnit_Framework_TestCase
Request::setTrustedHeaderName(Request::HEADER_CLIENT_IP, $trustedHeaderName);
}
public function testHeadersPossiblyResultingIn304AreNotAssignedToSubrequest()
{
$expectedSubRequest = Request::create('/');
if (Request::getTrustedHeaderName(Request::HEADER_CLIENT_IP)) {
$expectedSubRequest->headers->set('x-forwarded-for', array('127.0.0.1'));
$expectedSubRequest->server->set('HTTP_X_FORWARDED_FOR', '127.0.0.1');
}
$strategy = new InlineFragmentRenderer($this->getKernelExpectingRequest($expectedSubRequest));
$request = Request::create('/', 'GET', array(), array(), array(), array('HTTP_IF_MODIFIED_SINCE' => 'Fri, 01 Jan 2016 00:00:00 GMT', 'HTTP_IF_NONE_MATCH' => '*'));
$strategy->render('/', $request);
}
}
class Bar

View File

@@ -181,6 +181,31 @@ class HttpCacheTest extends HttpCacheTestCase
$this->assertEquals(304, $this->response->getStatusCode());
}
public function testIncrementsMaxAgeWhenNoDateIsSpecifiedEventWhenUsingETag()
{
$this->setNextResponse(
200,
array(
'ETag' => '1234',
'Cache-Control' => 'public, s-maxage=60',
)
);
$this->request('GET', '/');
$this->assertHttpKernelIsCalled();
$this->assertEquals(200, $this->response->getStatusCode());
$this->assertTraceContains('miss');
$this->assertTraceContains('store');
sleep(2);
$this->request('GET', '/');
$this->assertHttpKernelIsNotCalled();
$this->assertEquals(200, $this->response->getStatusCode());
$this->assertTraceContains('fresh');
$this->assertEquals(2, $this->response->headers->get('Age'));
}
public function testValidatesPrivateResponsesCachedOnTheClient()
{
$this->setNextResponse(200, array(), '', function ($request, $response) {

View File

@@ -50,6 +50,9 @@ class HttpCacheTestCase extends \PHPUnit_Framework_TestCase
protected function tearDown()
{
if ($this->cache) {
$this->cache->getStore()->cleanup();
}
$this->kernel = null;
$this->cache = null;
$this->caches = null;

View File

@@ -19,6 +19,10 @@ class StoreTest extends \PHPUnit_Framework_TestCase
{
protected $request;
protected $response;
/**
* @var Store
*/
protected $store;
protected function setUp()

View File

@@ -260,6 +260,27 @@ class HttpKernelTest extends \PHPUnit_Framework_TestCase
$kernel->handle($request, HttpKernelInterface::MASTER_REQUEST);
}
/**
* @expectedException Symfony\Component\HttpKernel\Exception\BadRequestHttpException
*/
public function testInconsistentClientIpsOnMasterRequests()
{
$dispatcher = new EventDispatcher();
$dispatcher->addListener(KernelEvents::REQUEST, function ($event) {
$event->getRequest()->getClientIp();
});
$kernel = new HttpKernel($dispatcher, $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);
}
protected function getResolver($controller = null)
{
if (null === $controller) {

View File

@@ -18,7 +18,7 @@
"require": {
"php": ">=5.5.9",
"symfony/event-dispatcher": "~2.8|~3.0",
"symfony/http-foundation": "~2.8|~3.0",
"symfony/http-foundation": "~2.8.8|~3.0.8|~3.1.2|~3.2",
"symfony/debug": "~2.8|~3.0",
"psr/log": "~1.0"
},