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

Commit 5be3cb0

Browse files
author
Jamie Snape
committed
Revise upload components for improved Cloud Storage compatibility
1 parent 71d16f2 commit 5be3cb0

File tree

7 files changed

+243
-162
lines changed

7 files changed

+243
-162
lines changed

core/controllers/components/ApisystemComponent.php

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -459,6 +459,7 @@ public function uploadGeneratetoken($args)
459459
* @param changes (Optional)
460460
* The changes field on the affected item revision,
461461
* e.g. for recording what has changed since the previous revision.
462+
* @param license (Optional) The license for the revision.
462463
* @return The item information of the item created or changed.
463464
*
464465
* @param array $args parameters
@@ -526,20 +527,19 @@ public function uploadPerform($args)
526527
$result = $httpUploadComponent->process($args);
527528

528529
$filename = $result['filename'];
529-
$filepath = $result['path'];
530-
$filesize = $result['size'];
531-
$filemd5 = $result['md5'];
530+
$filePath = $result['path'];
531+
$fileSize = (int) $result['size'];
532+
$fileChecksum = $result['md5'];
532533
} elseif ($mode == 'multipart') {
533534
if (!array_key_exists('file', $args) || !array_key_exists('file', $_FILES)
534535
) {
535536
throw new Exception('Parameter file is not defined', MIDAS_INVALID_PARAMETER);
536537
}
537538
$file = $_FILES['file'];
538-
539539
$filename = $file['name'];
540-
$filepath = $file['tmp_name'];
541-
$filesize = $file['size'];
542-
$filemd5 = '';
540+
$filePath = $file['tmp_name'];
541+
$fileSize = (int) $file['size'];
542+
$fileChecksum = '';
543543
} else {
544544
throw new Exception('Invalid upload mode', MIDAS_INVALID_PARAMETER);
545545
}
@@ -558,35 +558,38 @@ public function uploadPerform($args)
558558
'CALLBACK_CORE_VALIDATE_UPLOAD',
559559
array(
560560
'filename' => $filename,
561-
'size' => $filesize,
562-
'path' => $filepath,
561+
'size' => $fileSize,
562+
'path' => $filePath,
563563
'folderId' => $firstParent->getFolderId(),
564564
)
565565
);
566566
foreach ($validations as $validation) {
567567
if (!$validation['status']) {
568-
unlink($filepath);
568+
unlink($filePath);
569569
throw new Exception($validation['message'], MIDAS_INVALID_POLICY);
570570
}
571571
}
572572

573-
/** @var UploadComponent $uploadComponent */
574-
$uploadComponent = MidasLoader::loadComponent('Upload');
575-
$license = null;
573+
$license = array_key_exists('license', $args) ? $args['license'] : null;
576574
$changes = array_key_exists('changes', $args) ? $args['changes'] : '';
577575
$revisionNumber = null;
578576
if (isset($revision) && $revision !== false) {
579577
$revisionNumber = $revision->getRevision();
580578
}
579+
580+
/** @var UploadComponent $uploadComponent */
581+
$uploadComponent = MidasLoader::loadComponent('Upload');
581582
$item = $uploadComponent->createNewRevision(
582583
$userDao,
583584
$filename,
584-
$filepath,
585+
$filePath,
585586
$changes,
586587
$item->getKey(),
587588
$revisionNumber,
588589
$license,
589-
$filemd5
590+
$fileChecksum,
591+
false,
592+
$fileSize
590593
);
591594

