scratch – Blame information for rev 52
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
7 | office | 1 | <?php |
2 | |||
3 | ########################################################################### |
||
4 | ## Copyright (C) Wizardry and Steamworks 2017 - License: GNU GPLv3 ## |
||
5 | ########################################################################### |
||
6 | |||
13 | office | 7 | require_once('inc/pseudocrypt.php'); |
8 | require_once('inc/functions.php'); |
||
7 | office | 9 | require_once('config.php'); |
10 | |||
52 | office | 11 | #### POST -> upload / GET -> download |
12 | switch ($_SERVER['REQUEST_METHOD']) { |
||
13 | case 'POST': |
||
14 | #### Retrieve uploaded file. |
||
15 | if (!empty($_FILES['file']) and |
||
16 | is_uploaded_file($_FILES['file']['tmp_name'])) { |
||
17 | # Regular multipart/form-data upload. |
||
18 | $name = $_FILES['file']['name']; |
||
19 | $data = file_get_contents($_FILES['file']['tmp_name']); |
||
20 | } else { |
||
21 | # Raw POST data. |
||
22 | $name = urldecode(@$_SERVER['HTTP_X_FILE_NAME']); |
||
23 | $data = file_get_contents("php://input"); |
||
24 | } |
||
7 | office | 25 | |
52 | office | 26 | #### Grab the file extension. |
27 | $fileExtension = pathinfo($name, PATHINFO_EXTENSION); |
||
11 | office | 28 | |
52 | office | 29 | #### If the extension is not allowed then change it to a text extension. |
30 | if (!isset($fileExtension) || |
||
31 | !in_array(strtoupper($fileExtension), |
||
32 | array_map('strtoupper', $ALLOWED_FILE_EXTENSIONS))) { |
||
33 | header("HTTP/1.1 500 Internal Server Error", true, 500); |
||
34 | return; |
||
35 | } |
||
14 | office | 36 | |
52 | office | 37 | #### Hash filename. |
38 | $file = strtolower( |
||
39 | PseudoCrypt::hash( |
||
40 | preg_replace( |
||
41 | '/\D/', |
||
42 | '', |
||
43 | hash( |
||
44 | 'sha512', |
||
45 | $data |
||
46 | ) |
||
47 | ), |
||
48 | $ASSET_HASH_SIZE |
||
7 | office | 49 | ) |
52 | office | 50 | ); |
14 | office | 51 | |
52 | office | 52 | #### Build the user path. |
53 | $userPath = join( |
||
54 | DIRECTORY_SEPARATOR, |
||
55 | array( |
||
56 | $STORE_FOLDER, |
||
57 | $file |
||
58 | ) |
||
59 | ); |
||
11 | office | 60 | |
52 | office | 61 | #### Check for path traversals |
62 | $pathPart = pathinfo($userPath.'.'.$fileExtension); |
||
63 | if (strcasecmp( |
||
64 | realpath($pathPart['dirname']), realpath($STORE_FOLDER)) != 0) { |
||
65 | return; |
||
66 | } |
||
7 | office | 67 | |
52 | office | 68 | #### Store the file. |
69 | atomized_put_contents($userPath.'.'.$fileExtension, $data); |
||
14 | office | 70 | |
52 | office | 71 | ### Return the URL to the file. |
72 | header('Content-Type: text/plain; charset=utf-8'); |
||
73 | echo sprintf('%s/%s', trim($URL_PATH, '/'), $file); |
||
74 | break; |
||
75 | case 'GET': |
||
76 | ### If no file has been specified for download then return. |
||
77 | if (!isset($_GET['o']) or empty($_GET['o'])) { |
||
78 | http_response_code(404); |
||
79 | return; |
||
80 | } |
||
81 | |||
82 | $file = array_shift( |
||
83 | preg_grep( |
||
84 | "/$_GET[o]/", |
||
85 | scandir($STORE_FOLDER) |
||
86 | ) |
||
87 | ); |
||
88 | |||
89 | if (!isset($file) or empty($file)) |
||
90 | return; |
||
91 | |||
92 | ### Open MIME info database and send the content type. |
||
93 | $finfo = finfo_open(FILEINFO_MIME_TYPE); |
||
94 | if (!$finfo) { |
||
95 | http_response_code(500); |
||
96 | return; |
||
97 | } |
||
98 | |||
99 | header('Content-type: '.finfo_file($finfo, $STORE_FOLDER.'/'.$file)); |
||
100 | finfo_close($finfo); |
||
101 | |||
102 | ### Send the file along with the inline content disposition. |
||
103 | header('Content-length: '.(int)get_file_size($STORE_FOLDER.'/'.$file)); |
||
104 | header('Content-Disposition: inline; filename="' . basename($STORE_FOLDER.'/'.$file) . '"'); |
||
105 | header('X-Sendfile: '.$STORE_FOLDER.'/'.$file); |
||
106 | break; |
||
107 | } |