From fa17f36311f3012053b0413b3618ad97cb4c9bba Mon Sep 17 00:00:00 2001 From: steckbrief Date: Sat, 20 Aug 2016 21:29:05 +0200 Subject: Feature added: delete a file previously uploaded using the httpupload --- storage-backend/.htaccess | 2 +- storage-backend/config/config.inc.php | 2 + storage-backend/index.php | 150 +++++++++++++++++++++++++++------- 3 files changed, 123 insertions(+), 31 deletions(-) diff --git a/storage-backend/.htaccess b/storage-backend/.htaccess index 6655c30..6848e98 100644 --- a/storage-backend/.htaccess +++ b/storage-backend/.htaccess @@ -1,3 +1,3 @@ RewriteEngine on -RewriteCond %{REQUEST_METHOD} =PUT +RewriteCond %{REQUEST_METHOD} !^(DELETE|PUT) RewriteRule ^(.*)$ index.php?uri=$1 [L,QSA] diff --git a/storage-backend/config/config.inc.php b/storage-backend/config/config.inc.php index bfc2c9a..9a96ad9 100644 --- a/storage-backend/config/config.inc.php +++ b/storage-backend/config/config.inc.php @@ -10,5 +10,7 @@ return [ 'max_upload_file_size' => 10 * 1024 * 1024, // Array of characters which are not allowed in filenames 'invalid_characters_in_filename' => ['/'], + // Validity time of a delete token in seconds + 'delete_token_validity' => 5 * 60, ]; ?> \ No newline at end of file diff --git a/storage-backend/index.php b/storage-backend/index.php index 8b5f2b4..62d4eb2 100644 --- a/storage-backend/index.php +++ b/storage-backend/index.php @@ -1,9 +1,9 @@ 'File is empty.', 'err_code' => 1]); - } - // check file size - return 406 (not acceptable) if file too large - if ($filesize > $config['max_upload_file_size']) { - sendHttpReturnCodeAndJson(406, ['msg' => 'File too large.', 'err_code' => 2, 'parameters' => ['max_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) { - sendHttpReturnCodeAndJson(406, ['msg' => 'Invalid character found in filename.', 'err_code' => 3, 'parameters' => ['invalid_character' => $invalidCharacter]]); - } - } - // 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))) { - sendHttpReturnCodeAndJson(500, "Could not create directory for upload."); + + switch ($slotType) { + case 'delete': + // Check if all parameters needed for an delete are present - return 400 (bad request) if a parameter is missing / empty + $fileURL = getMandatoryPostParameter('file_url'); + + $slotUUID = getUUIDFromUri($fileURL); + $filename = getFilenameFromUri($fileURL); + if (!slotExists($slotUUID, $config)) { + sendHttpReturnCodeAndJson(403, "The slot does not exist."); + } + + // generate delete token, register delete token + $deleteToken = generate_uuid(); + registerDeleteToken($slotUUID, $filename, $deleteToken, $config); + + // return 200 for success and delete url Json formatted ( ['delete'=>url] ) + $result = ['delete_token' => $deleteToken]; + break; + case 'upload': + default: + // Check if all parameters needed for an upload are present - return 400 (bad request) if a parameter is missing / empty + $filename = rawurlencode(getMandatoryPostParameter('filename')); + $filesize = getMandatoryPostParameter('size'); + $mimeType = getOptionalPostParameter('content_type'); + + // 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) { + sendHttpReturnCodeAndJson(406, ['msg' => 'Invalid character found in filename.', 'err_code' => 3, 'parameters' => ['invalid_character' => $invalidCharacter]]); + } + } + // check file size - return 406 (not acceptable) if file too small + if ($filesize <= 0) { + sendHttpReturnCodeAndJson(406, ['msg' => 'File is empty.', 'err_code' => 1]); + } + // check file size - return 406 (not acceptable) if file too large + if ($filesize > $config['max_upload_file_size']) { + sendHttpReturnCodeAndJson(406, ['msg' => 'File too large.', 'err_code' => 2, 'parameters' => ['max_file_size' => $config['max_upload_file_size']]]); + } + // generate slot uuid, register slot uuid and expected file size and expected mime type + $slotUUID = generate_uuid(); + registerSlot($slotUUID, $filename, $filesize, $mimeType, $userJid, $config); + if (!mkdir(getUploadFilePath($slotUUID, $config))) { + sendHttpReturnCodeAndJson(500, "Could not create directory for upload."); + } + // return 200 for success and get / put url Json formatted ( ['get'=>url, 'put'=>url] ) + $result = ['put' => $config['base_url_put'].$slotUUID.'/'.$filename, + 'get' => $config['base_url_get'].$slotUUID.'/'.$filename]; } - // return 200 for success and get / put url Json formatted ( ['get'=>url, 'put'=>url] ) - $result = ['put' => $config['base_url_put'].$slotUUID.'/'.$filename, - 'get' => $config['base_url_get'].$slotUUID.'/'.$filename]; + echo json_encode($result); break; case 'PUT': @@ -113,6 +159,40 @@ switch ($method) { // return 201 for success sendHttpReturnCodeAndMessage(201); break; + case 'DELETE': + // check slot uuid - return 403 if not existing + $uri = $_SERVER["REQUEST_URI"]; + $slotUUID = getUUIDFromUri($uri); + $filename = getFilenameFromUri($uri); + $deleteToken = $_SERVER["HTTP_X_FILETRANSFER_HTTP_DELETE_TOKEN"]; + if (!slotExists($slotUUID, $config)) { + sendHttpReturnCodeAndJson(403, "The slot does not exist."); + } + $slotParameters = loadSlotParameters($slotUUID, $config); + if ($deleteToken != $slotParameters['delete_token']) { + sendHttpReturnCodeAndJson(403, "The delete token is not valid."); + } + if (time() > $slotParameters['delete_token_valid_till']) { + sendHttpReturnCodeAndJson(403, "The delete token is not valid anymore."); + } + if (!checkFilenameParameter($filename, $slotParameters)) { + sendHttpReturnCodeAndJson(403, "Filename to delete differs from requested slot filename."); + } + $uploadFilePath = rawurldecode(getUploadFilePath($slotUUID, $config, $slotParameters['filename'])); + if (!file_exists($uploadFilePath)) { + sendHttpReturnCodeAndJson(404, "The file does not exist."); + } + + // Delete file + if (unlink($uploadFilePath)) { + // Clean up the server - ignore errors + @rmdir(getUploadFilePath($slotUUID, $config)); + // return 204 for success + sendHttpReturnCodeAndMessage(204); + } else { + sendHttpReturnCodeAndJson(500, "Could not delete file."); + } + break; default: sendHttpReturnCodeAndJson(403, "Access not allowed."); break; @@ -147,10 +227,10 @@ function getMandatoryPostParameter($parameterName) { return $parameter; } -function getOptionalPostParameter($parameterName) { +function getOptionalPostParameter($parameterName, $default = NULL) { $parameter = $_POST[$parameterName]; if (!isset($parameter) || is_null($parameter) || empty($parameter)) { - $parameter = NULL; + $parameter = $default; } return $parameter; } @@ -187,6 +267,16 @@ function registerSlot($slotUUID, $filename, $filesize, $contentType, $userJid, $ } } +function registerDeleteToken($slotUUID, $filename, $deleteToken, $config) { + $slotFilePath = getSlotFilePath($slotUUID, $config); + $contents = file_get_contents($slotFilePath); + $validTo = time() + $config['delete_token_validity']; + $newContents = str_replace("]", ", 'delete_token' => '".$deleteToken."', 'delete_token_valid_till' => '".$validTo."']", $contents); + if (!file_put_contents($slotFilePath, $newContents)) { + sendHttpReturnCodeAndMessage(500, "Could not update slot registry entry."); + } +} + function slotExists($slotUUID, $config) { return file_exists(getSlotFilePath($slotUUID, $config)); } -- cgit v1.2.3