#!/bin/bash
host=0.0.0.0
port=1111
if [ -n "$1" ]; then
if [[ $1 =~ ^[0-9]+$ ]]; then
port=$1
else
echo "Usage: $0 port"
exit 1
fi
fi
# Temporary directory for storing uploads and PHP script
tmpdir="$(mktemp -d)"
out="$tmpdir/upload.php"
cleanup() {
rm -rvf "$tmpdir"
}
trap cleanup EXIT
# wrap
startline=$(grep -hn -F -m 1 "# stuff ""below" "$0" | cut -d: -f1)
tail -n+$((startline+1)) "$0" > "$out"
php -d post_max_size=128M -d upload_max_filesize=128M \
-d upload_tmp_dir="$tmpdir/" \
-d open_basedir="$tmpdir/:$(pwd)/" \
-S "$host:$port" "$out"
exit
# stuff below
file($file);
}
return false;
}
$url = urldecode($_SERVER['REQUEST_URI']);
/* Simply returning false causes PHP to parse (index).php. Unwanted,
* therefore serve it here. First check whether the path is within the
* current working directory, then whether the file exists or not. */
$cwdir = realpath(".");
if ($cwdir === FALSE) {
http_response_code(500);
exit;
}
$path = realpath("./" . $url);
if ($path === FALSE) {
http_response_code(404);
exit;
}
if (strpos($path . DIRECTORY_SEPARATOR, $cwdir . DIRECTORY_SEPARATOR) !== 0) {
http_response_code(403);
exit;
}
$relDir = '';
if (is_dir($path)) {
if (substr($url, -1) !== '/') {
header("Location: $url/");
exit;
}
/* remove common prefix */
$rootDir = realpath(".");
if ($cwdir == '/') {
$relDir = substr($path, strlen($cwdir));
} else {
$relDir = substr($path, strlen($cwdir . DIRECTORY_SEPARATOR));
}
if (!strlen($relDir)) {
$relDir = '.';
}
$relDir .= DIRECTORY_SEPARATOR;
} else {
/* determine content type and size in bytes */
$filesize = filesize($path);
$mimetype = get_mime_type($path);
if (!$mimetype) {
http_response_code(500);
exit;
}
header("Content-Type: $mimetype");
if ($filesize !== false) {
header("Content-Length: $filesize");
}
error_log(sprintf("download %s %s %d", $mimetype, $path, $filesize));
readfile($path);
exit;
}
$msg = "";
if (isset($_FILES["file"]["name"]) && is_array($_FILES["file"]["name"])) {
$upload = $_FILES["file"];
for ($i=0; $i
\n";
}
}
function saveUpload($upload) {
global $relDir;
$msg = NULL;
$name = trim(basename($upload["name"]), ".");
$name = preg_replace('/[\x00-\x1F\x7F]/', '', $name);
if ($relDir === '') {
$msg = 'Invalid upload directory!';
} else if ($name === '') {
$msg = "No filename is given!";
} else if (!$_FILES["file"]["size"]) {
$msg = "I do not accept empty files!";
} else {
$filename = $relDir . $name;
$is_dupe = file_equals($filename, $upload["tmp_name"], $upload["size"]);
for ($i=1; !$is_dupe && file_exists($filename); $i++) {
$filename = "$name.$i";
$is_dupe = file_equals($filename, $upload["tmp_name"], $upload["size"]);
}
if ($is_dupe) {
$msg = "Uploaded file is a duplicate of " . htmlspecialchars($filename);
} else if (move_uploaded_file($upload["tmp_name"], $filename)) {
$msg = "File is saved as " . htmlspecialchars($filename);
error_log(sprintf("upload %s", $filename));
} else {
$msg = "File could not be saved.";
}
}
return $msg;
}
?>
$msg
getFilename(); /* skip top-level directory due to basedir restrictions */ if ($filename == '..' && $relDir == '.' . DIRECTORY_SEPARATOR) { continue; } $len = mb_strlen($filename); $maxLen = $f->isDir() ? 49 : 50; if ($len > $maxLen) { $dispName = mb_substr($filename, 0, $maxLen - 3) . '..>'; } else { $dispName = $filename; } if ($f->isDir()) { $filename .= '/'; $dispName .= '/'; } printf('%s%s %s %20d' . "\n", htmlspecialchars($filename), htmlspecialchars($dispName), str_repeat(' ', max(0, $maxLen - $len)), date('d-M-Y H:i', $f->getMTime()), $f->getSize() ); } function file_equals($newFile, $refFile, $refSize) { if (!file_exists($newFile)) { return false; } $newSize = filesize($newFile); if ($newSize !== $refSize) { return false; } return md5_file($newFile) === md5_file($refFile); } ?>