src/CdnFarfutureController.php | 23 ++++++++++------------- src/File/FileUrlGenerator.php | 19 +++++++++---------- 2 files changed, 19 insertions(+), 23 deletions(-) diff --git a/src/CdnFarfutureController.php b/src/CdnFarfutureController.php index ec7ec75..d79f98d 100644 --- a/src/CdnFarfutureController.php +++ b/src/CdnFarfutureController.php @@ -70,25 +70,22 @@ class CdnFarfutureController { throw new BadRequestHttpException(); } - $path = $request->query->get('relative_file_url'); - // A relative URL for a file contains '%20' instead of spaces. A relative - // file path contains spaces. - $uri = $scheme === FileUrlGenerator::RELATIVE - ? $path - // Path comes with a leading slash from the URL. - : $scheme . ':/' . $path; // Validate security token. - $calculated_token = Crypt::hmacBase64($mtime . $scheme . $path, $this->privateKey->get() . Settings::getHashSalt()); + $relative_file_url = $request->query->get('relative_file_url'); + $calculated_token = Crypt::hmacBase64($mtime . $scheme . $relative_file_url, $this->privateKey->get() . Settings::getHashSalt()); if ($security_token !== $calculated_token) { throw new AccessDeniedHttpException('Invalid security token.'); } - // Strip the leading slash for truly relative paths. - if ($scheme === FileUrlGenerator::RELATIVE) { - $uri = substr($path, 1); - } + // A relative URL for a file contains '%20' instead of spaces. A relative + // file path contains spaces. + $relative_file_path = rawurldecode($relative_file_url); + + $file_to_stream = $scheme === FileUrlGenerator::RELATIVE + ? substr($relative_file_path, 1) + : $scheme . '://' . substr($relative_file_path, 1); - $response = new BinaryFileResponse(rawurldecode($uri), 200, $this->getFarfutureHeaders(), TRUE, NULL, FALSE, FALSE); + $response = new BinaryFileResponse($file_to_stream, 200, $this->getFarfutureHeaders(), TRUE, NULL, FALSE, FALSE); $response->isNotModified($request); return $response; } diff --git a/src/File/FileUrlGenerator.php b/src/File/FileUrlGenerator.php index 8a7314b..41a05b8 100644 --- a/src/File/FileUrlGenerator.php +++ b/src/File/FileUrlGenerator.php @@ -124,30 +124,29 @@ class FileUrlGenerator { if (!$scheme = $this->fileSystem->uriScheme($uri)) { $scheme = self::RELATIVE; - // A relative URL for a file contains '%20' instead of spaces. A relative - // file path contains spaces. - $file_path = $relative_url = '/' . $uri; - $real_file = $this->root . rawurldecode($relative_url);; + $relative_url = '/' . $uri; + $relative_file_path = rawurldecode($relative_url); + $absolute_file_path = $this->root . $relative_file_path; } else { - $file_uri = $real_file = $uri; - $file_path = '/' . substr($file_uri, strlen($scheme . '://')); $relative_url = str_replace($this->requestStack->getCurrentRequest()->getSchemeAndHttpHost() . $this->getBasePath(), '', $this->streamWrapperManager->getViaUri($uri)->getExternalUrl()); + $relative_file_path = rawurldecode('/' . substr($uri, strlen($scheme . '://'))); + $absolute_file_path = $scheme . '://' . $relative_file_path; } // When farfuture is enabled, rewrite the file URL to let Drupal serve the // file with optimal headers. Only possible if the file exists. - if ($this->settings->farfutureIsEnabled() && file_exists($real_file)) { + if ($this->settings->farfutureIsEnabled() && file_exists($absolute_file_path)) { // We do the filemtime() call separately, because a failed filemtime() // will cause a PHP warning to be written to the log, which would remove // any performance gain achieved by removing the file_exists() call. - $mtime = filemtime($real_file); + $mtime = filemtime($absolute_file_path); // Generate a security token. Ensures that users can not request any // file they want by manipulating the URL (they could otherwise request // settings.php for example). See https://www.drupal.org/node/1441502. - $calculated_token = Crypt::hmacBase64($mtime . $scheme . UrlHelper::encodePath($file_path), $this->privateKey->get() . Settings::getHashSalt()); - return '//' . $cdn_domain . $this->getBasePath() . '/cdn/ff/' . $calculated_token . '/' . $mtime . '/' . $scheme . $file_path; + $calculated_token = Crypt::hmacBase64($mtime . $scheme . UrlHelper::encodePath($relative_file_path), $this->privateKey->get() . Settings::getHashSalt()); + return '//' . $cdn_domain . $this->getBasePath() . '/cdn/ff/' . $calculated_token . '/' . $mtime . '/' . $scheme . $relative_file_path; } return '//' . $cdn_domain . $this->getBasePath() . $relative_url;