$config['max_upload_file_size']) { sendHttpErrorCodeAndMessage(406, 'File too large. Maximum file size: '.$config['max_upload_file_size']); } // check file name - return 406 (not acceptable) if file contains invalid characters foreach ($config['invalid_characters_in_filename'] as $invalidCharacter) { if (stripos($filename, $invalidCharacter) !== false) { sendHttpErrorCodeAndMessage(406, 'Invalid character found in filename.'); } } // generate slot uuid, register slot uuid and expected file size and expected mime type $basePath = $config['storage_base_path']; $slotUUID = generate_uuid(); registerSlot($slotUUID, $filename, $filesize, $type, $userJid, $config); if (!mkdir(getUploadFilePath($slotUUID, $config))) { sendHttpErrorCodeAndMessage(500, "Could not create directory for upload."); } // return 200 for success and get / put url Json formatted ( ['get'=>url, 'put'=>url] ) $result = array('put' => $config['base_url_put'].$slotUUID.'/'.$filename, 'get' => $config['base_url_get'].$slotUUID.'/'.$filename); echo json_encode($result); break; case 'PUT': // check slot uuid - return 403 if not existing $uri = $_SERVER["REQUEST_URI"]; $slotUUID = getUUIDFromUri($uri); $filename = getFilenameFromUri($uri); $uploadFilePath = getUploadFilePath($slotUUID, $config, $filename); if (file_exists($uploadFilePath)) { sendHttpErrorCodeAndMessage(403, "The slot was already used."); } if (!slotExists($slotUUID, $config)) { sendHttpErrorCodeAndMessage(403, "The slot does not exist."); } $slotParameters = require(getSlotFilePath($slotUUID, $config)); // save file $incomingFileStream = fopen("php://input", "r"); $targetFileStream = fopen($uploadFilePath, "w"); $uploadedFilesize = stream_copy_to_stream($incomingFileStream, $targetFileStream); fclose($targetFileStream); // check actual file size with registered file size - return 413 if ($uploadedFilesize != $slotParameters['filesize']) { unlink($uploadedFilePath); sendHttpErrorCodeAndMessage(403, "Uploaded file size differs from requestes slot size."); } // check actual mime type with registered mime type if (mime_content_type($uploadFilePath) != $slotParameters['content_type']) { unlink($uploadedFilePath); sendHttpErrorCodeAndMessage(403, "Uploaded file content type differs from requestes slot content type."); } // return 500 in case of any error // return 201 for success sendHttpErrorCodeAndMessage(201); break; case 'GET': // better use really apache to serve files... break; } function getMandatoryPostParameter($parameterName) { $parameter = $_POST[$parameterName]; if (!isset($parameter) || is_null($parameter) || empty($parameter)) { sendHttpErrorCodeAndMessage(400, 'Missing parameter "'.$parameterName.'"'); } return $parameter; } function sendHttpErrorCodeAndMessage($code, $text = '') { http_response_code($code); exit($text); } function getUUIDFromUri($uri) { $pattern = "/[a-f0-9]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/"; preg_match($pattern, $uri, $matches); return $matches[0]; } function getFilenameFromUri($uri) { $lastSlash = strrpos($uri, '/'); return substr($uri, $lastSlash); } function registerSlot($slotUUID, $filename, $filesize, $contentType, $userJid, $config) { $contents = " \''.$filename.'\', \'filesize\' => \''.$filesize.'\', '; $contents .= '\'content_type\' => \''.$contentType.'\', \'user_jid\' => \''.$userJid.'\');'; if (!file_put_contents(getSlotFilePath($slotUUID, $config), $contents)) { sendHttpErrorCodeAndMessage(500, "Could not create slot registry entry."); } } function slotExists($slotUUID, $config) { return file_exists(getSlotFilePath($slotUUID, $config)); } function getSlotFilePath($slotUUID, $config) { return $config['slot_registry_dir'].$slotUUID; } function getUploadFilePath($slotUUID, $config, $filename = NULL) { $path = $config['storage_base_path'].$slotUUID; if (!is_null($filename)) { $path .= '/'.$filename; } return $path; } /** * Copied from http://rogerstringer.com/2013/11/15/generate-uuids-php/ */ function generate_uuid() { return sprintf( '%04x%04x-%04x-%04x-%04x-%04x%04x%04x', mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ), mt_rand( 0, 0x0fff ) | 0x4000, mt_rand( 0, 0x3fff ) | 0x8000, mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ) ); }