vendor/symfony/src/Symfony/Component/HttpKernel/HttpCache/HttpCache.php
author cavaliet
Mon, 20 Feb 2012 11:51:04 +0100
changeset 68 76ae0d76a933
parent 0 7f95f8617b0b
permissions -rwxr-xr-x
Close span tag
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
     1
<?php
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
     2
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
     3
/*
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
     4
 * This file is part of the Symfony package.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
     5
 *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
     6
 * (c) Fabien Potencier <fabien@symfony.com>
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
     7
 *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
     8
 * This code is partially based on the Rack-Cache library by Ryan Tomayko,
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
     9
 * which is released under the MIT license.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    10
 * (based on commit 02d2b48d75bcb63cf1c0c7149c077ad256542801)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    11
 *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    12
 * For the full copyright and license information, please view the LICENSE
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    13
 * file that was distributed with this source code.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    14
 */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    15
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    16
namespace Symfony\Component\HttpKernel\HttpCache;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    17
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    18
use Symfony\Component\HttpKernel\HttpKernelInterface;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    19
use Symfony\Component\HttpFoundation\Request;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    20
use Symfony\Component\HttpFoundation\Response;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    21
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    22
/**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    23
 * Cache provides HTTP caching.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    24
 *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    25
 * @author Fabien Potencier <fabien@symfony.com>
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    26
 *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    27
 * @api
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    28
 */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    29
