/vendor/symfony/src/Symfony/Component/HttpKernel/bootstrap_cache.php
PHP | 2484 lines | 2484 code | 0 blank | 0 comment | 227 complexity | 1930940b3e76a2316b0e82b015a8c584 MD5 | raw file
Possible License(s): LGPL-2.1, LGPL-3.0, ISC, BSD-3-Clause
Large files files are truncated, but you can click here to view the full file
- <?php
- namespace Symfony\Component\HttpKernel
- {
- use Symfony\Component\DependencyInjection\ContainerInterface;
- use Symfony\Component\DependencyInjection\Loader\LoaderInterface;
- use Symfony\Component\HttpKernel\HttpKernelInterface;
- use Symfony\Component\HttpKernel\Bundle\BundleInterface;
- interface KernelInterface extends HttpKernelInterface, \Serializable
- {
- function registerRootDir();
- function registerBundles();
- function registerContainerConfiguration(LoaderInterface $loader);
- function boot();
- function shutdown();
- function getBundles();
- function isClassInActiveBundle($class);
- function getBundle($name, $first = true);
- function locateResource($name, $dir = null, $first = true);
- function getName();
- function getEnvironment();
- function isDebug();
- function getRootDir();
- function getContainer();
- function getStartTime();
- function getCacheDir();
- function getLogDir();
- }
- }
- namespace Symfony\Component\HttpKernel
- {
- use Symfony\Component\DependencyInjection\ContainerInterface;
- use Symfony\Component\DependencyInjection\ContainerBuilder;
- use Symfony\Component\DependencyInjection\Dumper\PhpDumper;
- use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
- use Symfony\Component\DependencyInjection\Loader\DelegatingLoader;
- use Symfony\Component\DependencyInjection\Loader\LoaderResolver;
- use Symfony\Component\DependencyInjection\Loader\LoaderInterface;
- use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
- use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
- use Symfony\Component\DependencyInjection\Loader\IniFileLoader;
- use Symfony\Component\DependencyInjection\Loader\PhpFileLoader;
- use Symfony\Component\DependencyInjection\Loader\ClosureLoader;
- use Symfony\Component\HttpFoundation\Request;
- use Symfony\Component\HttpKernel\HttpKernelInterface;
- use Symfony\Component\HttpKernel\Bundle\BundleInterface;
- abstract class Kernel implements KernelInterface
- {
- protected $bundles;
- protected $bundleMap;
- protected $container;
- protected $rootDir;
- protected $environment;
- protected $debug;
- protected $booted;
- protected $name;
- protected $startTime;
- const VERSION = '2.0.0-DEV';
- public function __construct($environment, $debug)
- {
- $this->environment = $environment;
- $this->debug = (Boolean) $debug;
- $this->booted = false;
- $this->rootDir = realpath($this->registerRootDir());
- $this->name = preg_replace('/[^a-zA-Z0-9_]+/', '', basename($this->rootDir));
- if ($this->debug) {
- ini_set('display_errors', 1);
- error_reporting(-1);
- $this->startTime = microtime(true);
- } else {
- ini_set('display_errors', 0);
- }
- }
- public function __clone()
- {
- if ($this->debug) {
- $this->startTime = microtime(true);
- }
- $this->booted = false;
- $this->container = null;
- }
- public function boot()
- {
- if (true === $this->booted) {
- return;
- }
- $this->initializeBundles();
- $this->initializeContainer();
- foreach ($this->bundles as $bundle) {
- $bundle->setContainer($this->container);
- $bundle->boot();
- }
- $this->booted = true;
- }
- public function shutdown()
- {
- $this->booted = false;
- foreach ($this->bundles as $bundle) {
- $bundle->shutdown();
- $bundle->setContainer(null);
- }
- $this->container = null;
- }
- public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = true)
- {
- if (false === $this->booted) {
- $this->boot();
- }
- return $this->container->get('http_kernel')->handle($request, $type, $catch);
- }
- public function getBundles()
- {
- return $this->bundles;
- }
- public function isClassInActiveBundle($class)
- {
- foreach ($this->bundles as $bundle) {
- $bundleClass = get_class($bundle);
- if (0 === strpos($class, substr($bundleClass, 0, strrpos($bundleClass, '\\')))) {
- return true;
- }
- }
- return false;
- }
- public function getBundle($name, $first = true)
- {
- if (!isset($this->bundleMap[$name])) {
- throw new \InvalidArgumentException(sprintf('Bundle "%s" does not exist or it is not enabled.', $name));
- }
- if (true === $first) {
- return $this->bundleMap[$name][0];
- } elseif (false === $first) {
- return $this->bundleMap[$name];
- }
- }
- public function locateResource($name, $dir = null, $first = true)
- {
- if ('@' !== $name[0]) {
- throw new \InvalidArgumentException(sprintf('A resource name must start with @ ("%s" given).', $name));
- }
- if (false !== strpos($name, '..')) {
- throw new \RuntimeException(sprintf('File name "%s" contains invalid characters (..).', $name));
- }
- $name = substr($name, 1);
- list($bundle, $path) = explode('/', $name, 2);
- $isResource = 0 === strpos($path, 'Resources');
- $files = array();
- if (true === $isResource && null !== $dir && file_exists($file = $dir.'/'.$bundle.'/'.substr($path, 10))) {
- if ($first) {
- return $file;
- }
- $files[] = $file;
- }
- foreach ($this->getBundle($bundle, false) as $bundle) {
- if (file_exists($file = $bundle->getNormalizedPath().'/'.$path)) {
- if ($first) {
- return $file;
- }
- $files[] = $file;
- }
- }
- if ($files) {
- return $files;
- }
- throw new \InvalidArgumentException(sprintf('Unable to find file "@%s".', $name));
- }
- public function getName()
- {
- return $this->name;
- }
- public function getEnvironment()
- {
- return $this->environment;
- }
- public function isDebug()
- {
- return $this->debug;
- }
- public function getRootDir()
- {
- return $this->rootDir;
- }
- public function getContainer()
- {
- return $this->container;
- }
- public function getStartTime()
- {
- return $this->debug ? $this->startTime : -INF;
- }
- public function getCacheDir()
- {
- return $this->rootDir.'/cache/'.$this->environment;
- }
- public function getLogDir()
- {
- return $this->rootDir.'/logs';
- }
- protected function initializeBundles()
- {
- $this->bundles = array();
- $topMostBundles = array();
- $directChildren = array();
- foreach ($this->registerBundles() as $bundle) {
- $name = $bundle->getName();
- if (isset($this->bundles[$name])) {
- throw new \LogicException(sprintf('Trying to register two bundles with the same name "%s"', $name));
- }
- $this->bundles[$name] = $bundle;
- if ($parentName = $bundle->getParent()) {
- if (isset($directChildren[$parentName])) {
- throw new \LogicException(sprintf('Bundle "%s" is directly extended by two bundles "%s" and "%s".', $parentName, $name, $directChildren[$parentName]));
- }
- $directChildren[$parentName] = $name;
- } else {
- $topMostBundles[$name] = $bundle;
- }
- }
- if (count($diff = array_diff(array_keys($directChildren), array_keys($this->bundles)))) {
- throw new \LogicException(sprintf('Bundle "%s" extends bundle "%s", which is not registered.', $directChildren[$diff[0]], $diff[0]));
- }
- $this->bundleMap = array();
- foreach ($topMostBundles as $name => $bundle) {
- $bundleMap = array($bundle);
- $hierarchy = array($name);
- while (isset($directChildren[$name])) {
- $name = $directChildren[$name];
- array_unshift($bundleMap, $this->bundles[$name]);
- $hierarchy[] = $name;
- }
- foreach ($hierarchy as $bundle) {
- $this->bundleMap[$bundle] = $bundleMap;
- array_pop($bundleMap);
- }
- }
- }
- protected function initializeContainer()
- {
- $class = $this->name.ucfirst($this->environment).($this->debug ? 'Debug' : '').'ProjectContainer';
- $location = $this->getCacheDir().'/'.$class;
- $reload = $this->debug ? $this->needsReload($class, $location) : false;
- $fresh = false;
- if ($reload || !file_exists($location.'.php')) {
- $container = $this->buildContainer();
- $this->dumpContainer($container, $class, $location.'.php');
- $fresh = true;
- }
- require_once $location.'.php';
- $this->container = new $class();
- $this->container->set('kernel', $this);
- if ($fresh && 'cli' !== php_sapi_name()) {
- $this->container->get('cache_warmer')->warmUp($this->container->getParameter('kernel.cache_dir'));
- }
- }
- protected function getKernelParameters()
- {
- $bundles = array();
- foreach ($this->bundles as $name => $bundle) {
- $bundles[$name] = get_class($bundle);
- }
- return array_merge(
- array(
- 'kernel.root_dir' => $this->rootDir,
- 'kernel.environment' => $this->environment,
- 'kernel.debug' => $this->debug,
- 'kernel.name' => $this->name,
- 'kernel.cache_dir' => $this->getCacheDir(),
- 'kernel.logs_dir' => $this->getLogDir(),
- 'kernel.bundles' => $bundles,
- 'kernel.charset' => 'UTF-8',
- ),
- $this->getEnvParameters()
- );
- }
- protected function getEnvParameters()
- {
- $parameters = array();
- foreach ($_SERVER as $key => $value) {
- if ('SYMFONY__' === substr($key, 0, 9)) {
- $parameters[strtolower(str_replace('__', '.', substr($key, 9)))] = $value;
- }
- }
- return $parameters;
- }
- protected function needsReload($class, $location)
- {
- if (!file_exists($location.'.meta') || !file_exists($location.'.php')) {
- return true;
- }
- $meta = unserialize(file_get_contents($location.'.meta'));
- $time = filemtime($location.'.php');
- foreach ($meta as $resource) {
- if (!$resource->isUptodate($time)) {
- return true;
- }
- }
- return false;
- }
- protected function buildContainer()
- {
- $parameterBag = new ParameterBag($this->getKernelParameters());
- $container = new ContainerBuilder($parameterBag);
- foreach ($this->bundles as $bundle) {
- $bundle->registerExtensions($container);
- if ($this->debug) {
- $container->addObjectResource($bundle);
- }
- }
- if (null !== $cont = $this->registerContainerConfiguration($this->getContainerLoader($container))) {
- $container->merge($cont);
- }
- $container->compile();
- return $container;
- }
- protected function dumpContainer(ContainerBuilder $container, $class, $file)
- {
- foreach (array('cache', 'logs') as $name) {
- $dir = $container->getParameter(sprintf('kernel.%s_dir', $name));
- if (!is_dir($dir)) {
- if (false === @mkdir($dir, 0777, true)) {
- die(sprintf('Unable to create the %s directory (%s)', $name, dirname($dir)));
- }
- } elseif (!is_writable($dir)) {
- die(sprintf('Unable to write in the %s directory (%s)', $name, $dir));
- }
- }
- $dumper = new PhpDumper($container);
- $content = $dumper->dump(array('class' => $class));
- if (!$this->debug) {
- $content = self::stripComments($content);
- }
- $this->writeCacheFile($file, $content);
- if ($this->debug) {
- $container->addObjectResource($this);
- $this->writeCacheFile($this->getCacheDir().'/'.$class.'.meta', serialize($container->getResources()));
- }
- }
- protected function getContainerLoader(ContainerInterface $container)
- {
- $resolver = new LoaderResolver(array(
- new XmlFileLoader($container),
- new YamlFileLoader($container),
- new IniFileLoader($container),
- new PhpFileLoader($container),
- new ClosureLoader($container),
- ));
- return new DelegatingLoader($resolver);
- }
- static public function stripComments($source)
- {
- if (!function_exists('token_get_all')) {
- return $source;
- }
- $output = '';
- foreach (token_get_all($source) as $token) {
- if (is_string($token)) {
- $output .= $token;
- } elseif (!in_array($token[0], array(T_COMMENT, T_DOC_COMMENT))) {
- $output .= $token[1];
- }
- }
- $output = preg_replace(array('/\s+$/Sm', '/\n+/S'), "\n", $output);
- return $output;
- }
- protected function writeCacheFile($file, $content)
- {
- $tmpFile = tempnam(dirname($file), basename($file));
- if (false !== @file_put_contents($tmpFile, $content) && @rename($tmpFile, $file)) {
- chmod($file, 0644);
- return;
- }
- throw new \RuntimeException(sprintf('Failed to write cache file "%s".', $file));
- }
- public function serialize()
- {
- return serialize(array($this->environment, $this->debug));
- }
- public function unserialize($data)
- {
- list($environment, $debug) = unserialize($data);
- $this->__construct($environment, $debug);
- }
- }
- }
- namespace Symfony\Component\HttpKernel
- {
- use Symfony\Component\HttpFoundation\Request;
- interface HttpKernelInterface
- {
- const MASTER_REQUEST = 1;
- const SUB_REQUEST = 2;
- function handle(Request $request, $type = self::MASTER_REQUEST, $catch = true);
- }
- }
- namespace Symfony\Component\HttpKernel\HttpCache
- {
- use Symfony\Component\HttpKernel\HttpKernelInterface;
- use Symfony\Component\HttpFoundation\Request;
- use Symfony\Component\HttpFoundation\Response;
- class HttpCache implements HttpKernelInterface
- {
- protected $kernel;
- protected $traces;
- protected $store;
- protected $request;
- protected $esi;
- public function __construct(HttpKernelInterface $kernel, StoreInterface $store, Esi $esi = null, array $options = array())
- {
- $this->store = $store;
- $this->kernel = $kernel;
- register_shutdown_function(array($this->store, 'cleanup'));
- $this->options = array_merge(array(
- 'debug' => false,
- 'default_ttl' => 0,
- 'private_headers' => array('Authorization', 'Cookie'),
- 'allow_reload' => false,
- 'allow_revalidate' => false,
- 'stale_while_revalidate' => 2,
- 'stale_if_error' => 60,
- ), $options);
- $this->esi = $esi;
- }
- public function getTraces()
- {
- return $this->traces;
- }
- public function getLog()
- {
- $log = array();
- foreach ($this->traces as $request => $traces) {
- $log[] = sprintf('%s: %s', $request, implode(', ', $traces));
- }
- return implode('; ', $log);
- }
- public function getRequest()
- {
- return $this->request;
- }
- public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = true)
- {
- if (HttpKernelInterface::MASTER_REQUEST === $type) {
- $this->traces = array();
- $this->request = $request;
- }
- $path = $request->getPathInfo();
- if ($qs = $request->getQueryString()) {
- $path .= '?'.$qs;
- }
- $this->traces[$request->getMethod().' '.$path] = array();
- if (!$request->isMethodSafe($request)) {
- $response = $this->invalidate($request, $catch);
- } elseif ($request->headers->has('expect')) {
- $response = $this->pass($request, $catch);
- } else {
- $response = $this->lookup($request, $catch);
- }
- $response->isNotModified($request);
- $this->restoreResponseBody($request, $response);
- if (HttpKernelInterface::MASTER_REQUEST === $type && $this->options['debug']) {
- $response->headers->set('X-Symfony-Cache', $this->getLog());
- }
- return $response;
- }
- protected function pass(Request $request, $catch = false)
- {
- $this->record($request, 'pass');
- return $this->forward($request, $catch);
- }
- protected function invalidate(Request $request, $catch = false)
- {
- $response = $this->pass($request, $catch);
- if ($response->isSuccessful() || $response->isRedirect()) {
- try {
- $this->store->invalidate($request, $catch);
- $this->record($request, 'invalidate');
- } catch (\Exception $e) {
- $this->record($request, 'invalidate-failed');
- if ($this->options['debug']) {
- throw $e;
- }
- }
- }
- return $response;
- }
- protected function lookup(Request $request, $catch = false)
- {
- if ($this->options['allow_reload'] && $request->isNoCache()) {
- $this->record($request, 'reload');
- return $this->fetch($request);
- }
- try {
- $entry = $this->store->lookup($request);
- } catch (\Exception $e) {
- $this->record($request, 'lookup-failed');
- if ($this->options['debug']) {
- throw $e;
- }
- return $this->pass($request, $catch);
- }
- if (null === $entry) {
- $this->record($request, 'miss');
- return $this->fetch($request, $catch);
- }
- if (!$this->isFreshEnough($request, $entry)) {
- $this->record($request, 'stale');
- return $this->validate($request, $entry);
- }
- $this->record($request, 'fresh');
- $entry->headers->set('Age', $entry->getAge());
- return $entry;
- }
- protected function validate(Request $request, Response $entry)
- {
- $subRequest = clone $request;
- $subRequest->setMethod('get');
- $subRequest->headers->set('if_modified_since', $entry->headers->get('Last-Modified'));
- $cachedEtags = array($entry->getEtag());
- $requestEtags = $request->getEtags();
- $etags = array_unique(array_merge($cachedEtags, $requestEtags));
- $subRequest->headers->set('if_none_match', $etags ? implode(', ', $etags) : '');
- $response = $this->forward($subRequest, false, $entry);
- if (304 == $response->getStatusCode()) {
- $this->record($request, 'valid');
- $etag = $response->getEtag();
- if ($etag && in_array($etag, $requestEtags) && !in_array($etag, $cachedEtags)) {
- return $response;
- }
- $entry = clone $entry;
- $entry->headers->remove('Date');
- foreach (array('Date', 'Expires', 'Cache-Control', 'ETag', 'Last-Modified') as $name) {
- if ($response->headers->has($name)) {
- $entry->headers->set($name, $response->headers->get($name));
- }
- }
- $response = $entry;
- } else {
- $this->record($request, 'invalid');
- }
- if ($response->isCacheable()) {
- $this->store($request, $response);
- }
- return $response;
- }
- protected function fetch(Request $request, $catch = false)
- {
- $subRequest = clone $request;
- $subRequest->setMethod('get');
- $subRequest->headers->remove('if_modified_since');
- $subRequest->headers->remove('if_none_match');
- $response = $this->forward($subRequest, $catch);
- if ($this->isPrivateRequest($request) && !$response->headers->hasCacheControlDirective('public')) {
- $response->setPrivate(true);
- } elseif ($this->options['default_ttl'] > 0 && null === $response->getTtl() && !$response->headers->getCacheControlDirective('must-revalidate')) {
- $response->setTtl($this->options['default_ttl']);
- }
- if ($response->isCacheable()) {
- $this->store($request, $response);
- }
- return $response;
- }
- protected function forward(Request $request, $catch = false, Response $entry = null)
- {
- if ($this->esi) {
- $this->esi->addSurrogateEsiCapability($request);
- }
- $response = $this->kernel->handle($request, HttpKernelInterface::MASTER_REQUEST, $catch);
- if (null !== $entry && in_array($response->getStatusCode(), array(500, 502, 503, 504))) {
- if (null === $age = $entry->headers->getCacheControlDirective('stale-if-error')) {
- $age = $this->options['stale_if_error'];
- }
- if (abs($entry->getTtl()) < $age) {
- $this->record($request, 'stale-if-error');
- return $entry;
- }
- }
- $this->processResponseBody($request, $response);
- return $response;
- }
- protected function isFreshEnough(Request $request, Response $entry)
- {
- if (!$entry->isFresh()) {
- return $this->lock($request, $entry);
- }
- if ($this->options['allow_revalidate'] && null !== $maxAge = $request->headers->getCacheControlDirective('max-age')) {
- return $maxAge > 0 && $maxAge >= $entry->getAge();
- }
- return true;
- }
- protected function lock(Request $request, Response $entry)
- {
- $lock = $this->store->lock($request, $entry);
- if (true !== $lock) {
- if (null === $age = $entry->headers->getCacheControlDirective('stale-while-revalidate')) {
- $age = $this->options['stale_while_revalidate'];
- }
- if (abs($entry->getTtl()) < $age) {
- $this->record($request, 'stale-while-revalidate');
- return true;
- } else {
- $wait = 0;
- while (file_exists($lock) && $wait < 5000000) {
- usleep($wait += 50000);
- }
- if ($wait < 2000000) {
- $new = $this->lookup($request);
- $entry->headers = $new->headers;
- $entry->setContent($new->getContent());
- $entry->setStatusCode($new->getStatusCode());
- $entry->setProtocolVersion($new->getProtocolVersion());
- $entry->setCookies($new->getCookies());
- return true;
- } else {
- $entry->setStatusCode(503);
- $entry->setContent('503 Service Unavailable');
- $entry->headers->set('Retry-After', 10);
- return true;
- }
- }
- }
- return false;
- }
- protected function store(Request $request, Response $response)
- {
- try {
- $this->store->write($request, $response);
- $this->record($request, 'store');
- $response->headers->set('Age', $response->getAge());
- } catch (\Exception $e) {
- $this->record($request, 'store-failed');
- if ($this->options['debug']) {
- throw $e;
- }
- }
- $this->store->unlock($request);
- }
- protected function restoreResponseBody(Request $request, Response $response)
- {
- if ('head' === strtolower($request->getMethod())) {
- $response->setContent('');
- $response->headers->remove('X-Body-Eval');
- $response->headers->remove('X-Body-File');
- return;
- }
- if ($response->headers->has('X-Body-Eval')) {
- ob_start();
- if ($response->headers->has('X-Body-File')) {
- include $response->headers->get('X-Body-File');
- } else {
- eval('; ?>'.$response->getContent().'<?php ;');
- }
- $response->setContent(ob_get_clean());
- $response->headers->remove('X-Body-Eval');
- } elseif ($response->headers->has('X-Body-File')) {
- $response->setContent(file_get_contents($response->headers->get('X-Body-File')));
- } else {
- return;
- }
- $response->headers->remove('X-Body-File');
- if (!$response->headers->has('Transfer-Encoding')) {
- $response->headers->set('Content-Length', strlen($response->getContent()));
- }
- }
- protected function processResponseBody(Request $request, Response $response)
- {
- if (null !== $this->esi && $this->esi->needsEsiParsing($response)) {
- $this->esi->process($request, $response);
- }
- }
- protected function isPrivateRequest(Request $request)
- {
- foreach ($this->options['private_headers'] as $key) {
- $key = strtolower(str_replace('HTTP_', '', $key));
- if ('cookie' === $key) {
- if (count($request->cookies->all())) {
- return true;
- }
- } elseif ($request->headers->has($key)) {
- return true;
- }
- }
- return false;
- }
- protected function record(Request $request, $event)
- {
- $path = $request->getPathInfo();
- if ($qs = $request->getQueryString()) {
- $path .= '?'.$qs;
- }
- $this->traces[$request->getMethod().' '.$path][] = $event;
- }
- }
- }
- namespace Symfony\Component\HttpKernel\HttpCache
- {
- use Symfony\Component\HttpFoundation\Request;
- use Symfony\Component\HttpFoundation\Response;
- use Symfony\Component\HttpFoundation\HeaderBag;
- interface StoreInterface
- {
- function lookup(Request $request);
- function write(Request $request, Response $response);
- function invalidate(Request $request);
- function lock(Request $request);
- function unlock(Request $request);
- function purge($url);
- function cleanup();
- }
- }
- namespace Symfony\Component\HttpKernel\HttpCache
- {
- use Symfony\Component\HttpFoundation\Request;
- use Symfony\Component\HttpFoundation\Response;
- use Symfony\Component\HttpFoundation\HeaderBag;
- class Store implements StoreInterface
- {
- protected $root;
- protected $keyCache;
- protected $locks;
- public function __construct($root)
- {
- $this->root = $root;
- if (!is_dir($this->root)) {
- mkdir($this->root, 0777, true);
- }
- $this->keyCache = new \SplObjectStorage();
- $this->locks = array();
- }
- public function cleanup()
- {
- foreach ($this->locks as $lock) {
- @unlink($lock);
- }
- $error = error_get_last();
- if (1 === $error['type'] && false === headers_sent()) {
- header('HTTP/1.0 503 Service Unavailable');
- header('Retry-After: 10');
- echo '503 Service Unavailable';
- }
- }
- public function lock(Request $request)
- {
- if (false !== $lock = @fopen($path = $this->getPath($this->getCacheKey($request).'.lck'), 'x')) {
- fclose($lock);
- $this->locks[] = $path;
- return true;
- } else {
- return $path;
- }
- }
- public function unlock(Request $request)
- {
- return @unlink($this->getPath($this->getCacheKey($request).'.lck'));
- }
- public function lookup(Request $request)
- {
- $key = $this->getCacheKey($request);
- if (!$entries = $this->getMetadata($key)) {
- return null;
- }
- $match = null;
- foreach ($entries as $entry) {
- if ($this->requestsMatch(isset($entry[1]['vary']) ? $entry[1]['vary'][0] : '', $request->headers->all(), $entry[0])) {
- $match = $entry;
- break;
- }
- }
- if (null === $match) {
- return null;
- }
- list($req, $headers) = $match;
- if (file_exists($body = $this->getPath($headers['x-content-digest'][0]))) {
- return $this->restoreResponse($headers, $body);
- } else {
- return null;
- }
- }
- public function write(Request $request, Response $response)
- {
- $key = $this->getCacheKey($request);
- $storedEnv = $this->persistRequest($request);
- if (!$response->headers->has('X-Content-Digest')) {
- $digest = 'en'.sha1($response->getContent());
- if (false === $this->save($digest, $response->getContent())) {
- throw new \RuntimeException('Unable to store the entity.');
- }
- $response->headers->set('X-Content-Digest', $digest);
- if (!$response->headers->has('Transfer-Encoding')) {
- $response->headers->set('Content-Length', strlen($response->getContent()));
- }
- }
- $entries = array();
- $vary = $response->headers->get('vary');
- foreach ($this->getMetadata($key) as $entry) {
- if (!isset($entry[1]['vary'])) {
- $entry[1]['vary'] = array('');
- }
- if ($vary != $entry[1]['vary'][0] || !$this->requestsMatch($vary, $entry[0], $storedEnv)) {
- $entries[] = $entry;
- }
- }
- $headers = $this->persistResponse($response);
- unset($headers['age']);
- array_unshift($entries, array($storedEnv, $headers));
- if (false === $this->save($key, serialize($entries))) {
- throw new \RuntimeException('Unable to store the metadata.');
- }
- return $key;
- }
- public function invalidate(Request $request)
- {
- $modified = false;
- $key = $this->getCacheKey($request);
- $entries = array();
- foreach ($this->getMetadata($key) as $entry) {
- $response = $this->restoreResponse($entry[1]);
- if ($response->isFresh()) {
- $response->expire();
- $modified = true;
- $entries[] = array($entry[0], $this->persistResponse($response));
- } else {
- $entries[] = $entry;
- }
- }
- if ($modified) {
- if (false === $this->save($key, serialize($entries))) {
- throw new \RuntimeException('Unable to store the metadata.');
- }
- }
- foreach (array('Location', 'Content-Location') as $header) {
- if ($uri = $request->headers->get($header)) {
- $subRequest = Request::create($uri, 'get', array(), array(), array(), $request->server->all());
- $this->invalidate($subRequest);
- }
- }
- }
- protected function requestsMatch($vary, $env1, $env2)
- {
- if (empty($vary)) {
- return true;
- }
- foreach (preg_split('/[\s,]+/', $vary) as $header) {
- $key = strtr(strtolower($header), '_', '-');
- $v1 = isset($env1[$key]) ? $env1[$key] : null;
- $v2 = isset($env2[$key]) ? $env2[$key] : null;
- if ($v1 !== $v2) {
- return false;
- }
- }
- return true;
- }
- protected function getMetadata($key)
- {
- if (false === $entries = $this->load($key)) {
- return array();
- }
- return unserialize($entries);
- }
- public function purge($url)
- {
- if (file_exists($path = $this->getPath($this->getCacheKey(Request::create($url))))) {
- unlink($path);
- return true;
- }
- return false;
- }
- protected function load($key)
- {
- $path = $this->getPath($key);
- return file_exists($path) ? file_get_contents($path) : false;
- }
- protected function save($key, $data)
- {
- $path = $this->getPath($key);
- if (!is_dir(dirname($path)) && false === @mkdir(dirname($path), 0777, true)) {
- 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, 0644);
- }
- public function getPath($key)
- {
- return $this->root.DIRECTORY_SEPARATOR.substr($key, 0, 2).DIRECTORY_SEPARATOR.substr($key, 2, 2).DIRECTORY_SEPARATOR.substr($key, 4, 2).DIRECTORY_SEPARATOR.substr($key, 6);
- }
- protected function getCacheKey(Request $request)
- {
- if (isset($this->keyCache[$request])) {
- return $this->keyCache[$request];
- }
- return $this->keyCache[$request] = 'md'.sha1($request->getUri());
- }
- protected function persistRequest(Request $request)
- {
- return $request->headers->all();
- }
- protected function persistResponse(Response $response)
- {
- $headers = $response->headers->all();
- $headers['X-Status'] = array($response->getStatusCode());
- return $headers;
- }
- protected function restoreResponse($headers, $body = null)
- {
- $status = $headers['X-Status'][0];
- unset($headers['X-Status']);
- if (null !== $body) {
- $headers['X-Body-File'] = array($body);
- }
- return new Response($body, $status, $headers);
- }
- }
- }
- namespace Symfony\Component\HttpKernel\HttpCache
- {
- use Symfony\Component\HttpFoundation\Request;
- use Symfony\Component\HttpFoundation\Response;
- use Symfony\Component\HttpKernel\HttpKernelInterface;
- class Esi
- {
- protected $contentTypes;
- public function __construct(array $contentTypes = array('text/html', 'text/xml', 'application/xml'))
- {
- $this->contentTypes = $contentTypes;
- }
- public function hasSurrogateEsiCapability(Request $request)
- {
- if (null === $value = $request->headers->get('Surrogate-Capability')) {
- return false;
- }
- return (Boolean) preg_match('#ESI/1.0#', $value);
- }
- public function addSurrogateEsiCapability(Request $request)
- {
- $current = $request->headers->get('Surrogate-Capability');
- $new = 'symfony2="ESI/1.0"';
- $request->headers->set('Surrogate-Capability', $current ? $current.', '.$new : $new);
- }
- public function addSurrogateControl(Response $response)
- {
- if (false !== strpos($response->getContent(), '<esi:include')) {
- $response->headers->set('Surrogate-Control', 'content="ESI/1.0"');
- }
- }
- public function needsEsiParsing(Response $response)
- {
- if (!$control = $response->headers->get('Surrogate-Control')) {
- return false;
- }
- return (Boolean) preg_match('#content="[^"]*ESI/1.0[^"]*"#', $control);
- }
- public function renderIncludeTag($uri, $alt = null, $ignoreErrors = true, $comment = '')
- {
- $html = sprintf('<esi:include src="%s"%s%s />',
- $uri,
- $ignoreErrors ? ' onerror="continue"' : '',
- $alt ? sprintf(' alt="%s"', $alt) : ''
- );
- if (!empty($comment)) {
- return sprintf("<esi:comment text=\"%s\" />\n%s", $comment, $html);
- }
- return $html;
- }
- public function process(Request $request, Response $response)
- {
- $this->request = $request;
- $type = $response->headers->get('Content-Type');
- if (empty($type)) {
- $type = 'text/html';
- }
- $parts = explode(';', $type);
- if (!in_array($parts[0], $this->contentTypes)) {
- return $response;
- }
- $content = $response->getContent();
- $content = preg_replace_callback('#<esi\:include\s+(.*?)\s*/>#', array($this, 'handleEsiIncludeTag'), $content);
- $content = preg_replace('#<esi\:comment[^>]*/>#', '', $content);
- $content = preg_replace('#<esi\:remove>.*?</esi\:remove>#', '', $content);
- $response->setContent($content);
- $response->headers->set('X-Body-Eval', 'ESI');
- if ($response->headers->has('Surrogate-Control')) {
- $value = $response->headers->get('Surrogate-Control');
- if ('content="ESI/1.0"' == $value) {
- $response->headers->remove('Surrogate-Control');
- } elseif (preg_match('#,\s*content="ESI/1.0"#', $value)) {
- $response->headers->set('Surrogate-Control', preg_replace('#,\s*content="ESI/1.0"#', '', $value));
- } elseif (preg_match('#content="ESI/1.0",\s*#', $value)) {
- $response->headers->set('Surrogate-Control', preg_replace('#content="ESI/1.0",\s*#', '', $value));
- }
- }
- }
- public function handle(HttpCache $cache, $uri, $alt, $ignoreErrors)
- {
- $subRequest = Request::create($uri, 'get', array(), $cache->getRequest()->cookies->all(), array(), $cache->getRequest()->server->all());
- try {
- $response = $cache->handle($subRequest, HttpKernelInterface::SUB_REQUEST, true);
- if (200 != $response->getStatusCode()) {
- throw new \RuntimeException(sprintf('Error when rendering "%s" (Status code is %s).', $subRequest->getUri(), $response->getStatusCode()));
- }
- return $response->getContent();
- } catch (\Exception $e) {
- if ($alt) {
- return $this->handle($cache, $alt, '', $ignoreErrors);
- }
- if (!$ignoreErrors) {
- throw $e;
- }
- }
- }
- protected function handleEsiIncludeTag($attributes)
- {
- $options = array();
- preg_match_all('/(src|onerror|alt)="([^"]*?)"/', $attributes[1], $matches, PREG_SET_ORDER);
- foreach ($matches as $set) {
- $options[$set[1]] = $set[2];
- }
- if (!isset($options['src'])) {
- throw new \RuntimeException('Unable to process an ESI tag without a "src" attribute.');
- }
- return sprintf('<?php echo $this->esi->handle($this, \'%s\', \'%s\', %s) ?>'."\n",
- $options['src'],
- isset($options['alt']) ? $options['alt'] : null,
- isset($options['onerror']) && 'continue' == $options['onerror'] ? 'true' : 'false'
- );
- }
- }
- }
- namespace Symfony\Component\HttpFoundation
- {
- class ParameterBag
- {
- protected $parameters;
- public function __construct(array $parameters = array())
- {
- $this->parameters = $parameters;
- }
- public function all()
- {
- return $this->parameters;
- }
- public function keys()
- {
- return array_keys($this->parameters);
- }
- public function replace(array $parameters = array())
- {
- $this->parameters = $parameters;
- }
- public function add(array $parameters = array())
- {
- $this->parameters = array_replace($this->parameters, $parameters);
- }
- public function get($key, $default = null)
- {
- return array_key_exists($key, $this->parameters) ? $this->parameters[$key] : $default;
- }
- public function set($key, $value)
- {
- $this->parameters[$key] = $value;
- }
- public function has($key)
- {
- return array_key_exists($key, $this->parameters);
- }
- public function remove($key)
- {
- unset($this->parameters[$key]);
- }
- public function getAlpha($key, $default = '')
- {
- return preg_replace('/[^[:alpha:]]/', '', $this->get($key, $default));
- }
- public function getAlnum($key, $default = '')
- {
- return preg_replace('/[^[:alnum:]]/', '', $this->get($key, $default));
- }
- public function getDigits($key, $default = '')
- {
- return preg_replace('/[^[:digit:]]/', '', $this->get($key, $default));
- }
- public function getInt($key, $default = 0)
- {
- return (int) $this->get($key, $default);
- }
- }
- }
- namespace Symfony\Component\HttpFoundation
- {
- use Symfony\Component\HttpFoundation\File\UploadedFile;
- class FileBag extends ParameterBag
- {
- private $fileKeys = array('error', 'name', 'size', 'tmp_name', 'type');
- public function __construct(array $parameters = array())
- {
- parent::__construct();
- $this->replace($parameters);
- }
- public function replace(array $files = array())
- {
- $this->parameters = array();
- $this->add($files);
- }
- public function set($key, $value)
- {
- if (is_array($value) || $value instanceof UploadedFile) {
- parent::set($key, $this->convertFileInformation($value));
- }
- }
- public function add(array $files = array())
- {
- foreach ($files as $key => $file) {
- $this->set($key, $file);
- }
- }
- protected function convertFileInformation($file)
- {
- if ($file instanceof UploadedFile) {
- return $file;
- }
- $file = $this->fixPhpFilesArray($file);
- if (is_array($file)) {
- $keys = array_keys($file);
- sort($keys);
- if ($keys == $this->fileKeys) {
- $file['error'] = (int) $file['error'];
- }
- if ($keys != $this->fileKeys) {
- $file = array_map(array($this, 'convertFileInformation'), $file);
- } else
- if ($file['error'] === UPLOAD_ERR_NO_FILE) {
- $file = null;
- } else {
- $file = new UploadedFile($file['tmp_name'], $file['name'],
- $file['type'], $file['size'], $file['error']);
- }
- }
- return $file;
- }
- protected function fixPhpFilesArray($data)
- {
- if (! is_array($data)) {
- return $data;
- }
- $keys = array_keys($data);
- sort($keys);
- if ($this->fileKeys != $keys || ! isset($data['name']) ||
- ! is_array($data['name'])) {
- return $data;
- }
- $files = $data;
- foreach ($this->fileKeys as $k) {
- unset($files[$k]);
- }
- foreach (array_keys($data['name']) as $key) {
- $files[$key] = $this->fixPhpFilesArray(array(
- 'error' => $data['error'][$key],
- 'name' => $data['name'][$key], 'type' => $data['type'][$key],
- 'tmp_name' => $data['tmp_name'][$key],
- 'size' => $data['size'][$key]
- ));
- }
- return $files;
- }
- }
- }
- namespace Symfony\Component\HttpFoundation
- {
- class ServerBag extends ParameterBag
- {
- public function getHeaders()
- {
- $headers = array();
- foreach ($this->parameters as $key => $value) {
- if ('HTTP_' === substr($key, 0, 5)) {
- $headers[substr($key, 5)] = $value;
- }
- }
- return $headers;
- }
- }
- }
- namespace Symfony\Component\HttpFoundation
- {
- class HeaderBag
- {
- protected $headers;
- protected $cookies;
- protected $cacheControl;
- public function __construct(array $headers = array())
- {
- $this->cacheControl = array();
- $this->cookies = array();
- $this->headers = array();
- foreach ($headers as $key => $values) {
- $this->set($key, $values);
- }
- }
- public function all()
- {
- return $this->headers;
- }
- public function keys()
- {
- return array_keys($this->headers);
- }
- public function replace(array $headers = array())
- {
- $this->headers = array();
- $this->add($headers);
- }
- public function add(array $headers)
- {
- foreach ($headers as $key => $values) {
- $this->set($key, $values);
- }
- }
- public function get($key, $default = null, $first = true)
- {
- $key = strtr(strtolower($key), '_', '-');
- if (!array_key_exists($key, $this->headers)) {
- if (null === $default) {
- return $first ? null : array();
- } else {
- return $first ? $default : array($default);
- }
- }
- if ($first) {
- return count($this->headers[$key]) ? $this->headers[$key][0] : $default;
- } else {
- return $this->headers[$key];
- }
- }
- public function set($key, $values, $replace = true)
- {
- $key = strtr(strtolower($key), '_', '-');
- if (!is_array($values)) {
- $values = array($values);
- }
- if (true === $replace || !isset($this->headers[$key])) {
- $this->headers[$key] = $values;
- } else {
- $this->headers[$key] = array_merge($this->headers[$key], $values);
- }
- if ('cache-control' === $key) {
- $this->cacheControl = $this->parseCacheControl($values[0]);
- }
- }
- public function has($key)
- {
- return array_key_exists(strtr(strtolower($key), '_', '-'), $this->headers);
- }
- public function contains($key, $value)
- {
- return in_array($value, $this->get($key, null, false));
- }
- public function remove($key)
- {
- $key = strtr(strtolower($key), '_', '-');
- unset($this->headers[$key]);
- if ('cache-control' === $key) {
- $this->cacheControl = array();
- }
- }
- public function setCookie(Cookie $cookie)
- {
- $this->cookies[$cookie->getName()] = $cookie;
- }
- public function removeCookie($name)
- {
- unset($this->cookies[$name]);
- }
- public function hasCookie($name)
- {
- return isset($this->cookies[$name]);
- }
- public function getCookie($name)
- {
- if (!$this->hasCookie($name)) {
- throw new \InvalidArgumentException(sprintf('There is no cookie with name "%s".', $name));
- }
- return $this->cookies[$name];
- }
- public function getCookies()
- {
- return $this->cookies;
- }
- public function getDate($key, \DateTime $default = null)
- {
- if (null === $value = $this->get($key)) {
- return $default;
- }
- if (false === $date = \DateTime::createFromFormat(DATE_RFC2822, $value)) {
- throw new \RuntimeException(sprintf('The %s HTTP header is not parseable (%s).', $key, $value));
- }
- return $date;
- }
- public function addCacheControlDirective($key, $value = true)
- {
- $this->cacheControl[$key] = $value;
- $this->set('Cache-Control', $this->getCacheControlHeader());
- }
- public function hasCacheControlDirective($key)
- {
- return array_key_exists($key, $this->cacheControl);
- }
- public function getCacheControlDirective($key)
- {
- return array_key_exists($key, $this->cacheControl) ? $this->cacheControl[$key] : null;
- }
- public function removeCacheControlDirective($key)
- {
- unset($this->cacheControl[$key]);
- $this->set('Cache-Control', $this->getCacheControlHeader());
- }
- protected function getCacheControlHeader()
- {
- $parts = array();
- ksort($this->cacheControl);
- foreach ($this->cacheControl as $key => $value) {
- if (true === $value) {
- $parts[] = $key;
- } else {
- if (preg_match('#[^a-zA-Z0-9._-]#', $value)) {
- $value = '"'.$value.'"';
- }
- $parts[] = "$key=$value";
- }
- }
- return implode(', ', $parts);
- }
- protected function parseCacheControl($header)
- {
- $cacheControl = array();
- preg_match_all('#([a-zA-Z][a-zA-Z_-]*)\s*(?:=(?:"([^"]*)"|([^ \t",;]*)))?#', $header, $matches, PREG_SET_ORDER);
- foreach ($matches as $match) {
- $cacheControl[strtolower($match[1])] = isset($match[2]) && $match[2] ? $match[2] : (isset($match[3]) ? $match[3] : true);
- }
- return $cacheControl;
- }
- }
- }
- namespace Symfony\Component\HttpFoundation
- {
- use Symfony\Component\HttpFoundation\SessionStorage\NativeSessionStorage;
- use Symfony\Component\HttpFoundation\File\UploadedFile;
- class Request
- {
- public $attributes;
- public $request;
- public $query;
- public $server;
- public $files;
- public $cookies;
- public $headers;
- protected $content;
- protected $languages;
- protected $charsets;
- protected $acceptableContentTypes;
- protected $pathInfo;
- protected $requestUri;
- protected $baseUrl;
- protected $basePath;
- protected $method;
- protected $format;
- protected $session;
- static protected $formats;
- public function __construct(array $query = array(), array $request = array(), array $attributes = array(), array $cookies = array(), array $files = array(), array $server = array(), $content = null)
- {
- $this->initialize($query, $request, $attributes, $cookies, $files, $server, $content);
- }
- public function initialize(array $query = array(), array $request = array(), array $attributes = array(), array $cookies = array(), array $files = array(), array $server = array(), $content = null)
- {
- $this->request = new ParameterBag($request);
- $this->query = new ParameterBag($query);
- $this->attributes = new ParameterBag($attributes);
- $this->cookies = new ParameterBag($cookies);
- $this->files = new FileBag($files);
- $this->server = new ServerBag($server);
- $this->headers = new HeaderBag($this->server->getHeaders());
- $this->content = $content;
- $this->languages = null;
- $this->charsets =…
Large files files are truncated, but you can click here to view the full file