|
18 | 18 | use Symfony\Component\Cache\Adapter\TagAwareAdapter; |
19 | 19 | use Symfony\Component\Cache\Adapter\TagAwareAdapterInterface; |
20 | 20 | use Symfony\Component\Cache\PruneableInterface; |
| 21 | +use Symfony\Component\HttpFoundation\BinaryFileResponse; |
| 22 | +use Symfony\Component\HttpFoundation\File\Exception\FileNotFoundException; |
| 23 | +use Symfony\Component\HttpFoundation\File\File; |
21 | 24 | use Symfony\Component\HttpFoundation\Request; |
22 | 25 | use Symfony\Component\HttpFoundation\Response; |
23 | 26 | use Symfony\Component\Lock\Exception\LockReleasingException; |
@@ -203,7 +206,11 @@ public function write(Request $request, Response $response) |
203 | 206 | if (!$response->headers->has('X-Content-Digest')) { |
204 | 207 | $contentDigest = $this->generateContentDigest($response); |
205 | 208 |
|
206 | | - if (false === $this->saveDeferred($contentDigest, $response->getContent())) { |
| 209 | + $cacheValue = $this->isBinaryFileResponseContentDigest($contentDigest) ? |
| 210 | + $response->getFile()->getPathname() : |
| 211 | + $response->getContent(); |
| 212 | + |
| 213 | + if (false === $this->saveDeferred($contentDigest, $cacheValue)) { |
207 | 214 | throw new \RuntimeException('Unable to store the entity.'); |
208 | 215 | } |
209 | 216 |
|
@@ -462,9 +469,25 @@ public function getVaryKey(array $vary, Request $request) |
462 | 469 | */ |
463 | 470 | public function generateContentDigest(Response $response) |
464 | 471 | { |
| 472 | + if ($response instanceof BinaryFileResponse) { |
| 473 | + return 'bf'.hash_file('sha256', $response->getFile()->getPathname()); |
| 474 | + } |
| 475 | + |
465 | 476 | return 'en'.hash('sha256', $response->getContent()); |
466 | 477 | } |
467 | 478 |
|
| 479 | + /** |
| 480 | + * Test whether a given digest identifies a BinaryFileResponse. |
| 481 | + * |
| 482 | + * @param string $digest |
| 483 | + * |
| 484 | + * @return bool |
| 485 | + */ |
| 486 | + private function isBinaryFileResponseContentDigest($digest) |
| 487 | + { |
| 488 | + return 'bf' === substr($digest, 0, 2); |
| 489 | + } |
| 490 | + |
468 | 491 | /** |
469 | 492 | * Increases a counter every time an item is stored to the cache and then |
470 | 493 | * prunes expired cache entries if a configurable threshold is reached. |
@@ -522,20 +545,34 @@ private function saveDeferred($key, $data, $expiresAfter = null, $tags = []) |
522 | 545 | */ |
523 | 546 | private function restoreResponse(array $cacheData) |
524 | 547 | { |
525 | | - $body = null; |
526 | | - |
527 | 548 | if (isset($cacheData['headers']['x-content-digest'][0])) { |
528 | 549 | $item = $this->cache->getItem($cacheData['headers']['x-content-digest'][0]); |
529 | 550 | if ($item->isHit()) { |
530 | | - $body = $item->get(); |
| 551 | + $value = $item->get(); |
| 552 | + |
| 553 | + if ($this->isBinaryFileResponseContentDigest($cacheData['headers']['x-content-digest'][0])) { |
| 554 | + try { |
| 555 | + $file = new File($value); |
| 556 | + } catch (FileNotFoundException $e) { |
| 557 | + return null; |
| 558 | + } |
| 559 | + |
| 560 | + return new BinaryFileResponse( |
| 561 | + $file, |
| 562 | + $cacheData['status'], |
| 563 | + $cacheData['headers'] |
| 564 | + ); |
| 565 | + } |
| 566 | + |
| 567 | + return new Response( |
| 568 | + $value, |
| 569 | + $cacheData['status'], |
| 570 | + $cacheData['headers'] |
| 571 | + ); |
531 | 572 | } |
532 | 573 | } |
533 | 574 |
|
534 | | - return new Response( |
535 | | - $body, |
536 | | - $cacheData['status'], |
537 | | - $cacheData['headers'] |
538 | | - ); |
| 575 | + return null; |
539 | 576 | } |
540 | 577 |
|
541 | 578 | /** |
|
0 commit comments