-
-
Save DaveRandom/234e9e04f238eb4a584724295c94ad03 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
// This is the absolute path under which all the files that are allowed for download are stored | |
const FILES_ROOT_DIR = __DIR__; | |
// This is the path that was specified by the user | |
$userPath = $_GET['file']; | |
// First get the normalised canonical path of the base dir | |
$baseDir = realpath(FILES_ROOT_DIR); | |
if ($baseDir === false) { | |
header('HTTP/1.1 500 Internal Server Error'); | |
exit("The configured root path does not exist or is not accessible"); | |
} | |
// Next, try to resolve the user-supplied path against the root dir | |
$target = realpath($baseDir . '/' . ltrim($userPath, '/')); | |
if ($target === false || !is_file($target)) { | |
header('HTTP/1.1 404 Not Found'); | |
exit("The specified path does not exist or is not a file"); | |
} | |
// extract the start of the resolved path that should match the root dir | |
// get 1 more character, we need to check it's a slash | |
$targetBaseDirPath = substr($target, 0, strlen($baseDir) + 1); | |
// Now check that the resolved target path starts with the exact string of the base path | |
if ($targetBaseDirPath !== $baseDir . '/') { | |
header('HTTP/1.1 400 Bad Request'); | |
exit("The specified path is outside the root path"); | |
} | |
// Everything OK, output the file | |
// Load the files from the Resume lib (this should really be done with composer and autoloading) | |
require_once __DIR__ . '/Resume/DefaultOutputWriter.php'; | |
require_once __DIR__ . '/Resume/FileResource.php'; | |
require_once __DIR__ . '/Resume/HeaderSet.php'; | |
require_once __DIR__ . '/Resume/IncompatibleRangesException.php'; | |
require_once __DIR__ . '/Resume/InvalidRangeException.php'; | |
require_once __DIR__ . '/Resume/InvalidRangeHeaderException.php'; | |
require_once __DIR__ . '/Resume/LengthNotAvailableException.php'; | |
require_once __DIR__ . '/Resume/LogicException.php'; | |
require_once __DIR__ . '/Resume/NonExistentFileException.php'; | |
require_once __DIR__ . '/Resume/OutputWriter.php'; | |
require_once __DIR__ . '/Resume/Range.php'; | |
require_once __DIR__ . '/Resume/RangeNotApplicableException.php'; | |
require_once __DIR__ . '/Resume/RangeSet.php'; | |
require_once __DIR__ . '/Resume/RangeUnitProvider.php'; | |
require_once __DIR__ . '/Resume/Resource.php'; | |
require_once __DIR__ . '/Resume/ResourceServlet.php'; | |
require_once __DIR__ . '/Resume/RuntimeException.php'; | |
require_once __DIR__ . '/Resume/SendFileFailureException.php'; | |
require_once __DIR__ . '/Resume/UnreadableFileException.php'; | |
require_once __DIR__ . '/Resume/UnsatisfiableRangeException.php'; | |
require_once __DIR__ . '/Resume/functions.php'; | |
try { | |
$resource = new \DaveRandom\Resume\FileResource($target, 'video/mp4'); | |
// Note that this construct will still work if the client did not specify a Range: header | |
$rangeHeader = \DaveRandom\Resume\get_request_header('Range'); | |
$rangeSet = \DaveRandom\Resume\RangeSet::createFromHeader($rangeHeader); | |
// Discard any buffered output, and disable output buffering | |
while (ob_get_level()) { | |
ob_end_clean(); | |
} | |
(new \DaveRandom\Resume\ResourceServlet($resource)) | |
->sendResource($rangeSet); | |
} catch (\DaveRandom\Resume\InvalidRangeHeaderException $e) { | |
\header("HTTP/1.1 400 Bad Request"); | |
} catch (\DaveRandom\Resume\UnsatisfiableRangeException $e) { | |
\header("HTTP/1.1 416 Range Not Satisfiable"); | |
} catch (NonExistentFileException $e) { | |
\header("HTTP/1.1 404 Not Found"); | |
} catch (\DaveRandom\Resume\UnreadableFileException $e) { | |
\header("HTTP/1.1 500 Internal Server Error"); | |
} catch (\DaveRandom\Resume\SendFileFailureException $e) { | |
if (!\headers_sent()) { | |
\header("HTTP/1.1 500 Internal Server Error"); | |
} | |
echo "An error occurred while attempting to send the requested resource: {$e->getMessage()}"; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment