diff options
author | steckbrief <steckbrief@chefmail.de> | 2016-08-20 21:29:05 +0200 |
---|---|---|
committer | steckbrief <steckbrief@chefmail.de> | 2016-08-20 21:29:05 +0200 |
commit | fa17f36311f3012053b0413b3618ad97cb4c9bba (patch) | |
tree | 2753c68af4bdb60978ce145e8eb640b02becec88 /storage-backend | |
parent | 31da8eb9ef38af5c9cc05c76342a34fa2fb8b97c (diff) |
Feature added: delete a file previously uploaded using the httpupload
Diffstat (limited to 'storage-backend')
-rw-r--r-- | storage-backend/.htaccess | 2 | ||||
-rw-r--r-- | storage-backend/config/config.inc.php | 2 | ||||
-rw-r--r-- | 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 @@ <?php /* * This script serves as storing backend for the xmpp extension - * XEP-0313 Http Upload + * XEP-0363 Http Upload and for the extension to delete a file previously uploaded via HTTP upload * - * The following return codes are used for requesting a slot: + * The following return codes are used for requesting an upload slot (parameter 'slot_type' = 'upload' or empty): * 200: Success - response body contains PUT URL, GET URL formatted in Json * 400: In case a mandatory parameter is not set. (error code: 4, parameters: missing_parameter). Mandatory parameters are: * xmpp_server_key @@ -20,6 +20,18 @@ * Upload directory for slot cannot be created * Slot registry file cannot be created * + * The following return codes are used for requesting an delete slot (parameter 'slot_type' = 'delete'): + * 200: Success - response body contains delete_token formatted in Json + * 400: In case a mandatory parameter is not set. (error code: 4, parameters: missing_parameter). Mandatory parameters are: + * xmpp_server_key + * file_url + * user_jid + * 403: In case the XMPP Server Key is not valid + * 406: + * Invalid character found in filename (error code: 3, parameters: invalid_character) + * 500: Any other server error + * Slot registry file cannot be updated with delete token and token validity time + * The following return codes are used for uploading a file: * 201: Success - File Created * 403: If a slot is already used or file upload contains other data than in the request slot. @@ -27,6 +39,14 @@ * The slot does not exist * File size differs from slot request * Mime Type differs from slot request + * + * The following return codes are used for deleting a file: + * 204: Success - No Content + * 403: If a slot does not exist or a slot is not marked for deletion. + * The slot does not exist + * The slot does not contain a delete token + * The slot's delete token does not match the header field "X-FILETRANSFER-HTTP-DELETE-TOKEN" + * The slot's delete token is not valid any more */ $method = $_SERVER['REQUEST_METHOD']; @@ -44,38 +64,64 @@ switch ($method) { // parse post parameters // check if all parameters are present - return 400 (bad request) if a parameter is missing / empty $xmppServerKey = getMandatoryPostParameter('xmpp_server_key'); - $filename = rawurlencode(getMandatoryPostParameter('filename')); - $filesize = getMandatoryPostParameter('size'); - $type = getOptionalPostParameter('content_type'); $userJid = getMandatoryPostParameter('user_jid'); + $slotType = getOptionalPostParameter('slot_type', 'upload'); + // Check if xmppServerKey is allowed to request slots if (false === checkXmppServerKey($config['valid_xmpp_server_keys'], $xmppServerKey)) { sendHttpReturnCodeAndJson(403, 'Server is not allowed to request an upload slot'); } - // 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']]]); - } - // 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)); } |