summaryrefslogtreecommitdiff
path: root/tmp-upload
diff options
context:
space:
mode:
authorPeter Wu <lekensteyn@gmail.com>2013-06-26 19:48:33 +0200
committerPeter Wu <lekensteyn@gmail.com>2013-06-26 19:48:33 +0200
commit82c07bc02cafe9b8d6cb9fa2362b2ba6326d6a7b (patch)
treeabe9215c03b1f9133f96b4dab2b0e73f046c1113 /tmp-upload
parentc6bff4f7fc3ffc0e1e9883a812e05b53995514d4 (diff)
downloadscripts-82c07bc02cafe9b8d6cb9fa2362b2ba6326d6a7b.tar.gz
tmp-upload: support subdirs, duplicate detection
Diffstat (limited to 'tmp-upload')
-rwxr-xr-xtmp-upload103
1 files changed, 76 insertions, 27 deletions
diff --git a/tmp-upload b/tmp-upload
index 913c129..3578a50 100755
--- a/tmp-upload
+++ b/tmp-upload
@@ -2,6 +2,15 @@
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
+
out="$(mktemp /tmp/tmp-upload-php.XXXXXXXX)"
cleanup() {
rm -v "$out"
@@ -26,26 +35,40 @@ function get_mime_type($file) {
}
$url = $_SERVER['REQUEST_URI'];
-if ($url != '/') {
- /* 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, $cwdir . DIRECTORY_SEPARATOR) !== 0) {
- http_response_code(403);
+/* 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;
}
+ $relDir = substr($path, strlen($path . 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);
@@ -59,24 +82,34 @@ if ($url != '/') {
header("Content-Length: $filesize");
}
+ error_log(sprintf("download %s %s %d", $mimetype, $path, $filesize));
readfile($path);
exit;
}
$msg = NULL;
if (isset($_FILES["file"]["name"])) {
- $name = trim(basename($_FILES["file"]["name"]), ".");
- if (!$name) {
+ $upload = $_FILES["file"];
+ $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 = $name;
- for ($i=1; file_exists($filename); $i++) {
- $filename = "$filename.$i";
+ $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 (move_uploaded_file($_FILES["file"]["tmp_name"], $filename)) {
+ 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.";
}
@@ -99,26 +132,42 @@ if ($msg) echo "<p>$msg</p>";
<?php
mb_internal_encoding('UTF-8');
date_default_timezone_set('Europe/Amsterdam');
-$dir = new DirectoryIterator('.');
+$dir = new DirectoryIterator($path);
+
foreach ($dir as $f) {
if ($f->isDot()) {
- continue;
+ //continue;
}
$filename = $f->getFilename();
$len = mb_strlen($filename);
- if ($len > 50) {
- $dispName = mb_substr($filename, 0, 47) . '..>';
+ $maxLen = $f->isDir() ? 49 : 50;
+ if ($len > $maxLen) {
+ $dispName = mb_substr($filename, 0, $maxLen - 3) . '..>';
} else {
$dispName = $filename;
}
+ if ($f->isDir()) {
+ $filename .= '/';
+ $dispName .= '/';
+ }
printf('<a href="%s">%s</a>%s %s %20d' . "\n",
htmlspecialchars($filename),
htmlspecialchars($dispName),
- str_repeat(' ', max(0, 50 - $len)),
+ 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);
+}
?>
</pre>