diff options
Diffstat (limited to 'static')
| -rw-r--r-- | static/classes/UploadedFile.class.php | 32 | ||||
| -rw-r--r-- | static/favicon.ico | bin | 0 -> 4119 bytes | |||
| -rw-r--r-- | static/grill.php | 16 | ||||
| -rw-r--r-- | static/includes/database.inc.php | 6 | ||||
| -rw-r--r-- | static/includes/settings.inc.php | 19 | ||||
| -rw-r--r-- | static/upload.php | 159 |
6 files changed, 232 insertions, 0 deletions
diff --git a/static/classes/UploadedFile.class.php b/static/classes/UploadedFile.class.php new file mode 100644 index 0000000..5b7ba9b --- /dev/null +++ b/static/classes/UploadedFile.class.php @@ -0,0 +1,32 @@ +<?php + +class UploadedFile { + /* Public attributes */ + public $name; + public $mime; + public $tempfile; + public $error; + public $size; + + /* Cached checksums */ + private $sha1; + private $crc32; + + /** + * Generates the SHA1 or returns the cached SHA1 hash for the file. + */ + public function get_sha1 () { + if (! $this->sha1) $this->sha1 = sha1_file($this->tempfile); + + return $this->sha1; + } + /** + * Generates the CRC32 or returns the cached CRC32 hash for the file. + */ + public function get_crc32 () { + if (! $this->crc32) $this->crc32 = hash_file('crc32b', $this->tempfile); + + return $this->crc32; + } +} +?> diff --git a/static/favicon.ico b/static/favicon.ico Binary files differnew file mode 100644 index 0000000..b115e11 --- /dev/null +++ b/static/favicon.ico diff --git a/static/grill.php b/static/grill.php new file mode 100644 index 0000000..34bdce1 --- /dev/null +++ b/static/grill.php @@ -0,0 +1,16 @@ +<?php +$images = array( + 'img/2.png', + 'img/3.png', + 'img/4.png', + 'img/5.png', + 'img/6.png', + 'img/7.png', + 'img/8.png', + 'img/9.png', + 'img/10.png' +); +if (headers_sent() === false) { + header('Location: ' . $images[array_rand($images)], true, 303); +} +?> diff --git a/static/includes/database.inc.php b/static/includes/database.inc.php new file mode 100644 index 0000000..2ed0274 --- /dev/null +++ b/static/includes/database.inc.php @@ -0,0 +1,6 @@ +<?php +include_once 'settings.inc.php'; + +/* NOTE: we don't have to unref the PDO because we're not long-running */ +$db = new PDO(POMF_DB_CONN, POMF_DB_USER, POMF_DB_PASS); +?> diff --git a/static/includes/settings.inc.php b/static/includes/settings.inc.php new file mode 100644 index 0000000..73c2ae7 --- /dev/null +++ b/static/includes/settings.inc.php @@ -0,0 +1,19 @@ +<?php +/** + * PDO Connection data + */ +// PDO socket +define('POMF_DB_CONN', 'mysql:host=127.0.0.1;dbname=pomf'); +// PDO user +define('POMF_DB_USER', 'pomf'); +// PDO password +define('POMF_DB_PASS', '***'); + +/** + * File stuff + */ +// Root location of files +define('POMF_FILES_ROOT', '/mnt/disk1/pomf/files/'); +// How many times to retry when exists() before giving up +define('POMF_FILES_RETRIES', 5); +?> diff --git a/static/upload.php b/static/upload.php new file mode 100644 index 0000000..e2a3016 --- /dev/null +++ b/static/upload.php @@ -0,0 +1,159 @@ +<?php +include_once 'classes/UploadedFile.class.php'; +include_once 'includes/settings.inc.php'; +include_once 'includes/database.inc.php'; + +/** + * Generates a name for the file, retrying until we get an unused one + * + * @param UploadedFile $file + * @returns string + */ +function generate_name ($file) { + // We start at N retries, and --N until we give up + $tries = POMF_FILES_RETRIES; + // We rip out the extension using pathinfo + // TODO: figure out a solution for .tar.gz and similar files? + $ext = pathinfo($file->name, PATHINFO_EXTENSION); + // Take the first 3 chars of the CRC32 checksum + $hashchunk = substr($file->get_crc32(), 0, 3); + do { + // If we run out of tries, throw an exception. Should be caught and JSONified. + if ($tries-- == 0) throw new Exception('Gave up trying to find an unused name'); + + // TODO: come up with a better name generating algorithm + $newname = ''; // Filename Generator: + $newname .= chr(mt_rand(ord("a"), ord("z"))); // + random lowercase letter + $newname .= $hashchunk; // + first 3 of crc32b checksum + $newname .= chr(mt_rand(ord("a"), ord("z"))); // + random lowercase letter + $newname .= '.' . $ext; // + '.' + extension + + } while (file_exists(POMF_FILES_ROOT . $newname)); // TODO: check the database instead? + + return $newname; +} + +/** + * Handles the uploading and db entry for a file + * + * @param UploadedFile $file + * @returns array + */ +function upload_file ($file) { + global $db; + + // If the file has an error attached, we just throw it as an exception. + if ($file->error) throw new Exception($file->error); + + // Check if we have a file with that hash in the db + $q = $db->prepare("SELECT hash, filename, size FROM files WHERE hash = (:hash)"); + $q->bindValue('hash', $file->get_sha1()); + $q->execute(); + $result = $q->fetch(); + + // If we found a file with the same checksums, then we can assume it's a dupe + // so we don't bother with it, and just unlink (delete) the tmpfile and return + // the previous data. + if ($result['hash'] === $file->get_sha1()) { + unlink($file->tempfile); + return array( + 'hash' => $result['hash'], + 'name' => $file->name, + 'url' => $result['filename'], + 'size' => $result['size'] + ); + } else { + // Generate a name for the file + $newname = generate_name($file); + + // Attempt to move it to the static directory + if (move_uploaded_file($file->tempfile, POMF_FILES_ROOT . $newname)) { + // Add it to the database + $q = $db->prepare('INSERT INTO files (hash, orginalname, filename, size, date, expire, delid)' . + 'VALUES (:hash, :orig, :name, :size, :date, :expires, :delid)'); + $q->bindValue(':hash', $file->get_sha1()); + $q->bindValue(':orig', $file->name); + $q->bindValue(':name', $newname); + $q->bindValue(':size', $file->size); + $q->bindValue(':date', date('Y-m-d')); + $q->bindValue(':expires', null); + $q->bindValue(':delid', sha1($file->tempfile)); + $q->execute(); + + return array( + 'hash' => $file->get_sha1(), + 'name' => $file->name, + 'url' => $newname, + 'size' => $file->size + ); + } else { + throw new Exception('Failed to move file to destination'); + } + } +} + +/** + * Reorganize the $_FILES array into something saner + * + * @param $_FILES + */ +function refiles ($files) { + $out = array(); + for ($i = 0, $n = count($files['name']); $i < $n; ++$i) { + // We create a new UploadedFile instance + $file = new UploadedFile(); + // And fill it with our shit + $file->name = $files['name'][$i]; + $file->mime = $files['type'][$i]; + $file->tempfile = $files['tmp_name'][$i]; + $file->error = $files['error'][$i]; + $file->size = $files['size'][$i]; + $out[] = &$file; + } + return $out; +} + +/** + * Responds to a request in JSON form. + */ +function respond ($code, $res = null) { + if (is_int($code)) { // If the code is an integer, we assume it's a response code + http_response_code($code); + } else { // Otherwise we just assume you left off the code and use the default and shift + http_response_code(200); + $res = $code; + } + + // Now we send the response based on the type + if ($res instanceof Exception) { + // If it's an Exception, we put the message in the error field + echo json_encode(array( + 'success' => false, + 'error' => $res->getMessage() + )); + } elseif (is_array($res)) { + // If it's an Array, we merge it with 'success' => true. + // Note that $res is later in the list, so you can override that. + echo json_encode(array_merge(array( + 'success' => true, + 'error' => null + ), $res)); + } +} + +if (isset($_FILES['files'])) { + try { + $uploads = refiles($_FILES['files']); + foreach ($uploads as $upload) { + $out[] = upload_file($upload); + } + respond(array( + 'files' => $out + )); + } catch (Exception $e) { + respond(500, $e); + } +} else { + respond(500, new Exception('Nigga what you doin\' here?')); +} +?> |
