-
Notifications
You must be signed in to change notification settings - Fork 59
Feat-large-file-s3 #17
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
b772000
e646ef3
a706dc4
1281644
332718f
6c4ddb1
3abac59
938aff2
86d6038
ce0edb1
7445353
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -137,4 +137,49 @@ public function testPartitionTotalSpace() | |
| { | ||
| $this->assertEquals(-1, $this->object->getPartitionTotalSpace()); | ||
| } | ||
|
|
||
| public function testPartUpload() { | ||
| $source = __DIR__ . "/../../resources/disk-a/large_file.mp4"; | ||
| $dest = $this->object->getPath('uploaded.mp4'); | ||
| $totalSize = \filesize($source); | ||
| // AWS S3 requires each part to be at least 5MB except for last part | ||
| $chunkSize = 5*1024*1024; | ||
|
|
||
| $chunks = ceil($totalSize / $chunkSize); | ||
|
|
||
| $chunk = 1; | ||
| $start = 0; | ||
|
|
||
| $metadata = [ | ||
| 'parts' => [], | ||
| 'chunks' => 0, | ||
| 'uploadId' => null, | ||
| 'content_type' => \mime_content_type($source), | ||
| ]; | ||
| $handle = @fopen($source, "rb"); | ||
| while ($start < $totalSize) { | ||
| $contents = fread($handle, $chunkSize); | ||
| $op = __DIR__ . '/chunk.part'; | ||
| $cc = fopen($op, 'wb'); | ||
| fwrite($cc, $contents); | ||
| fclose($cc); | ||
| $etag = $this->object->upload($op, $dest, $chunk, $chunks, $metadata); | ||
| $parts[] = ['partNumber' => $chunk, 'etag' => $etag]; | ||
| $start += strlen($contents); | ||
| $chunk++; | ||
| fseek($handle, $start); | ||
| } | ||
| @fclose($handle); | ||
| unlink($op); | ||
|
|
||
| $this->assertEquals(\filesize($source), $this->object->getFileSize($dest)); | ||
|
|
||
| // S3 doesnt provide a method to get a proper MD5-hash of a file created using multipart upload | ||
| // https://stackoverflow.com/questions/8618218/amazon-s3-checksum | ||
| // More info on how AWS calculates ETag for multipart upload here | ||
| // https://savjee.be/2015/10/Verifying-Amazon-S3-multi-part-uploads-with-ETag-hash/ | ||
| // TODO | ||
| // $this->assertEquals(\md5_file($source), $this->object->getFileHash($dest)); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we address this TODO before merging?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think we can, and may be we don't need to. For every chunk upload we are passing the md5 for the chunk, which is validated otherwise the part upload fails. And if all parts are uploaded correctly we can validate that, the overall data is uploaded correctly right? Also, don't know how to address this, AWS calculates MD5 differently for multipart upload, hashes the hash of individual parts or something. So the original file hash will not match. If you have an idea do share. |
||
| $this->object->delete($dest); | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this the intended string value for the
rangeheader?['range' => 'bytes=$offset-$end']There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it is. If reading a chunk the range will provide which part of the file was read.