You are here

public function CdnFarfutureController::downloadByScheme in CDN 8.3

Serves the requested file with optimal far future expiration headers.

Parameters

\Symfony\Component\HttpFoundation\Request $request: The current request. $request->query must have relative_file_url, set by \Drupal\cdn\PathProcessor\CdnFarfuturePathProcessor.

string $security_token: The 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.

int $mtime: The file's mtime.

string $scheme: The file's scheme.

Return value

\Symfony\Component\HttpFoundation\BinaryFileResponse|\Symfony\Component\HttpFoundation\Response The response that will efficiently send the requested file.

Throws

\Symfony\Component\HttpKernel\Exception\BadRequestHttpException Thrown when the 'relative_file_url' query argument is not set, which can only happen in case of malicious requests or in case of a malfunction in \Drupal\cdn\PathProcessor\CdnFarfuturePathProcessor.

File

src/CdnFarfutureController.php, line 67

Class

CdnFarfutureController

Namespace

Drupal\cdn

Code

public function downloadByScheme(Request $request, string $security_token, int $mtime, string $scheme) : Response {

  // Validate the scheme early.
  if (!$request->query
    ->has('relative_file_url') || $scheme !== FileUrlGenerator::RELATIVE && !$this->streamWrapperManager
    ->isValidScheme($scheme)) {
    throw new BadRequestHttpException();
  }

  // Validate security token.
  $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) {
    return new Response('Invalid security token.', 403);
  }

  // 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($file_to_stream, 200, $this
    ->getFarfutureHeaders(), TRUE, NULL, FALSE, FALSE);
  $response
    ->isNotModified($request);
  return $response;
}