Mercurial > hg > isophonics-drupal-site
diff core/modules/system/src/FileDownloadController.php @ 0:4c8ae668cc8c
Initial import (non-working)
author | Chris Cannam |
---|---|
date | Wed, 29 Nov 2017 16:09:58 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/core/modules/system/src/FileDownloadController.php Wed Nov 29 16:09:58 2017 +0000 @@ -0,0 +1,70 @@ +<?php + +namespace Drupal\system; + +use Drupal\Core\Controller\ControllerBase; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; +use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; +use Symfony\Component\HttpFoundation\BinaryFileResponse; + +/** + * System file controller. + */ +class FileDownloadController extends ControllerBase { + + /** + * Handles private file transfers. + * + * Call modules that implement hook_file_download() to find out if a file is + * accessible and what headers it should be transferred with. If one or more + * modules returned headers the download will start with the returned headers. + * If a module returns -1 an AccessDeniedHttpException will be thrown. If the + * file exists but no modules responded an AccessDeniedHttpException will be + * thrown. If the file does not exist a NotFoundHttpException will be thrown. + * + * @see hook_file_download() + * + * @param \Symfony\Component\HttpFoundation\Request $request + * The request object. + * @param string $scheme + * The file scheme, defaults to 'private'. + * + * @return \Symfony\Component\HttpFoundation\BinaryFileResponse + * The transferred file as response. + * + * @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException + * Thrown when the requested file does not exist. + * @throws \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException + * Thrown when the user does not have access to the file. + */ + public function download(Request $request, $scheme = 'private') { + $target = $request->query->get('file'); + // Merge remaining path arguments into relative file path. + $uri = $scheme . '://' . $target; + + if (file_stream_wrapper_valid_scheme($scheme) && file_exists($uri)) { + // Let other modules provide headers and controls access to the file. + $headers = $this->moduleHandler()->invokeAll('file_download', [$uri]); + + foreach ($headers as $result) { + if ($result == -1) { + throw new AccessDeniedHttpException(); + } + } + + if (count($headers)) { + // \Drupal\Core\EventSubscriber\FinishResponseSubscriber::onRespond() + // sets response as not cacheable if the Cache-Control header is not + // already modified. We pass in FALSE for non-private schemes for the + // $public parameter to make sure we don't change the headers. + return new BinaryFileResponse($uri, 200, $headers, $scheme !== 'private'); + } + + throw new AccessDeniedHttpException(); + } + + throw new NotFoundHttpException(); + } + +}