From 4f37d8d64c2ffb6e0de12a79f03a4fc99afe9373 Mon Sep 17 00:00:00 2001
From: nod_ <nod_@598310.no-reply.drupal.org>
Date: Sat, 7 Sep 2024 00:03:45 +0200
Subject: [PATCH] Issue #3454507 by hablat, catch: Aggregated asset generation
 causes uncacheable assets

---
 .../src/Controller/AssetControllerBase.php    | 19 +++++++++++++++----
 .../Asset/AssetOptimizationTest.php           | 12 ++++--------
 2 files changed, 19 insertions(+), 12 deletions(-)

diff --git a/core/modules/system/src/Controller/AssetControllerBase.php b/core/modules/system/src/Controller/AssetControllerBase.php
index 6d4b74c3a46e..4f8d5ad69659 100644
--- a/core/modules/system/src/Controller/AssetControllerBase.php
+++ b/core/modules/system/src/Controller/AssetControllerBase.php
@@ -16,6 +16,7 @@
 use Drupal\Core\Theme\ThemeManagerInterface;
 use Drupal\system\FileDownloadController;
 use Symfony\Component\HttpFoundation\BinaryFileResponse;
+use Symfony\Component\HttpFoundation\RedirectResponse;
 use Symfony\Component\HttpFoundation\Request;
 use Symfony\Component\HttpFoundation\Response;
 use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
@@ -183,6 +184,11 @@ public function deliver(Request $request, string $file_name) {
     $generated_hash = $this->generateHash($group);
     $data = $this->optimizer->optimizeGroup($group);
 
+    $response = new Response($data, 200, [
+      'Cache-control' => static::CACHE_CONTROL,
+      'Content-Type' => $this->contentType,
+    ]);
+
     // However, the hash from the library definitions in code may not match the
     // hash from the URL. This can be for three reasons:
     // 1. Someone has requested an outdated URL, i.e. from a cached page, which
@@ -198,10 +204,15 @@ public function deliver(Request $request, string $file_name) {
     if (hash_equals($generated_hash, $received_hash)) {
       $this->dumper->dumpToUri($data, $this->assetType, $uri);
     }
-    return new Response($data, 200, [
-      'Cache-control' => static::CACHE_CONTROL,
-      'Content-Type' => $this->contentType,
-    ]);
+    else {
+      $expected_filename = $this->fileExtension . '_' . $generated_hash . '.' . $this->fileExtension;
+      $response = new RedirectResponse(
+        str_replace($file_name, $expected_filename, $request->getRequestUri()),
+        301,
+        ['Cache-Control' => 'public, max-age=3600, must-revalidate'],
+      );
+    }
+    return $response;
   }
 
   /**
diff --git a/core/tests/Drupal/FunctionalTests/Asset/AssetOptimizationTest.php b/core/tests/Drupal/FunctionalTests/Asset/AssetOptimizationTest.php
index dd0fdbd9614b..0b298f2175ec 100644
--- a/core/tests/Drupal/FunctionalTests/Asset/AssetOptimizationTest.php
+++ b/core/tests/Drupal/FunctionalTests/Asset/AssetOptimizationTest.php
@@ -187,16 +187,12 @@ protected function assertInvalidAggregates(string $url): void {
     $session->visit($this->setInvalidLibrary($url));
     $this->assertSession()->statusCodeEquals(200);
 
+    // When an invalid asset hash name is given.
     $session->visit($this->replaceGroupHash($url));
     $this->assertSession()->statusCodeEquals(200);
-    $headers = $session->getResponseHeaders();
-    $this->assertEquals(['no-store, private'], $headers['Cache-Control']);
-
-    // And again to confirm it's not cached on disk.
-    $session->visit($this->replaceGroupHash($url));
-    $this->assertSession()->statusCodeEquals(200);
-    $headers = $session->getResponseHeaders();
-    $this->assertEquals(['no-store, private'], $headers['Cache-Control']);
+    $current_url = $session->getCurrentUrl();
+    // Redirect to the correct one.
+    $this->assertEquals($url, $current_url);
   }
 
   /**
-- 
GitLab