Overview

Namespaces

  • Contrib
    • Bundle
      • CoverallsBundle
        • Console
        • Entity
      • CoverallsV1Bundle
        • Api
        • Collector
        • Command
        • Config
        • Entity
          • Git
    • Component
      • File
      • Log
      • System
        • Git
  • Guzzle
    • Batch
      • Exception
    • Cache
    • Common
      • Exception
    • Http
      • Curl
      • Exception
      • Message
      • QueryAggregator
    • Inflection
    • Iterator
    • Log
    • Parser
      • Cookie
      • Message
      • UriTemplate
      • Url
    • Plugin
      • Async
      • Backoff
      • Cache
      • Cookie
        • CookieJar
        • Exception
      • CurlAuth
      • ErrorResponse
        • Exception
      • History
      • Log
      • Md5
      • Mock
      • Oauth
    • Service
      • Builder
      • Command
        • Factory
        • LocationVisitor
          • Request
          • Response
      • Description
      • Exception
      • Resource
    • Stream
  • PHP
  • Psr
    • Log
  • Symfony
    • Component
      • Config
        • Definition
          • Builder
          • Exception
        • Exception
        • Loader
        • Resource
        • Util
      • Console
        • Command
        • Formatter
        • Helper
        • Input
        • Output
        • Tester
      • EventDispatcher
        • Debug
      • Finder
        • Adapter
        • Comparator
        • Exception
        • Expression
        • Iterator
        • Shell
      • Stopwatch
      • Yaml
        • Exception

Classes

  • CachePlugin
  • CallbackCacheKeyProvider
  • CallbackCanCacheStrategy
  • DefaultCacheKeyProvider
  • DefaultCacheStorage
  • DefaultCanCacheStrategy
  • DefaultRevalidation
  • DenyRevalidation
  • SkipRevalidation

