annotate core/modules/system/src/FileDownloadController.php @ 19:fa3358dc1485 tip

Add ndrum files
author Chris Cannam
date Wed, 28 Aug 2019 13:14:47 +0100
parents 4c8ae668cc8c
children
rev   line source
Chris@0 1 <?php
Chris@0 2
Chris@0 3 namespace Drupal\system;
Chris@0 4
Chris@0 5 use Drupal\Core\Controller\ControllerBase;
Chris@0 6 use Symfony\Component\HttpFoundation\Request;
Chris@0 7 use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
Chris@0 8 use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
Chris@0 9 use Symfony\Component\HttpFoundation\BinaryFileResponse;
Chris@0 10
Chris@0 11 /**
Chris@0 12 * System file controller.
Chris@0 13 */
Chris@0 14 class FileDownloadController extends ControllerBase {
Chris@0 15
Chris@0 16 /**
Chris@0 17 * Handles private file transfers.
Chris@0 18 *
Chris@0 19 * Call modules that implement hook_file_download() to find out if a file is
Chris@0 20 * accessible and what headers it should be transferred with. If one or more
Chris@0 21 * modules returned headers the download will start with the returned headers.
Chris@0 22 * If a module returns -1 an AccessDeniedHttpException will be thrown. If the
Chris@0 23 * file exists but no modules responded an AccessDeniedHttpException will be
Chris@0 24 * thrown. If the file does not exist a NotFoundHttpException will be thrown.
Chris@0 25 *
Chris@0 26 * @see hook_file_download()
Chris@0 27 *
Chris@0 28 * @param \Symfony\Component\HttpFoundation\Request $request
Chris@0 29 * The request object.
Chris@0 30 * @param string $scheme
Chris@0 31 * The file scheme, defaults to 'private'.
Chris@0 32 *
Chris@0 33 * @return \Symfony\Component\HttpFoundation\BinaryFileResponse
Chris@0 34 * The transferred file as response.
Chris@0 35 *
Chris@0 36 * @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException
Chris@0 37 * Thrown when the requested file does not exist.
Chris@0 38 * @throws \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException
Chris@0 39 * Thrown when the user does not have access to the file.
Chris@0 40 */
Chris@0 41 public function download(Request $request, $scheme = 'private') {
Chris@0 42 $target = $request->query->get('file');
Chris@0 43 // Merge remaining path arguments into relative file path.
Chris@0 44 $uri = $scheme . '://' . $target;
Chris@0 45
Chris@0 46 if (file_stream_wrapper_valid_scheme($scheme) && file_exists($uri)) {
Chris@0 47 // Let other modules provide headers and controls access to the file.
Chris@0 48 $headers = $this->moduleHandler()->invokeAll('file_download', [$uri]);
Chris@0 49
Chris@0 50 foreach ($headers as $result) {
Chris@0 51 if ($result == -1) {
Chris@0 52 throw new AccessDeniedHttpException();
Chris@0 53 }
Chris@0 54 }
Chris@0 55
Chris@0 56 if (count($headers)) {
Chris@0 57 // \Drupal\Core\EventSubscriber\FinishResponseSubscriber::onRespond()
Chris@0 58 // sets response as not cacheable if the Cache-Control header is not
Chris@0 59 // already modified. We pass in FALSE for non-private schemes for the
Chris@0 60 // $public parameter to make sure we don't change the headers.
Chris@0 61 return new BinaryFileResponse($uri, 200, $headers, $scheme !== 'private');
Chris@0 62 }
Chris@0 63
Chris@0 64 throw new AccessDeniedHttpException();
Chris@0 65 }
Chris@0 66
Chris@0 67 throw new NotFoundHttpException();
Chris@0 68 }
Chris@0 69
Chris@0 70 }