14 use Doctrine\Common\Cache\ArrayCache;
53 if (!is_array($options)) {
57 $options = array(
'storage' => $options);
60 } elseif (!class_exists(
'Doctrine\Common\Cache\ArrayCache')) {
67 $this->autoPurge = isset($options[
'auto_purge']) ? $options[
'auto_purge'] :
false;
70 $this->storage = isset($options[
'storage'])
72 :
new DefaultCacheStorage(
new DoctrineCacheAdapter(
new ArrayCache()));
74 if (!isset($options[
'can_cache'])) {
75 $this->canCache =
new DefaultCanCacheStrategy();
77 $this->canCache = is_callable($options[
'can_cache'])
78 ?
new CallbackCanCacheStrategy($options[
'can_cache'])
79 : $options[
'can_cache'];
83 $this->revalidation = isset($options[
'revalidation'])
84 ? $options[
'revalidation']
85 :
new DefaultRevalidation($this->storage, $this->canCache);
91 'request.before_send' => array(
'onRequestBeforeSend', -255),
92 'request.sent' => array(
'onRequestSent', 255),
93 'request.error' => array(
'onRequestError', 0),
94 'request.exception' => array(
'onRequestException', 0),
105 $request = $event[
'request'];
106 $request->addHeader(
'Via', sprintf(
'%s GuzzleCache/%s', $request->getProtocolVersion(),
Version::VERSION));
108 if (!$this->canCache->canCacheRequest($request)) {
109 switch ($request->getMethod()) {
111 $this->
purge($request);
112 $request->setResponse(
new Response(200, array(),
'purged'));
118 if ($this->autoPurge) {
119 $this->
purge($request);
125 if ($response = $this->storage->fetch($request)) {
126 $params = $request->getParams();
127 $params[
'cache.lookup'] =
true;
128 $response->setHeader(
130 time() - strtotime($response->getDate() ? : $response->getLastModified() ?:
'now')
134 if (!isset($params[
'cache.hit'])) {
135 $params[
'cache.hit'] =
true;
137 $request->setResponse($response);
149 $request = $event[
'request'];
150 $response = $event[
'response'];
152 if ($request->getParams()->get(
'cache.hit') ===
null &&
153 $this->canCache->canCacheRequest($request) &&
154 $this->canCache->canCacheResponse($response)
156 $this->storage->cache($request, $response);
169 $request = $event[
'request'];
171 if (!$this->canCache->canCacheRequest($request)) {
175 if ($response = $this->storage->fetch($request)) {
176 $response->setHeader(
178 time() - strtotime($response->getLastModified() ? : $response->getDate() ?:
'now')
182 $request->getParams()->set(
'cache.hit',
'error');
184 $event[
'response'] = $response;
199 if (!$event[
'exception'] instanceof CurlException) {
203 $request = $event[
'request'];
204 if (!$this->canCache->canCacheRequest($request)) {
208 if ($response = $this->storage->fetch($request)) {
209 $response->setHeader(
'Age', time() - strtotime($response->getDate() ? :
'now'));
213 $request->getParams()->set(
'cache.hit',
'error');
214 $request->setResponse($response);
216 $event->stopPropagation();
230 $responseAge = $response->calculateAge();
231 $reqc = $request->getHeader(
'Cache-Control');
232 $resc = $response->getHeader(
'Cache-Control');
235 if ($reqc && $reqc->hasDirective(
'max-age') &&
236 $responseAge > $reqc->getDirective(
'max-age')) {
241 if ($response->isFresh() ===
false) {
242 $maxStale = $reqc ? $reqc->getDirective(
'max-stale') :
null;
243 if (
null !== $maxStale) {
244 if ($maxStale !==
true && $response->getFreshness() < (-1 * $maxStale)) {
247 } elseif ($resc && $resc->hasDirective(
'max-age')
248 && $responseAge > $resc->getDirective(
'max-age')
254 if ($this->revalidation->shouldRevalidate($request, $response)) {
256 return $this->revalidation->revalidate($request, $response);
257 }
catch (CurlException $e) {
258 $request->getParams()->set(
'cache.hit',
'error');
276 $reqc = $request->getHeader(
'Cache-Control');
277 $resc = $response->getHeader(
'Cache-Control');
278 $requestStaleIfError = $reqc ? $reqc->getDirective(
'stale-if-error') :
null;
279 $responseStaleIfError = $resc ? $resc->getDirective(
'stale-if-error') :
null;
281 if (!$requestStaleIfError && !$responseStaleIfError) {
285 if (is_numeric($requestStaleIfError) && $response->getAge() - $response->getMaxAge() > $requestStaleIfError) {
289 if (is_numeric($responseStaleIfError) && $response->getAge() - $response->getMaxAge() > $responseStaleIfError) {
301 public function purge($url)
304 $url = $url instanceof RequestInterface ? $url->getUrl() : $url;
305 $this->storage->purge($url);
316 $params = $request->getParams();
317 $response->setHeader(
'Via', sprintf(
'%s GuzzleCache/%s', $request->getProtocolVersion(),
Version::VERSION));
319 $lookup = ($params[
'cache.lookup'] ===
true ?
'HIT' :
'MISS') .
' from GuzzleCache';
320 if ($header = $response->getHeader(
'X-Cache-Lookup')) {
322 $values = $header->toArray();
324 $response->setHeader(
'X-Cache-Lookup', array_unique($values));
326 $response->setHeader(
'X-Cache-Lookup', $lookup);
329 if ($params[
'cache.hit'] ===
true) {
330 $xcache =
'HIT from GuzzleCache';
331 } elseif ($params[
'cache.hit'] ==
'error') {
332 $xcache =
'HIT_ERROR from GuzzleCache';
334 $xcache =
'MISS from GuzzleCache';
337 if ($header = $response->getHeader(
'X-Cache')) {
339 $values = $header->toArray();
341 $response->setHeader(
'X-Cache', array_unique($values));
343 $response->setHeader(
'X-Cache', $xcache);
346 if ($response->isFresh() ===
false) {
347 $response->addHeader(
'Warning', sprintf(
'110 GuzzleCache/%s "Response is stale"',
Version::VERSION));
348 if ($params[
'cache.hit'] ===
'error') {
349 $response->addHeader(
'Warning', sprintf(
'111 GuzzleCache/%s "Revalidation failed"',
Version::VERSION));