public function testCacheProvider() { $TMP_DIR = __DIR__ . '/tmp/'; $cacheProviders = [new ArrayCache(), new ChainCache([new ArrayCache()]), new FilesystemCache($TMP_DIR), new PhpFileCache($TMP_DIR)]; $request = new Request('GET', 'test.local'); $response = new Response(200, ['Cache-Control' => 'max-age=60'], 'Test content'); /** @var CacheProvider $cacheProvider */ foreach ($cacheProviders as $cacheProvider) { $this->rrmdir($TMP_DIR); $cache = new PrivateCache($cacheProvider); $cache->cache($request, $response); $entry = $cache->fetch($request); $this->assertNotNull($entry); $this->assertEquals((string) $response->getBody(), (string) $entry->getResponse()->getBody()); } $this->rrmdir($TMP_DIR); }
/** * @param CacheStorageInterface $cacheStorage * @return \Closure the Middleware for Guzzle HandlerStack */ public static function getMiddleware(CacheStorageInterface $cacheStorage = null) { if ($cacheStorage === null) { $cacheStorage = new PrivateCache(); } register_shutdown_function(['Kevinrob\\GuzzleCache\\CacheMiddleware', 'purgeReValidation']); return function (callable $handler) use(&$cacheStorage) { return function (RequestInterface $request, array $options) use($handler, &$cacheStorage) { $reqMethod = $request->getMethod(); if ($reqMethod !== 'GET' && $reqMethod !== 'HEAD') { // No caching for others methods return $handler($request, $options); } if ($request->hasHeader("X-ReValidation")) { return $handler($request->withoutHeader("X-ReValidation"), $options); } // If cache => return new FulfilledPromise(...) with response $cacheEntry = $cacheStorage->fetch($request); if ($cacheEntry instanceof CacheEntry) { if ($cacheEntry->isFresh()) { // Cache HIT! return new FulfilledPromise($cacheEntry->getResponse()->withHeader("X-Cache", "HIT")); } elseif ($cacheEntry->hasValidationInformation()) { // Re-validation header $request = static::getRequestWithReValidationHeader($request, $cacheEntry); if ($cacheEntry->staleWhileValidate()) { static::addReValidationRequest($request, $cacheStorage, $cacheEntry); return new FulfilledPromise($cacheEntry->getResponse()->withHeader("X-Cache", "Stale while revalidate")); } } } /** @var Promise $promise */ $promise = $handler($request, $options); return $promise->then(function (ResponseInterface $response) use($request, &$cacheStorage, $cacheEntry) { if ($response->getStatusCode() >= 500) { $responseStale = static::getStaleResponse($cacheEntry); if ($responseStale instanceof ResponseInterface) { return $responseStale; } } if ($response->getStatusCode() == 304 && $cacheEntry instanceof CacheEntry) { // Not modified => cache entry is re-validate /** @var ResponseInterface $response */ $response = $response->withStatus($cacheEntry->getResponse()->getStatusCode())->withHeader("X-Cache", "HIT with validation"); $response = $response->withBody($cacheEntry->getResponse()->getBody()); } // Add to the cache $cacheStorage->cache($request, $response); return $response; }, function (\Exception $ex) use($cacheEntry) { if ($ex instanceof TransferException) { $response = static::getStaleResponse($cacheEntry); if ($response instanceof ResponseInterface) { return $response; } } throw $ex; }); }; }; }