class HttpCache implements HttpKernelInterface
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    30
{
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    31
    private $kernel;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    32
    private $store;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    33
    private $request;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    34
    private $esi;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    35
    private $esiCacheStrategy;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    36
    private $traces;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    37
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    38
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    39
     * Constructor.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    40
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    41
     * The available options are:
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    42
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    43
     *   * debug:                 If true, the traces are added as a HTTP header to ease debugging
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    44
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    45
     *   * default_ttl            The number of seconds that a cache entry should be considered
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    46
     *                            fresh when no explicit freshness information is provided in
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    47
     *                            a response. Explicit Cache-Control or Expires headers
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    48
     *                            override this value. (default: 0)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    49
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    50
     *   * private_headers        Set of request headers that trigger "private" cache-control behavior
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    51
     *                            on responses that don't explicitly state whether the response is
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    52
     *                            public or private via a Cache-Control directive. (default: Authorization and Cookie)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    53
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    54
     *   * allow_reload           Specifies whether the client can force a cache reload by including a
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    55
     *                            Cache-Control "no-cache" directive in the request. Set it to ``true``
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    56
     *                            for compliance with RFC 2616. (default: false)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    57
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    58
     *   * allow_revalidate       Specifies whether the client can force a cache revalidate by including
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    59
     *                            a Cache-Control "max-age=0" directive in the request. Set it to ``true``
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    60
     *                            for compliance with RFC 2616. (default: false)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    61
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    62
     *   * stale_while_revalidate Specifies the default number of seconds (the granularity is the second as the
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    63
     *                            Response TTL precision is a second) during which the cache can immediately return
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    64
     *                            a stale response while it revalidates it in the background (default: 2).
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    65
     *                            This setting is overridden by the stale-while-revalidate HTTP Cache-Control
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    66
     *                            extension (see RFC 5861).
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    67
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    68
     *   * stale_if_error         Specifies the default number of seconds (the granularity is the second) during which
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    69
     *                            the cache can serve a stale response when an error is encountered (default: 60).
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    70
     *                            This setting is overridden by the stale-if-error HTTP Cache-Control extension
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    71
     *                            (see RFC 5861).
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    72
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    73
     * @param HttpKernelInterface $kernel  An HttpKernelInterface instance
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    74
     * @param StoreInterface      $store   A Store instance
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    75
     * @param Esi                 $esi     An Esi instance
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    76
     * @param array               $options An array of options
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    77
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    78
    public function __construct(HttpKernelInterface $kernel, StoreInterface $store, Esi $esi = null, array $options = array())
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    79
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    80
        $this->store = $store;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    81
        $this->kernel = $kernel;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    82
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    83
        // needed in case there is a fatal error because the backend is too slow to respond
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    84
        register_shutdown_function(array($this->store, 'cleanup'));
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    85
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    86
        $this->options = array_merge(array(
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    87
            'debug'                  => false,
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    88
            'default_ttl'            => 0,
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    89
            'private_headers'        => array('Authorization', 'Cookie'),
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    90
            'allow_reload'           => false,
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    91
            'allow_revalidate'       => false,
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    92
            'stale_while_revalidate' => 2,
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    93
            'stale_if_error'         => 60,
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    94
        ), $options);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    95
        $this->esi = $esi;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    96
        $this->traces = array();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    97
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    98
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    99
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   100
     * Returns an array of events that took place during processing of the last request.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   101
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   102
     * @return array An array of events
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   103
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   104
    public function getTraces()
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   105
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   106
        return $this->traces;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   107
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   108
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   109
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   110
     * Returns a log message for the events of the last request processing.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   111
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   112
     * @return string A log message
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   113
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   114
    public function getLog()
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   115
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   116
        $log = array();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   117
        foreach ($this->traces as $request => $traces) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   118
            $log[] = sprintf('%s: %s', $request, implode(', ', $traces));
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   119
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   120
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   121
        return implode('; ', $log);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   122
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   123
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   124
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   125
     * Gets the Request instance associated with the master request.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   126
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   127
     * @return Symfony\Component\HttpFoundation\Request A Request instance
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   128
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   129
    public function getRequest()
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   130
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   131
        return $this->request;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   132
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   133
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   134
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   135
     * Gets the Kernel instance
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   136
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   137
     * @return Symfony\Component\HttpKernel\HttpKernelInterface An HttpKernelInterface instance
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   138
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   139
    public function getKernel()
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   140
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   141
        return $this->kernel;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   142
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   143
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   144
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   145
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   146
     * Gets the Esi instance
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   147
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   148
     * @return Symfony\Component\HttpKernel\HttpCache\Esi An Esi instance
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   149
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   150
    public function getEsi()
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   151
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   152
        return $this->esi;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   153
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   154
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   155
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   156
     * {@inheritdoc}
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   157
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   158
     * @api
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   159
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   160
    public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = true)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   161
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   162
        // FIXME: catch exceptions and implement a 500 error page here? -> in Varnish, there is a built-in error page mechanism
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   163
        if (HttpKernelInterface::MASTER_REQUEST === $type) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   164
            $this->traces = array();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   165
            $this->request = $request;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   166
            if (null !== $this->esi) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   167
                $this->esiCacheStrategy = $this->esi->createCacheStrategy();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   168
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   169
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   170
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   171
        $path = $request->getPathInfo();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   172
        if ($qs = $request->getQueryString()) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   173
            $path .= '?'.$qs;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   174
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   175
        $this->traces[$request->getMethod().' '.$path] = array();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   176
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   177
        if (!$request->isMethodSafe()) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   178
            $response = $this->invalidate($request, $catch);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   179
        } elseif ($request->headers->has('expect')) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   180
            $response = $this->pass($request, $catch);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   181
        } else {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   182
            $response = $this->lookup($request, $catch);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   183
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   184
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   185
        $response->isNotModified($request);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   186
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   187
        $this->restoreResponseBody($request, $response);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   188
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   189
        $response->setDate(new \DateTime(null, new \DateTimeZone('UTC')));
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   190
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   191
        if (HttpKernelInterface::MASTER_REQUEST === $type && $this->options['debug']) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   192
            $response->headers->set('X-Symfony-Cache', $this->getLog());
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   193
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   194
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   195
        if (null !== $this->esi) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   196
            $this->esiCacheStrategy->add($response);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   197
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   198
            if (HttpKernelInterface::MASTER_REQUEST === $type) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   199
                $this->esiCacheStrategy->update($response);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   200
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   201
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   202
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   203
        $response->prepare();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   204
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   205
        return $response;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   206
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   207
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   208
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   209
     * Forwards the Request to the backend without storing the Response in the cache.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   210
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   211
     * @param Request $request A Request instance
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   212
     * @param Boolean $catch   Whether to process exceptions
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   213
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   214
     * @return Response A Response instance
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   215
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   216
    protected function pass(Request $request, $catch = false)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   217
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   218
        $this->record($request, 'pass');
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   219
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   220
        return $this->forward($request, $catch);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   221
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   222
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   223
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   224
     * Invalidates non-safe methods (like POST, PUT, and DELETE).
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   225
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   226
     * @param Request $request A Request instance
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   227
     * @param Boolean $catch   Whether to process exceptions
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   228
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   229
     * @return Response A Response instance
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   230
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   231
     * @see RFC2616 13.10
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   232
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   233
    protected function invalidate(Request $request, $catch = false)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   234
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   235
        $response = $this->pass($request, $catch);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   236
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   237
        // invalidate only when the response is successful
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   238
        if ($response->isSuccessful() || $response->isRedirect()) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   239
            try {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   240
                $this->store->invalidate($request, $catch);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   241
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   242
                $this->record($request, 'invalidate');
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   243
            } catch (\Exception $e) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   244
                $this->record($request, 'invalidate-failed');
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   245
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   246
                if ($this->options['debug']) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   247
                    throw $e;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   248
                }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   249
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   250
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   251
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   252
        return $response;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   253
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   254
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   255
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   256
     * Lookups a Response from the cache for the given Request.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   257
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   258
     * When a matching cache entry is found and is fresh, it uses it as the
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   259
     * response without forwarding any request to the backend. When a matching
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   260
     * cache entry is found but is stale, it attempts to "validate" the entry with
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   261
     * the backend using conditional GET. When no matching cache entry is found,
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   262
     * it triggers "miss" processing.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   263
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   264
     * @param Request $request A Request instance
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   265
     * @param Boolean $catch   whether to process exceptions
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   266
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   267
     * @return Response A Response instance
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   268
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   269
    protected function lookup(Request $request, $catch = false)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   270
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   271
        // if allow_reload and no-cache Cache-Control, allow a cache reload
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   272
        if ($this->options['allow_reload'] && $request->isNoCache()) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   273
            $this->record($request, 'reload');
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   274
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   275
            return $this->fetch($request);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   276
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   277
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   278
        try {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   279
            $entry = $this->store->lookup($request);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   280
        } catch (\Exception $e) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   281
            $this->record($request, 'lookup-failed');
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   282
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   283
            if ($this->options['debug']) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   284
                throw $e;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   285
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   286
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   287
            return $this->pass($request, $catch);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   288
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   289
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   290
        if (null === $entry) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   291
            $this->record($request, 'miss');
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   292
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   293
            return $this->fetch($request, $catch);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   294
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   295
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   296
        if (!$this->isFreshEnough($request, $entry)) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   297
            $this->record($request, 'stale');
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   298
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   299
            return $this->validate($request, $entry, $catch);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   300
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   301
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   302
        $this->record($request, 'fresh');
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   303
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   304
        $entry->headers->set('Age', $entry->getAge());
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   305
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   306
        return $entry;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   307
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   308
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   309
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   310
     * Validates that a cache entry is fresh.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   311
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   312
     * The original request is used as a template for a conditional
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   313
     * GET request with the backend.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   314
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   315
     * @param Request  $request A Request instance
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   316
     * @param Response $entry   A Response instance to validate
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   317
     * @param Boolean  $catch   Whether to process exceptions
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   318
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   319
     * @return Response A Response instance
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   320
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   321
    protected function validate(Request $request, Response $entry, $catch = false)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   322
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   323
        $subRequest = clone $request;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   324
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   325
        // send no head requests because we want content
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   326
        $subRequest->setMethod('GET');
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   327
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   328
        // add our cached last-modified validator
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   329
        $subRequest->headers->set('if_modified_since', $entry->headers->get('Last-Modified'));
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   330
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   331
        // Add our cached etag validator to the environment.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   332
        // We keep the etags from the client to handle the case when the client
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   333
        // has a different private valid entry which is not cached here.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   334
        $cachedEtags = $entry->getEtag() ? array($entry->getEtag()) : array();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   335
        $requestEtags = $request->getEtags();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   336
        if ($etags = array_unique(array_merge($cachedEtags, $requestEtags))) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   337
            $subRequest->headers->set('if_none_match', implode(', ', $etags));
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   338
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   339
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   340
        $response = $this->forward($subRequest, $catch, $entry);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   341
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   342
        if (304 == $response->getStatusCode()) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   343
            $this->record($request, 'valid');
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   344
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   345
            // return the response and not the cache entry if the response is valid but not cached
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   346
            $etag = $response->getEtag();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   347
            if ($etag && in_array($etag, $requestEtags) && !in_array($etag, $cachedEtags)) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   348
                return $response;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   349
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   350
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   351
            $entry = clone $entry;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   352
            $entry->headers->remove('Date');
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   353
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   354
            foreach (array('Date', 'Expires', 'Cache-Control', 'ETag', 'Last-Modified') as $name) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   355
                if ($response->headers->has($name)) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   356
                    $entry->headers->set($name, $response->headers->get($name));
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   357
                }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   358
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   359
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   360
            $response = $entry;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   361
        } else {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   362
            $this->record($request, 'invalid');
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   363
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   364
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   365
        if ($response->isCacheable()) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   366
            $this->store($request, $response);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   367
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   368
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   369
        return $response;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   370
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   371
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   372
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   373
     * Forwards the Request to the backend and determines whether the response should be stored.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   374
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   375
     * This methods is triggered when the cache missed or a reload is required.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   376
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   377
     * @param Request $request A Request instance
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   378
     * @param Boolean $catch   whether to process exceptions
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   379
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   380
     * @return Response A Response instance
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   381
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   382
    protected function fetch(Request $request, $catch = false)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   383
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   384
        $subRequest = clone $request;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   385
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   386
        // send no head requests because we want content
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   387
        $subRequest->setMethod('GET');
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   388
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   389
        // avoid that the backend sends no content
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   390
        $subRequest->headers->remove('if_modified_since');
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   391
        $subRequest->headers->remove('if_none_match');
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   392
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   393
        $response = $this->forward($subRequest, $catch);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   394
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   395
        if ($this->isPrivateRequest($request) && !$response->headers->hasCacheControlDirective('public')) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   396
            $response->setPrivate(true);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   397
        } elseif ($this->options['default_ttl'] > 0 && null === $response->getTtl() && !$response->headers->getCacheControlDirective('must-revalidate')) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   398
            $response->setTtl($this->options['default_ttl']);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   399
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   400
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   401
        if ($response->isCacheable()) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   402
            $this->store($request, $response);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   403
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   404
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   405
        return $response;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   406
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   407
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   408
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   409
     * Forwards the Request to the backend and returns the Response.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   410
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   411
     * @param Request  $request A Request instance
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   412
     * @param Boolean  $catch   Whether to catch exceptions or not
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   413
     * @param Response $entry   A Response instance (the stale entry if present, null otherwise)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   414
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   415
     * @return Response A Response instance
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   416
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   417
    protected function forward(Request $request, $catch = false, Response $entry = null)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   418
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   419
        if ($this->esi) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   420
            $this->esi->addSurrogateEsiCapability($request);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   421
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   422
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   423
        // always a "master" request (as the real master request can be in cache)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   424
        $response = $this->kernel->handle($request, HttpKernelInterface::MASTER_REQUEST, $catch);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   425
        // FIXME: we probably need to also catch exceptions if raw === true
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   426
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   427
        // we don't implement the stale-if-error on Requests, which is nonetheless part of the RFC
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   428
        if (null !== $entry && in_array($response->getStatusCode(), array(500, 502, 503, 504))) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   429
            if (null === $age = $entry->headers->getCacheControlDirective('stale-if-error')) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   430
                $age = $this->options['stale_if_error'];
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   431
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   432
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   433
            if (abs($entry->getTtl()) < $age) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   434
                $this->record($request, 'stale-if-error');
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   435
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   436
                return $entry;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   437
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   438
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   439
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   440
        $this->processResponseBody($request, $response);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   441
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   442
        return $response;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   443
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   444
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   445
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   446
     * Checks whether the cache entry is "fresh enough" to satisfy the Request.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   447
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   448
     * @param Request  $request A Request instance
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   449
     * @param Response $entry   A Response instance
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   450
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   451
     * @return Boolean true if the cache entry if fresh enough, false otherwise
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   452
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   453
    protected function isFreshEnough(Request $request, Response $entry)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   454
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   455
        if (!$entry->isFresh()) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   456
            return $this->lock($request, $entry);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   457
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   458
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   459
        if ($this->options['allow_revalidate'] && null !== $maxAge = $request->headers->getCacheControlDirective('max-age')) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   460
            return $maxAge > 0 && $maxAge >= $entry->getAge();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   461
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   462
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   463
        return true;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   464
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   465
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   466
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   467
     * Locks a Request during the call to the backend.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   468
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   469
     * @param Request  $request A Request instance
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   470
     * @param Response $entry   A Response instance
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   471
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   472
     * @return Boolean true if the cache entry can be returned even if it is staled, false otherwise
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   473
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   474
    protected function lock(Request $request, Response $entry)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   475
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   476
        // try to acquire a lock to call the backend
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   477
        $lock = $this->store->lock($request, $entry);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   478
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   479
        // there is already another process calling the backend
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   480
        if (true !== $lock) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   481
            // check if we can serve the stale entry
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   482
            if (null === $age = $entry->headers->getCacheControlDirective('stale-while-revalidate')) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   483
                $age = $this->options['stale_while_revalidate'];
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   484
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   485
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   486
            if (abs($entry->getTtl()) < $age) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   487
                $this->record($request, 'stale-while-revalidate');
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   488
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   489
                // server the stale response while there is a revalidation
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   490
                return true;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   491
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   492
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   493
            // wait for the lock to be released
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   494
            $wait = 0;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   495
            while (file_exists($lock) && $wait < 5000000) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   496
                usleep($wait += 50000);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   497
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   498
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   499
            if ($wait < 2000000) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   500
                // replace the current entry with the fresh one
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   501
                $new = $this->lookup($request);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   502
                $entry->headers = $new->headers;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   503
                $entry->setContent($new->getContent());
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   504
                $entry->setStatusCode($new->getStatusCode());
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   505
                $entry->setProtocolVersion($new->getProtocolVersion());
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   506
                foreach ($new->headers->getCookies() as $cookie) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   507
                    $entry->headers->setCookie($cookie);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   508
                }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   509
            } else {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   510
                // backend is slow as hell, send a 503 response (to avoid the dog pile effect)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   511
                $entry->setStatusCode(503);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   512
                $entry->setContent('503 Service Unavailable');
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   513
                $entry->headers->set('Retry-After', 10);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   514
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   515
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   516
            return true;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   517
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   518
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   519
        // we have the lock, call the backend
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   520
        return false;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   521
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   522
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   523
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   524
     * Writes the Response to the cache.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   525
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   526
     * @param Request  $request  A Request instance
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   527
     * @param Response $response A Response instance
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   528
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   529
    protected function store(Request $request, Response $response)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   530
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   531
        try {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   532
            $this->store->write($request, $response);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   533
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   534
            $this->record($request, 'store');
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   535
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   536
            $response->headers->set('Age', $response->getAge());
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   537
        } catch (\Exception $e) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   538
            $this->record($request, 'store-failed');
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   539
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   540
            if ($this->options['debug']) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   541
                throw $e;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   542
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   543
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   544
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   545
        // now that the response is cached, release the lock
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   546
        $this->store->unlock($request);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   547
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   548
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   549
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   550
     * Restores the Response body.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   551
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   552
     * @param Request  $request  A Request instance
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   553
     * @param Response $response A Response instance
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   554
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   555
     * @return Response A Response instance
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   556
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   557
    private function restoreResponseBody(Request $request, Response $response)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   558
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   559
        if ('HEAD' === $request->getMethod() || 304 === $response->getStatusCode()) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   560
            $response->setContent('');
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   561
            $response->headers->remove('X-Body-Eval');
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   562
            $response->headers->remove('X-Body-File');
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   563
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   564
            return;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   565
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   566
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   567
        if ($response->headers->has('X-Body-Eval')) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   568
            ob_start();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   569
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   570
            if ($response->headers->has('X-Body-File')) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   571
                include $response->headers->get('X-Body-File');
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   572
            } else {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   573
                eval('; ?>'.$response->getContent().'<?php ;');
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   574
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   575
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   576
            $response->setContent(ob_get_clean());
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   577
            $response->headers->remove('X-Body-Eval');
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   578
        } elseif ($response->headers->has('X-Body-File')) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   579
            $response->setContent(file_get_contents($response->headers->get('X-Body-File')));
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   580
        } else {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   581
            return;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   582
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   583
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   584
        $response->headers->remove('X-Body-File');
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   585
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   586
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   587
    protected function processResponseBody(Request $request, Response $response)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   588
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   589
        if (null !== $this->esi && $this->esi->needsEsiParsing($response)) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   590
            $this->esi->process($request, $response);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   591
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   592
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   593
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   594
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   595
     * Checks if the Request includes authorization or other sensitive information
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   596
     * that should cause the Response to be considered private by default.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   597
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   598
     * @param Request $request A Request instance
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   599
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   600
     * @return Boolean true if the Request is private, false otherwise
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   601
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   602
    private function isPrivateRequest(Request $request)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   603
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   604
        foreach ($this->options['private_headers'] as $key) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   605
            $key = strtolower(str_replace('HTTP_', '', $key));
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   606
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   607
            if ('cookie' === $key) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   608
                if (count($request->cookies->all())) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   609
                    return true;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   610
                }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   611
            } elseif ($request->headers->has($key)) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   612
                return true;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   613
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   614
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   615
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   616
        return false;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   617
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   618
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   619
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   620
     * Records that an event took place.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   621
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   622
     * @param Request $request A Request instance
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   623
     * @param string  $event The event name
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   624
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   625
    private function record(Request $request, $event)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   626
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   627
        $path = $request->getPathInfo();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   628
        if ($qs = $request->getQueryString()) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   629
            $path .= '?'.$qs;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   630
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   631
        $this->traces[$request->getMethod().' '.$path][] = $event;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   632
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   633
}