592595
if (!$item) {

core/controllers/components/HttpuploadComponent.php

Lines changed: 41 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -76,11 +76,11 @@ public function generateToken($args, $dirname = '')
7676
if (!array_key_exists('filename', $args)) {
7777
throw new Exception('Parameter filename is not defined', MIDAS_HTTPUPLOAD_FILENAME_PARAM_UNDEFINED);
7878
}
79-
$dir = $dirname == '' ? '' : '/'.$dirname;
79+
$dir = $dirname === '' ? '' : '/'.$dirname;
8080
$dir = UtilityComponent::getTempDirectory().$dir;
8181

8282
if (!file_exists($dir)) {
83-
if (!mkdir($dir, 0700, true)) {
83+
if (!mkdir($dir, 0777, true)) {
8484
throw new Exception('Failed to create temporary upload dir', MIDAS_HTTPUPLOAD_TMP_DIR_CREATION_FAILED);
8585
}
8686
}
@@ -90,10 +90,16 @@ public function generateToken($args, $dirname = '')
9090
if ($dirname != '') {
9191
$uniqueIdentifier = $dirname.'/'.$uniqueIdentifier;
9292
}
93-
if (file_exists(UtilityComponent::getTempDirectory().'/'.$uniqueIdentifier)) {
93+
94+
$path = UtilityComponent::getTempDirectory().'/'.$uniqueIdentifier;
95+
if (file_exists($path)) {
9496
throw new Exception('Failed to generate upload token', MIDAS_HTTPUPLOAD_UPLOAD_TOKEN_GENERATION_FAILED);
9597
}
96-
touch(UtilityComponent::getTempDirectory().'/'.$uniqueIdentifier);
98+
99+
if (touch($path) === false) {
100+
mkdir($path, 0777, true);
101+
$uniqueIdentifier .= '/';
102+
}
97103

98104
return array('token' => $uniqueIdentifier);
99105
}
@@ -123,48 +129,54 @@ public function process($args)
123129
if (!array_key_exists('length', $args)) {
124130
throw new Exception('Parameter length is not defined', MIDAS_HTTPUPLOAD_PARAM_UNDEFINED);
125131
}
126-
$length = (float) ($args['length']);
132+
$length = (int) ($args['length']);
127133

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

132-
// check if the temporary file exists
133-
$pathTemporaryFilename = UtilityComponent::getTempDirectory().'/'.$uploadToken;
134-
if (!file_exists($pathTemporaryFilename)) {
138+
$temporaryPath = UtilityComponent::getTempDirectory().'/'.$uploadToken;
139+
if (!file_exists($temporaryPath)) {
135140
throw new Exception(
136-
'Invalid upload token '.$pathTemporaryFilename, MIDAS_HTTPUPLOAD_INVALID_UPLOAD_TOKEN
141+
'Invalid upload token '.$uploadToken, MIDAS_HTTPUPLOAD_INVALID_UPLOAD_TOKEN
137142
);
138-
} else {
139-
$uploadOffset = UtilityComponent::fileSize($pathTemporaryFilename);
140143
}
141144

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

145-
ignore_user_abort(true);
149+
$uploadOffset = file_exists($temporaryPath) ? UtilityComponent::fileSize($temporaryPath) : 0;
146150

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

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

157156
// open target output
158-
$out = fopen($pathTemporaryFilename, 'ab'); // Stream (Server -> TempFile) Mode: Append, Binary
157+
$out = fopen($temporaryPath, 'ab'); // Stream (Server -> TempFile) Mode: Append, Binary
159158
if ($out === false) {
160159
throw new Exception(
161-
'Failed to open output file ['.$pathTemporaryFilename.']',
160+
'Failed to open output file ['.$temporaryPath.']',
162161
MIDAS_HTTPUPLOAD_OUTPUT_FILE_OPEN_FAILED
163162
);
164163
}
165164

165+
$inputFile = 'php://input'; // Stream (Client -> Server) Mode: Read, Binary
166+
if ($this->testingEnable && array_key_exists('localinput', $args)) {
167+
$inputFile = $localInput; // Stream (LocalServerFile -> Server) Mode: Read, Binary
168+
}
169+
170+
$in = fopen($inputFile, 'rb'); // Stream (LocalServerFile -> Server) Mode: Read, Binary
171+
if ($in === false) {
172+
fclose($out);
173+
throw new Exception('Failed to open ['.$inputFile.'] source', MIDAS_HTTPUPLOAD_INPUT_FILE_OPEN_FAILED);
174+
}
175+
166176
if ($streamChecksum) {
167-
$hashctx = hash_init('md5');
177+
$hashContext = hash_init('md5');
178+
} else {
179+
$hashContext = null;
168180
}
169181

170182
// read from input and write into file
@@ -177,7 +189,7 @@ public function process($args)
177189
$bufSize = $length - $uploadOffset;
178190
}
179191
if ($streamChecksum) {
180-
hash_update($hashctx, $buf);
192+
hash_update($hashContext, $buf);
181193
}
182194
}
183195
fclose($in);
@@ -191,9 +203,9 @@ public function process($args)
191203
}
192204

193205
$data['filename'] = $filename;
194-
$data['path'] = $pathTemporaryFilename;
206+
$data['path'] = $temporaryPath;
195207
$data['size'] = $uploadOffset;
196-
$data['md5'] = $streamChecksum ? hash_final($hashctx) : '';
208+
$data['md5'] = $streamChecksum ? hash_final($hashContext) : '';
197209

198210
return $data;
199211
}

core/controllers/components/MimeTypeComponent.php

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,10 @@ class MimeTypeComponent extends AppComponent
2525
* Get mime type
2626
*
2727
* @param string $filename
28+
* @param null|string $alternateName
2829
* @return string
2930
*/
30-
public function getType($filename)
31+
public function getType($filename, $alternateName = null)
3132
{
3233
if (function_exists('finfo_open') && file_exists($filename)) {
3334
$fileInfo = finfo_open(FILEINFO_MIME_TYPE);
@@ -37,33 +38,40 @@ public function getType($filename)
3738
return $mimeType;
3839
}
3940
}
40-
// get base name of the filename provided by user
41-
$filename = basename($filename);
4241

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

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

4948
// find mime type
50-
return $this->privFindType($filename);
49+
return $mimeType;
5150
}
5251

5352
/**
5453
* privFindType
5554
*
56-
* @param string $ext
55+
* @param string $filename
5756
* @return string
5857
*/
59-
public function privFindType($ext)
58+
public function privFindType($filename)
6059
{
60+
// get base name of the filename provided by user
61+
$filename = basename($filename);
62+
63+
// break file into parts separated by .
64+
$filename = explode('.', $filename);
65+
66+
// take the last part of the file to get the file extension
67+
$filename = $filename[count($filename) - 1];
68+
6169
// create MIME types array
62-
$mimetypes = $this->privBuildMimeArray();
70+
$mimeTypes = $this->privBuildMimeArray();
6371

6472
// return mime type for extension
65-
if (isset($mimetypes[$ext])) {
66-
return $mimetypes[$ext];
73+
if (isset($mimeTypes[$filename])) {
74+
return $mimeTypes[$filename];
6775
// if the extension wasn't found return octet-stream
6876
} else {
6977
return 'application/octet-stream';

0 commit comments

Comments
 (0)