Skip to content
This repository has been archived by the owner on Sep 10, 2021. It is now read-only.

Commit

Permalink
Revise upload components for improved Cloud Storage compatibility
Browse files Browse the repository at this point in the history
  • Loading branch information
Jamie Snape committed Dec 12, 2014
1 parent 71d16f2 commit 5be3cb0
Show file tree
Hide file tree
Showing 7 changed files with 243 additions and 162 deletions.
33 changes: 18 additions & 15 deletions core/controllers/components/ApisystemComponent.php
Original file line number Diff line number Diff line change
Expand Up @@ -459,6 +459,7 @@ public function uploadGeneratetoken($args)
* @param changes (Optional)
* The changes field on the affected item revision,
* e.g. for recording what has changed since the previous revision.
* @param license (Optional) The license for the revision.
* @return The item information of the item created or changed.
*
* @param array $args parameters
Expand Down Expand Up @@ -526,20 +527,19 @@ public function uploadPerform($args)
$result = $httpUploadComponent->process($args);

$filename = $result['filename'];
$filepath = $result['path'];
$filesize = $result['size'];
$filemd5 = $result['md5'];
$filePath = $result['path'];
$fileSize = (int) $result['size'];
$fileChecksum = $result['md5'];
} elseif ($mode == 'multipart') {
if (!array_key_exists('file', $args) || !array_key_exists('file', $_FILES)
) {
throw new Exception('Parameter file is not defined', MIDAS_INVALID_PARAMETER);
}
$file = $_FILES['file'];

$filename = $file['name'];
$filepath = $file['tmp_name'];
$filesize = $file['size'];
$filemd5 = '';
$filePath = $file['tmp_name'];
$fileSize = (int) $file['size'];
$fileChecksum = '';
} else {
throw new Exception('Invalid upload mode', MIDAS_INVALID_PARAMETER);
}
Expand All @@ -558,35 +558,38 @@ public function uploadPerform($args)
'CALLBACK_CORE_VALIDATE_UPLOAD',
array(
'filename' => $filename,
'size' => $filesize,
'path' => $filepath,
'size' => $fileSize,
'path' => $filePath,
'folderId' => $firstParent->getFolderId(),
)
);
foreach ($validations as $validation) {
if (!$validation['status']) {
unlink($filepath);
unlink($filePath);
throw new Exception($validation['message'], MIDAS_INVALID_POLICY);
}
}

/** @var UploadComponent $uploadComponent */
$uploadComponent = MidasLoader::loadComponent('Upload');
$license = null;
$license = array_key_exists('license', $args) ? $args['license'] : null;
$changes = array_key_exists('changes', $args) ? $args['changes'] : '';
$revisionNumber = null;
if (isset($revision) && $revision !== false) {
$revisionNumber = $revision->getRevision();
}

/** @var UploadComponent $uploadComponent */
$uploadComponent = MidasLoader::loadComponent('Upload');
$item = $uploadComponent->createNewRevision(
$userDao,
$filename,
$filepath,
$filePath,
$changes,
$item->getKey(),
$revisionNumber,
$license,
$filemd5
$fileChecksum,
false,
$fileSize
);

