-
Notifications
You must be signed in to change notification settings - Fork 4
/
index.php
171 lines (154 loc) · 4.29 KB
/
index.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
<?php
/**
* A minimal PhotoBackup API endpoint developed in PHP.
*
* @version 1.0.0
* @author Martijn van der Ven <[email protected]>
* @copyright 2015 Martijn van der Ven
* @license http://opensource.org/licenses/MIT The MIT License
*/
/**
* The password required to upload to this server.
*
* The password is currently stored as clear text here. PHP code is not normally
* readable by third-parties so this should be safe enough. Many applications
* store database credentials in this way as well. A secondary and safer way is
* being considered for the next version.
*
* @global string $Password A string (encapsulated by quotes).
*/
$Password = 'example';
/**
* The directory where files should be uploaded to.
*
* This directory path is relative to this index.php file and should not end
* with a /. It should point to an existing directory on the server.
*
* @global string $MediaRoot A string (encapsulated by quotes).
*/
$MediaRoot = 'photos';
// -----------------------------------------------------------------------------
// NO CONFIGURATION NECCESSARY BEYOND THIS POINT.
// -----------------------------------------------------------------------------
/**
* Establish what HTTP version is being used by the server.
*/
if (isset($_SERVER['SERVER_PROTOCOL'])) {
$protocol = $_SERVER['SERVER_PROTOCOL'];
} else {
$protocol = 'HTTP/1.0';
}
/**
* Find out if the client is requesting the test page.
*/
$request = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
$testing = substr($request, -5) === '/test';
/**
* If no data has been POSTed to the server and the client did not request the
* test page, exit imidiately.
*/
if (empty($_POST) && !$testing) {
exit();
}
/**
* If we are testing the server and see that no password has been set, exit with
* HTTP code 401.
*/
if (
$testing &&
(
!isset($Password) ||
!is_string($Password)
)
) {
header($protocol . ' 401 Unauthorized');
exit();
}
/**
* Exit with HTTP code 403 if no password has been set on the server, or if the
* client did not submit a password, or the submitted password did not match
* this server's password.
*/
if (
!isset($Password) ||
!is_string($Password) ||
!isset($_POST['password']) ||
$_POST['password'] !== hash('sha512', $Password)
) {
header($protocol . ' 403 Forbidden');
exit();
}
/**
* If the upload destination folder has not been configured, does not exist, or
* is not writable by PHP, exit with HTTP code 500.
*/
if (
!isset($MediaRoot) ||
!is_string($MediaRoot) ||
!file_exists($MediaRoot) ||
!is_dir($MediaRoot) ||
!is_writable($MediaRoot)
) {
header($protocol . ' 500 Internal Server Error');
exit();
}
/**
* If we were only supposed to test the server, end here.
*/
if ($testing) {
exit();
}
/**
* If the client did not submit a filesize, exit with HTTP code 400.
*/
if (!isset($_POST['filesize'])) {
header($protocol . ' 400 Bad Request');
exit();
}
/**
* If the client did not upload a file, or something went wrong in the upload
* process, exit with HTTP code 401.
*/
if (
!isset($_FILES['upfile']) ||
$_FILES['upfile']['error'] !== UPLOAD_ERR_OK ||
!is_uploaded_file($_FILES['upfile']['tmp_name'])
) {
header($protocol . ' 401 Unauthorized');
exit();
}
/**
* If the client submitted filesize did not match the uploaded file's size, exit
* with HTTP code 411.
*/
if (intval($_POST['filesize']) !== $_FILES['upfile']['size']) {
header($protocol . ' 411 Length Required');
exit();
}
/**
* Sanitize the file name to maximise server operating system compatibility and
* minimize possible attacks against this implementation.
*/
$filename = preg_replace('@\s+@', '-', $_FILES['upfile']['name']);
$filename = preg_replace('@[^0-9a-z._-]@i', '', $filename);
$target = $MediaRoot . '/' . $filename;
/**
* If a file with the same name and size exists, treat the new upload as a
* duplicate and exit.
*/
if (
file_exists($target) &&
filesize() === $_POST['filesize']
) {
header($protocol . ' 409 Conflict');
exit();
}
/**
* Move the uploaded file into the target directory. If anything did not work,
* exit with HTTP code 500.
*/
if (!move_uploaded_file($_FILES["upfile"]["tmp_name"], $target)) {
header($protocol . ' 500 Internal Server Error');
exit();
}
exit();