Subject: [PATCH] Issue #3171559 reroll patch.
---
Index: src/EventSubscriber/StageFileProxySubscriber.php
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/src/EventSubscriber/StageFileProxySubscriber.php b/src/EventSubscriber/StageFileProxySubscriber.php
--- a/src/EventSubscriber/StageFileProxySubscriber.php	(revision a26b05f77adeec5cec7ff340b0acea0d1d3b1473)
+++ b/src/EventSubscriber/StageFileProxySubscriber.php	(revision e5cebbb05fab014e6608a53cb80a578a2b255856)
@@ -7,6 +7,7 @@
 use Drupal\Core\Routing\TrustedRedirectResponse;
 use Drupal\Core\StreamWrapper\StreamWrapperManager;
 use Drupal\Core\Url;
+use Drupal\image\Controller\ImageStyleDownloadController;
 use Drupal\stage_file_proxy\DownloadManagerInterface;
 use Drupal\stage_file_proxy\EventDispatcher\AlterExcludedPathsEvent;
 use Psr\Log\LoggerInterface;
@@ -109,15 +110,30 @@
     }
 
     $request_path = rawurldecode($request_path);
+
     // Path relative to file directory. Used for hotlinking.
     $relative_path = mb_substr($request_path, mb_strlen($file_dir) + 1);
     // If file is fetched and use_imagecache_root is set, original is used.
     $paths = [$relative_path];
 
+    // Image style file conversion support.
+    $unconverted_path = substr(ImageStyleDownloadController::getUriWithoutConvertedExtension('public://' . $relative_path), strlen('public://'));
+    if ($unconverted_path !== $relative_path) {
+      if ($config->get('use_imagecache_root')) {
+        // Check the unconverted file path first in order to use the local
+        // original image.
+        array_unshift($paths, $unconverted_path);
+      }
+      else {
+        // Check the unconverted path after the image derivative.
+        $paths[] = $unconverted_path;
+      }
+    }
+
     // Webp support.
     $is_webp = FALSE;
-    if (strpos($relative_path, '.webp')) {
-      $paths[] = str_replace('.webp', '', $relative_path);
+    if (strpos($request_path, '.webp')) {
+      $request_path = str_replace('.webp', '', $request_path);
       $is_webp = TRUE;
     }
 
@@ -139,7 +155,7 @@
           // Imagecache can generate it without our help.
           return;
         }
-        if ($config->get('use_imagecache_root')) {
+        if ($config->get('use_imagecache_root') && $unconverted_path === $relative_path) {
           // Config says: Fetch the original.
           $fetch_path = StreamWrapperManager::getTarget($original_path);
         }
@@ -154,6 +170,7 @@
       ];
 
       if ($config->get('hotlink')) {
+        $relative_path = UrlHelper::encodePath($relative_path);
         $location = Url::fromUri("$server/$remote_file_dir/$relative_path", [
           'query' => $query_parameters,
           'absolute' => TRUE,
@@ -174,38 +191,6 @@
     }
   }
 
-  /**
-   * Get the file URI without the extension from any conversion image style.
-   *
-   * If the image style converted the image, then an extension has been added
-   * to the original file, resulting in filenames like image.png.jpeg.
-   *
-   * @param string $path
-   *   The file path.
-   *
-   * @return string
-   *   The file path without the extension from any conversion image style.
-   *   Defaults to the $path when the $path does not have a double extension.
-   *
-   * @todo Use ImageStyleDownloadController method for a URI once https://www.drupal.org/project/drupal/issues/2786735 has been committed.
-   * @todo this is used by #3402972 but caused regressions.
-   */
-  public static function getFilePathWithoutConvertedExtension(string $path): string {
-    $original_path = $path;
-    $original_path = '/' . ltrim($original_path, '/');
-    $path_info = pathinfo($original_path);
-    // Only convert the URI when the filename still has an extension.
-    if (!empty($path_info['filename']) && pathinfo($path_info['filename'], PATHINFO_EXTENSION)) {
-      $original_path = '';
-      if (!empty($path_info['dirname']) && $path_info['dirname'] !== '.') {
-        $original_path .= $path_info['dirname'] . DIRECTORY_SEPARATOR;
-      }
-      $original_path .= $path_info['filename'];
-    }
-
-    return str_starts_with($path, '/') ? $original_path : ltrim($original_path, '/');
-  }
-
   /**
    * Registers the methods in this class that should be listeners.
    *