if (!$item) {
Expand Down
70 changes: 41 additions & 29 deletions core/controllers/components/HttpuploadComponent.php
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,11 @@ public function generateToken($args, $dirname = '')
if (!array_key_exists('filename', $args)) {
throw new Exception('Parameter filename is not defined', MIDAS_HTTPUPLOAD_FILENAME_PARAM_UNDEFINED);
}
$dir = $dirname == '' ? '' : '/'.$dirname;
$dir = $dirname === '' ? '' : '/'.$dirname;
$dir = UtilityComponent::getTempDirectory().$dir;

if (!file_exists($dir)) {
if (!mkdir($dir, 0700, true)) {
if (!mkdir($dir, 0777, true)) {
throw new Exception('Failed to create temporary upload dir', MIDAS_HTTPUPLOAD_TMP_DIR_CREATION_FAILED);
}
}
Expand All @@ -90,10 +90,16 @@ public function generateToken($args, $dirname = '')
if ($dirname != '') {
$uniqueIdentifier = $dirname.'/'.$uniqueIdentifier;
}
if (file_exists(UtilityComponent::getTempDirectory().'/'.$uniqueIdentifier)) {

$path = UtilityComponent::getTempDirectory().'/'.$uniqueIdentifier;
if (file_exists($path)) {
throw new Exception('Failed to generate upload token', MIDAS_HTTPUPLOAD_UPLOAD_TOKEN_GENERATION_FAILED);
}
touch(UtilityComponent::getTempDirectory().'/'.$uniqueIdentifier);

if (touch($path) === false) {
mkdir($path, 0777, true);
$uniqueIdentifier .= '/';
}

return array('token' => $uniqueIdentifier);
}
Expand Down Expand Up @@ -123,48 +129,54 @@ public function process($args)
if (!array_key_exists('length', $args)) {
throw new Exception('Parameter length is not defined', MIDAS_HTTPUPLOAD_PARAM_UNDEFINED);
}
$length = (float) ($args['length']);
$length = (int) ($args['length']);

if ($this->testingEnable && array_key_exists('localinput', $args)) {
$localinput = array_key_exists('localinput', $args) ? $args['localinput'] : false;
$localInput = array_key_exists('localinput', $args) ? $args['localinput'] : false;
}

// check if the temporary file exists
$pathTemporaryFilename = UtilityComponent::getTempDirectory().'/'.$uploadToken;
if (!file_exists($pathTemporaryFilename)) {
$temporaryPath = UtilityComponent::getTempDirectory().'/'.$uploadToken;
if (!file_exists($temporaryPath)) {
throw new Exception(
'Invalid upload token '.$pathTemporaryFilename, MIDAS_HTTPUPLOAD_INVALID_UPLOAD_TOKEN
'Invalid upload token '.$uploadToken, MIDAS_HTTPUPLOAD_INVALID_UPLOAD_TOKEN
);
} else {
$uploadOffset = UtilityComponent::fileSize($pathTemporaryFilename);
}

// can't do streaming checksum if we have a partial file already.
$streamChecksum = $uploadOffset == 0;
if (substr($temporaryPath, -1) === '/') {
@rmdir($temporaryPath);
}

ignore_user_abort(true);
$uploadOffset = file_exists($temporaryPath) ? UtilityComponent::fileSize($temporaryPath) : 0;

$inputfile = 'php://input'; // Stream (Client -> Server) Mode: Read, Binary
if ($this->testingEnable && array_key_exists('localinput', $args)) {
$inputfile = $localinput; // Stream (LocalServerFile -> Server) Mode: Read, Binary
}
// can't do streaming checksum if we have a partial file already.
$streamChecksum = $uploadOffset === 0;

$in = fopen($inputfile, 'rb'); // Stream (LocalServerFile -> Server) Mode: Read, Binary
if ($in === false) {
throw new Exception('Failed to open ['.$inputfile.'] source', MIDAS_HTTPUPLOAD_INPUT_FILE_OPEN_FAILED);
}
ignore_user_abort(true);

// open target output
$out = fopen($pathTemporaryFilename, 'ab'); // Stream (Server -> TempFile) Mode: Append, Binary
$out = fopen($temporaryPath, 'ab'); // Stream (Server -> TempFile) Mode: Append, Binary
if ($out === false) {
throw new Exception(
'Failed to open output file ['.$pathTemporaryFilename.']',
'Failed to open output file ['.$temporaryPath.']',
MIDAS_HTTPUPLOAD_OUTPUT_FILE_OPEN_FAILED
);
}

$inputFile = 'php://input'; // Stream (Client -> Server) Mode: Read, Binary
if ($this->testingEnable && array_key_exists('localinput', $args)) {
$inputFile = $localInput; // Stream (LocalServerFile -> Server) Mode: Read, Binary
}

$in = fopen($inputFile, 'rb'); // Stream (LocalServerFile -> Server) Mode: Read, Binary
if ($in === false) {
fclose($out);
throw new Exception('Failed to open ['.$inputFile.'] source', MIDAS_HTTPUPLOAD_INPUT_FILE_OPEN_FAILED);
}

if ($streamChecksum) {
$hashctx = hash_init('md5');
$hashContext = hash_init('md5');
} else {
$hashContext = null;
}

// read from input and write into file
Expand All @@ -177,7 +189,7 @@ public function process($args)
$bufSize = $length - $uploadOffset;
}
if ($streamChecksum) {
hash_update($hashctx, $buf);
hash_update($hashContext, $buf);
}
}
fclose($in);
Expand All @@ -191,9 +203,9 @@ public function process($args)
}

$data['filename'] = $filename;
$data['path'] = $pathTemporaryFilename;
$data['path'] = $temporaryPath;
$data['size'] = $uploadOffset;
$data['md5'] = $streamChecksum ? hash_final($hashctx) : '';
$data['md5'] = $streamChecksum ? hash_final($hashContext) : '';

return $data;
}
Expand Down
34 changes: 21 additions & 13 deletions core/controllers/components/MimeTypeComponent.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,10 @@ class MimeTypeComponent extends AppComponent
* Get mime type
*
* @param string $filename
* @param null|string $alternateName
* @return string
*/
public function getType($filename)
public function getType($filename, $alternateName = null)
{
if (function_exists('finfo_open') && file_exists($filename)) {
$fileInfo = finfo_open(FILEINFO_MIME_TYPE);
Expand All @@ -37,33 +38,40 @@ public function getType($filename)
return $mimeType;
}
}
// get base name of the filename provided by user
$filename = basename($filename);

// break file into parts separated by .
$filename = explode('.', $filename);
$mimeType = $this->privFindType($filename);

// take the last part of the file to get the file extension
$filename = $filename[count($filename) - 1];
if (($mimeType === 'application/octet-stream' || $mimeType === 'binary/octet-stream') && !is_null($alternateName)) {
$mimeType = $this->privFindType($alternateName);
}

// find mime type
return $this->privFindType($filename);
return $mimeType;
}

/**
* privFindType
*
* @param string $ext
* @param string $filename
* @return string
*/
public function privFindType($ext)
public function privFindType($filename)
{
// get base name of the filename provided by user
$filename = basename($filename);

// break file into parts separated by .
$filename = explode('.', $filename);

// take the last part of the file to get the file extension
$filename = $filename[count($filename) - 1];

// create MIME types array
$mimetypes = $this->privBuildMimeArray();
$mimeTypes = $this->privBuildMimeArray();

// return mime type for extension
if (isset($mimetypes[$ext])) {
return $mimetypes[$ext];
if (isset($mimeTypes[$filename])) {
return $mimeTypes[$filename];
// if the extension wasn't found return octet-stream
} else {
return 'application/octet-stream';
Expand Down
Loading

0 comments on commit 5be3cb0

Please sign in to comment.