Interfaces

  • CacheKeyProviderInterface
  • CacheStorageInterface
  • CanCacheStrategyInterface
  • RevalidationInterface
  • Overview
  • Namespace
  • Class
  • Tree
  • Todo
  1: <?php
  2: 
  3: namespace Guzzle\Plugin\Cache;
  4: 
  5: use Guzzle\Http\Exception\CurlException;
  6: use Guzzle\Http\Message\RequestInterface;
  7: use Guzzle\Http\Message\Response;
  8: use Guzzle\Http\Exception\BadResponseException;
  9: 
 10: /**
 11:  * Default revalidation strategy
 12:  */
 13: class DefaultRevalidation implements RevalidationInterface
 14: {
 15:     /**
 16:      * @var CacheKeyProviderInterface Strategy used to create cache keys
 17:      */
 18:     protected $cacheKey;
 19: 
 20:     /**
 21:      * @var CacheStorageInterface Cache object storing cache data
 22:      */
 23:     protected $storage;
 24: 
 25:     /**
 26:      * @var CachePlugin
 27:      */
 28:     protected $plugin;
 29: 
 30:     /**
 31:      * @param CacheKeyProviderInterface $cacheKey Cache key strategy
 32:      * @param CacheStorageInterface     $cache    Cache storage
 33:      * @param CachePlugin               $plugin   Cache plugin to remove from revalidation requests
 34:      */
 35:     public function __construct(CacheKeyProviderInterface $cacheKey, CacheStorageInterface $cache, CachePlugin $plugin)
 36:     {
 37:         $this->cacheKey = $cacheKey;
 38:         $this->storage = $cache;
 39:         $this->plugin = $plugin;
 40:     }
 41: 
 42:     /**
 43:      * {@inheritdoc}
 44:      */
 45:     public function revalidate(RequestInterface $request, Response $response)
 46:     {
 47:         try {
 48:             $revalidate = $this->createRevalidationRequest($request, $response);
 49:             $validateResponse = $revalidate->send();
 50:             if ($validateResponse->getStatusCode() == 200) {
 51:                 return $this->handle200Response($request, $validateResponse);
 52:             } elseif ($validateResponse->getStatusCode() == 304) {
 53:                 return $this->handle304Response($request, $validateResponse, $response);
 54:             }
 55:         } catch (CurlException $e) {
 56:             return $this->plugin->canResponseSatisfyFailedRequest($request, $response);
 57:         } catch (BadResponseException $e) {
 58:             $this->handleBadResponse($e);
 59:         }
 60: 
 61:         // Other exceptions encountered in the revalidation request are ignored
 62:         // in hopes that sending a request to the origin server will fix it
 63:         return false;
 64:     }
 65: 
 66:     /**
 67:      * Handles a bad response when attempting to revalidate
 68:      *
 69:      * @param BadResponseException $e Exception encountered
 70:      *
 71:      * @throws BadResponseException
 72:      */
 73:     protected function handleBadResponse(BadResponseException $e)
 74:     {
 75:         // 404 errors mean the resource no longer exists, so remove from
 76:         // cache, and prevent an additional request by throwing the exception
 77:         if ($e->getResponse()->getStatusCode() == 404) {
 78:             $this->storage->delete($this->cacheKey->getCacheKey($e->getRequest()));
 79:             throw $e;
 80:         }
 81:     }
 82: 
 83:     /**
 84:      * Creates a request to use for revalidation
 85:      *
 86:      * @param RequestInterface $request  Request
 87:      * @param Response         $response Response to revalidate
 88:      *
 89:      * @return RequestInterface returns a revalidation request
 90:      */
 91:     protected function createRevalidationRequest(RequestInterface $request, Response $response)
 92:     {
 93:         $revalidate = clone $request;
 94:         $revalidate->removeHeader('Pragma')
 95:             ->removeHeader('Cache-Control')
 96:             ->setHeader('If-Modified-Since', $response->getLastModified() ?: $response->getDate());
 97: 
 98:         if ($response->getEtag()) {
 99:             $revalidate->setHeader('If-None-Match', '"' . $response->getEtag() . '"');
100:         }
101: 
102:         // Remove any cache plugins that might be on the request
103:         $revalidate->getEventDispatcher()->removeSubscriber($this->plugin);
104: 
105:         return $revalidate;
106:     }
107: 
108:     /**
109:      * Handles a 200 response response from revalidating. The server does not support validation, so use this response.
110:      *
111:      * @param RequestInterface $request          Request that was sent
112:      * @param Response         $validateResponse Response received
113:      *
114:      * @return bool Returns true if valid, false if invalid
115:      */
116:     protected function handle200Response(RequestInterface $request, Response $validateResponse)
117:     {
118:         $request->setResponse($validateResponse);
119:         // Store this response in cache if possible
120:         if ($validateResponse->canCache()) {
121:             $this->storage->cache(
122:                 $this->cacheKey->getCacheKey($request),
123:                 $validateResponse,
124:                 $request->getParams()->get('cache.override_ttl')
125:             );
126:         }
127: 
128:         return false;
129:     }
130: 
131:     /**
132:      * Handle a 304 response and ensure that it is still valid
133:      *
134:      * @param RequestInterface $request          Request that was sent
135:      * @param Response         $validateResponse Response received
136:      * @param Response         $response         Original cached response
137:      *
138:      * @return bool Returns true if valid, false if invalid
139:      */
140:     protected function handle304Response(RequestInterface $request, Response $validateResponse, Response $response)
141:     {
142:         static $replaceHeaders = array('Date', 'Expires', 'Cache-Control', 'ETag', 'Last-Modified');
143: 
144:         // Make sure that this response has the same ETag
145:         if ($validateResponse->getEtag() != $response->getEtag()) {
146:             return false;
147:         }
148:         // Replace cached headers with any of these headers from the
149:         // origin server that might be more up to date
150:         $modified = false;
151:         foreach ($replaceHeaders as $name) {
152:             if ($validateResponse->hasHeader($name)) {
153:                 $modified = true;
154:                 $response->setHeader($name, $validateResponse->getHeader($name));
155:             }
156:         }
157:         // Store the updated response in cache
158:         if ($modified && $response->canCache()) {
159:             $this->storage->cache(
160:                 $this->cacheKey->getCacheKey($request),
161:                 $response,
162:                 $request->getParams()->get('cache.override_ttl')
163:             );
164:         }
165: 
166:         return true;
167:     }
168: }
169: 
php-coveralls API documentation generated by ApiGen 2.8.0