/** * @param RequestInterface $request * @param ResponseInterface $response * @return CacheEntry|null entry to save, null if can't cache it */ protected function getCacheObject(RequestInterface $request, ResponseInterface $response) { if (!isset($this->statusAccepted[$response->getStatusCode()])) { // Don't cache it return; } $cacheControl = new KeyValueHttpHeader($response->getHeader('Cache-Control')); $varyHeader = new KeyValueHttpHeader($response->getHeader('Vary')); if ($varyHeader->has('*')) { // This will never match with a request return; } if ($cacheControl->has('no-store')) { // No store allowed (maybe some sensitives data...) return; } if ($cacheControl->has('no-cache')) { // Stale response see RFC7234 section 5.2.1.4 $entry = new CacheEntry($request, $response, new \DateTime('-1 seconds')); return $entry->hasValidationInformation() ? $entry : null; } foreach ($this->ageKey as $key) { if ($cacheControl->has($key)) { return new CacheEntry($request, $response, new \DateTime('+' . (int) $cacheControl->get($key) . 'seconds')); } } if ($response->hasHeader('Expires')) { $expireAt = \DateTime::createFromFormat(\DateTime::RFC1123, $response->getHeaderLine('Expires')); if ($expireAt !== false) { return new CacheEntry($request, $response, $expireAt); } } return new CacheEntry($request, $response, new \DateTime('-1 seconds')); }
/** * @param ResponseInterface $response * @return CacheEntry|null entry to save, null if can't cache it */ protected function getCacheObject(ResponseInterface $response) { if ($response->hasHeader("Cache-Control")) { $cacheControlDirectives = $response->getHeader("Cache-Control"); if (in_array("no-store", $cacheControlDirectives)) { // No store allowed (maybe some sensitives data...) return null; } if (in_array("no-cache", $cacheControlDirectives)) { // Stale response see RFC7234 section 5.2.1.4 $entry = new CacheEntry($response, new \DateTime('-1 seconds')); return $entry->hasValidationInformation() ? $entry : null; } $matches = []; if (preg_match('/^max-age=([0-9]*)$/', $response->getHeaderLine("Cache-Control"), $matches)) { // Handle max-age header return new CacheEntry($response, new \DateTime('+' . $matches[1] . 'seconds')); } } if ($response->hasHeader("Expires")) { $expireAt = \DateTime::createFromFormat('D, d M Y H:i:s T', $response->getHeaderLine("Expires")); if ($expireAt !== FALSE) { return new CacheEntry($response, $expireAt); } } return new CacheEntry($response, new \DateTime('1 days ago')); }
/** * @param ResponseInterface $response * @return CacheEntry|null entry to save, null if can't cache it */ protected function getCacheObject(ResponseInterface $response) { if ($response->hasHeader("Cache-Control")) { $values = new KeyValueHttpHeader($response->getHeader("Cache-Control")); if ($values->has('no-store')) { // No store allowed (maybe some sensitives data...) return null; } if ($values->has('no-cache')) { // Stale response see RFC7234 section 5.2.1.4 $entry = new CacheEntry($response, new \DateTime('-1 seconds')); return $entry->hasValidationInformation() ? $entry : null; } if ($values->has('max-age')) { return new CacheEntry($response, new \DateTime('+' . $values->get('max-age') . 'seconds')); } return new CacheEntry($response, new \DateTime()); } if ($response->hasHeader("Expires")) { $expireAt = \DateTime::createFromFormat('D, d M Y H:i:s T', $response->getHeaderLine("Expires")); if ($expireAt !== FALSE) { return new CacheEntry($response, $expireAt); } } return new CacheEntry($response, new \DateTime('-1 seconds')); }
/** * {@inheritdoc} */ public function save($key, CacheEntry $data) { try { $lifeTime = $data->getTTL(); if ($lifeTime >= 0) { return $this->cache->save($key, gzcompress(serialize($data)), $lifeTime); } } catch (\Exception $ignored) { // No fail if we can't save it the storage } return false; }
/** * @param ResponseInterface $response * @param KeyValueHttpHeader $cacheControl * @return CacheEntry|null */ protected function getCacheObjectForCacheControl(ResponseInterface $response, KeyValueHttpHeader $cacheControl) { if ($cacheControl->has('no-store')) { // No store allowed (maybe some sensitives data...) return null; } if ($cacheControl->has('no-cache')) { // Stale response see RFC7234 section 5.2.1.4 $entry = new CacheEntry($response, new \DateTime('-1 seconds')); return $entry->hasValidationInformation() ? $entry : null; } if ($cacheControl->has('max-age')) { return new CacheEntry($response, new \DateTime('+' . (int) $cacheControl->get('max-age') . 'seconds')); } return new CacheEntry($response, new \DateTime()); }
/** * {@inheritdoc} */ public function save($key, CacheEntry $data) { try { $lifeTime = $data->getTTL(); if ($lifeTime === 0) { return $this->cache->forever($key, serialize($data)); } else { if ($lifeTime > 0) { return $this->cache->add($key, serialize($data), $lifeTime); } } } catch (\Exception $ignored) { // No fail if we can't save it the storage } return false; }
/** * @param RequestInterface $request * @param CacheEntry $cacheEntry * * @return RequestInterface */ protected static function getRequestWithReValidationHeader(RequestInterface $request, CacheEntry $cacheEntry) { if ($cacheEntry->getResponse()->hasHeader('Last-Modified')) { $request = $request->withHeader('If-Modified-Since', $cacheEntry->getResponse()->getHeader('Last-Modified')); } if ($cacheEntry->getResponse()->hasHeader('Etag')) { $request = $request->withHeader('If-None-Match', $cacheEntry->getResponse()->getHeader('Etag')); } return $request; }
/** * @param RequestInterface $request * @param CacheStorageInterface $cacheStorage * @param CacheEntry $cacheEntry * @return bool if added */ protected static function addReValidationRequest(RequestInterface $request, CacheStorageInterface &$cacheStorage, CacheEntry $cacheEntry) { // Add the promise for revalidate if (static::$client !== null) { /** @var RequestInterface $request */ $request = $request->withHeader("X-ReValidation", "1"); static::$waitingRevalidate[] = static::$client->sendAsync($request)->then(function (ResponseInterface $response) use($request, &$cacheStorage, $cacheEntry) { if ($response->getStatusCode() == 304) { // Not modified => cache entry is re-validate /** @var ResponseInterface $response */ $response = $response->withStatus($cacheEntry->getResponse()->getStatusCode()); $response = $response->withBody($cacheEntry->getResponse()->getBody()); } $cacheStorage->cache($request, $response); }); return true; } return false; }