/** * @covers Util::downloadFileType() */ public function testDownloadFileType() { $vectors = [['in' => 'text/javascript', 'out' => 'text/plain'], ['in' => 'image/png', 'out' => 'image/png'], ['in' => 'application/javascript', 'out' => 'text/plain'], ['in' => 'text/html', 'out' => 'text/plain'], ['in' => 'text/html; charset=UTF-8', 'out' => 'text/plain; charset=UTF-8']]; foreach ($vectors as $test) { $this->assertSame($test['out'], Util::downloadFileType($test['in'])); } }
/** * Download a file (assuming we are allowed to) * * @param string $path * @param string $default Default MIME type * @route files/(.*) * @throws EmulatePageNotFound */ public function download(string $path, string $default = 'text/plain') { if (!$this->can('read')) { throw new EmulatePageNotFound(); } $pieces = \Airship\chunk($path); $filename = \array_pop($pieces); try { $fileData = $this->files->getFileInfo($this->cabin, $pieces, \urldecode($filename)); $realPath = AIRSHIP_UPLOADS . $fileData['realname']; if (!\file_exists($realPath)) { throw new FileNotFound(); } $fileData['type'] = Util::downloadFileType($fileData['type'], $default); $c = $this->config('file.cache'); if ($c > 0) { // Use caching \header('Cache-Control: private, max-age=' . $c); \header('Pragma: cache'); } // Serve the file \header('Content-Type: ' . $fileData['type']); /** * The following headers are necessary because Microsoft Internet * Explorer has a documented design flaw that, left unhandled, can * introduce a stored XSS vulnerability. The recommended solution * would be "never use Internet Explorer", but some people don't have * a choice in that matter. */ if (!$this->isViewable($fileData['type'])) { \header('Content-Disposition: attachment; filename="' . \urlencode($fileData['filename']) . '"'); \header('X-Download-Options: noopen'); } \header('X-Content-Type-Options: nosniff'); $this->airship_lens_object->sendStandardHeaders($fileData['type']); \readfile($realPath); exit; } catch (FileNotFound $ex) { // When all else fails, 404 not found \http_response_code(404); $this->lens('404'); exit(1); } }