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: 12:
13: class DefaultRevalidation implements RevalidationInterface
14: {
15: 16: 17:
18: protected $cacheKey;
19:
20: 21: 22:
23: protected $storage;
24:
25: 26: 27:
28: protected $plugin;
29:
30: 31: 32: 33: 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: 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:
62:
63: return false;
64: }
65:
66: 67: 68: 69: 70: 71: 72:
73: protected function handleBadResponse(BadResponseException $e)
74: {
75:
76:
77: if ($e->getResponse()->getStatusCode() == 404) {
78: $this->storage->delete($this->cacheKey->getCacheKey($e->getRequest()));
79: throw $e;
80: }
81: }
82:
83: 84: 85: 86: 87: 88: 89: 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:
103: $revalidate->getEventDispatcher()->removeSubscriber($this->plugin);
104:
105: return $revalidate;
106: }
107:
108: 109: 110: 111: 112: 113: 114: 115:
116: protected function handle200Response(RequestInterface $request, Response $validateResponse)
117: {
118: $request->setResponse($validateResponse);
119:
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: 133: 134: 135: 136: 137: 138: 139:
140: protected function handle304Response(RequestInterface $request, Response $validateResponse, Response $response)
141: {
142: static = array('Date', 'Expires', 'Cache-Control', 'ETag', 'Last-Modified');
143:
144:
145: if ($validateResponse->getEtag() != $response->getEtag()) {
146: return false;
147: }
148:
149:
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:
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: