Fatal error: Uncaught Aws \ S3 \ Exception \ InvalidRequestException: AWS Error code: InvalidRequest, status code: 400, AWS Request ID: B1A28EBE65521DF4, AWS Error type: client, AWS error message: you must specify at least one part, User- Agent: aws-sdk-php2 / 2.7.22 Guzzle / 3.9.2 curl / 7.40.0 PHP / 5.6.6 is thrown in C: \ vhosts ********. Com \ db **** * \ FileUploader_v2 \ aws \ Aws \ Common \ Exception \ NamespaceExceptionFactory.php on line 91
I get the above error whenever I run a multi-boot program using AWS S3. My program should cut part of the file into a JS script, which is then sent to a PHP script using XMLHTTPRequest. This part seems to work well. However, the problem occurs when CompleteMultipartUpload is called. From the error, I realized that my part is too small or empty.
upload.htm
var command; var file; var ownerName; var totalSize; var partSize = 2 * 1024 * 1024; // constant var sendBackData; var totalSize; var sureUploadSize = 0, probableUplaodSize = 0; var numParts; var partsLeft = [];
function _(el){ return document.getElementById(el); } function calcTotalSize(file){ var size_total = 0; for(var i = 0; i < file.length; i++){ size_total += file[i].size; } return size_total; } function uploadFile(){ file = _("file").files[0]; console.log(file); ownerName = _("name").value; totalSize = file.size; command = 'CreateMultipartUpload'; var formdata = new FormData(); formdata.append("command", command); formdata.append("filename", file.name); formdata.append("name", ownerName); var ajax = new XMLHttpRequest(); ajax.open("POST", "FileUploader.php", true); ajax.send(formdata); ajax.onreadystatechange = function() { if (ajax.readyState === 4) { sendBackData = JSON.parse(ajax.responseText); numParts = Math.ceil(totalSize / partSize); uploadPart(1); } }; } function uploadPart(partNum){ console.log("Uploading part " + partNum); console.log(sendBackData['uploadId']); command = 'UploadPart'; if (partNum > numParts) { completeMultipartUpload(); return; } var formdata = new FormData(); var start = (partNum - 1) * partSize; var end = start + partSize; if (end > totalSize) end = totalSize; var length = end - start; var curBlobPart = file.slice(start, end); //console.log(sendBackData['uploadId']); formdata.append("file[]", curBlobPart); formdata.append("command", command); formdata.append("uploadId", sendBackData['uploadId']); formdata.append("key", sendBackData['key']); formdata.append("partNumber", partNum); var ajax = new XMLHttpRequest(); ajax.open("POST", "FileUploader.php", true); ajax.addEventListener("load", completeHandler, false); ajax.addEventListener("error", errorHandler, false); ajax.addEventListener("abort", abortHandler, false); ajax.send(formdata); ajax.onreadystatechange = function() { if (ajax.readyState === 4) { uploadPart(partNum + 1); } }; } function completeMultipartUpload() { command = 'CompleteMultipartUpload'; var formdata = new FormData(); formdata.append("command", command); formdata.append("uploadId", sendBackData['uploadId']); formdata.append("key", sendBackData['key']); var ajax = new XMLHttpRequest(); ajax.open("POST", "FileUploader.php", true); ajax.addEventListener("load", completeHandler, false); ajax.addEventListener("error", errorHandler, false); ajax.addEventListener("abort", abortHandler, false); ajax.send(formdata); ajax.onreadystatechange = function() { if (ajax.readyState === 4) { alert("File uploaded successfully"); } }; } function progressHandler(event){ _("loaded_n_total").innerHTML = "Uploaded "+event.loaded+" bytes of "+event.total; var percent = (event.loaded / event.total) * 100; _("progressBar").value = Math.round(percent); _("status").innerHTML = Math.round(percent)+"% uploaded... please wait"; } function completeHandler(event){ _("status").innerHTML = event.target.responseText; _("progressBar").value = 0; } function errorHandler(event){ _("status").innerHTML = "Upload Failed"; } function abortHandler(event){ _("status").innerHTML = "Upload Aborted"; }`
FileUploader.php: `
//require 'SimpleImage.php'; //require 'gifsplit.php'; //require 'functions.php'; require 'config.php'; require 'aws/aws-autoloader.php'; use Aws\Common\Exception\MultipartUploadException; use Aws\S3\Model\MultipartUpload\UploadBuilder; use Aws\S3\S3Client; use Aws\S3\Exception\S3Exception; function sendJson($arr) { header('Content-Type: application/json'); die(json_encode($arr)); } // S3 $s3 = S3Client::factory(array( 'key' => AWS_KEY, 'secret' => AWS_SECRET_KEY )); //$part = $_POST['part']; switch ($_POST['command']) { case 'CreateMultipartUpload': $key = "other/".$_POST['name']."/".$_POST['filename']; $response = $s3->createMultipartUpload(array( 'Bucket' => TMP_IMG, 'Key' => $key )); $uploadId = $response['UploadId']; sendJson(array( 'uploadId' => $uploadId, 'key' => $key )); break; case 'UploadPart': var_dump($_FILES['file']); $result = $s3->uploadPart(array( 'Bucket' => TMP_IMG, 'Key' => $_POST['key'], 'UploadId' => $_POST['uploadId'], 'PartNumber'=> $_POST['partNumber'], 'Body' => $_FILES['file']['tmp_name'] )); break; case 'CompleteMultipartUpload': $partsModel = $s3->listParts(array( 'Bucket' => TMP_IMG, 'Key' => $_POST['key'], 'UploadId' => $_POST['uploadId'] )); $model = $s3->completeMultipartUpload(array( 'Bucket' => TMP_IMG, 'Key' => $_POST['key'], 'UploadId' => $_POST['uploadId'], 'Parts' => $partsModel['Parts'] )); sendJson(array( 'success' => true )); break; case 'AbortMultipartUpload':
Is there something that is clearly not the way I do my task. My only thought was that my part size is too small to load. If so, I have work for this with another version of my project that I was working on.