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