S3 V4 chunked upload - endpoint with bucket as directory (of the style s3.amazonaws.com/bucket.name/)
Author: d-a-sCreated Sep 9, 2017Updated Aug 8, 2018
Type of issue
- Bug report
Uploader type
- S3
Fine Uploader version
{example: 5.15.0}
Browsers where the bug is reproducible
Chrome or Firefox (presumably all browsers)
Operating systems where the bug is reproducible
(presumably all, tested on Windows 10)
All relevant Fine Uploader-related code that you have written
var getCpHeaders = function(si, key){
var i = parseInt(si);
if(i!==NaN) {
var file = uploader.getFile(i);
if(file && file.cpHeaders) {
if(typeof key==='string') return file.cpHeaders[key] ||'';
return file.cpHeaders;
}
}
return null;
};
var uploader = new qq.s3.FineUploader({
debug: true,
element: document.getElementById('fine-uploader'),
objectProperties: {
key: function (i) {
return getCpHeaders(i,'key');
},
serverSideEncryption: true
},
chunking: {
enabled: true,
concurrent: {
enabled: true
}
},
request: {
accessKey: @Html.RawSerialize(Emr.CasePacer.Data.Services.S3.AccessKey)
},
signature: {
customHeaders: function (i) {
return getCpHeaders(i);
},
endpoint: '/Record/S3Signature',
version: 4
},
uploadSuccess: {
endpoint: '/Record/S3Success'
},
iframeSupport: {
localBlankPagePath: '/success.html'
},
callbacks: {
onSubmit: function (i, name) {
var file = uploader.getFile(i);
var promise = new qq.Promise();
$.ajax({
method: 'POST',
url: '/Record/S3Initialize',
data: {
lawsuitId: $('#ActiveLawsuitId').val(),
fileName: file.name,
fileLength: file.size //, file.type
},
success: function (headers) {
if (headers && headers.key) {
file.cpHeaders = headers;
uploader.setEndpoint(headers.Endpoint, i);
promise.success();
} else promise.failure();
},
error: function () {
promise.failure();
}
});
return promise;
}
}
});Detailed explanation of the problem
If the endpoint is of the style s3.amazonaws.com/bucket.name/, the V4 signature expects the canonical header to be in the form:
PUT
/Bucket.Name/Path/To/File.txt
uploads=
host:s3.amazonaws.com
x-amz-content-sha256:...However with the current version (5.15.0) the canonical header looks like this:
PUT
/Path/To/File.txt
uploads=
host:s3.amazonaws.com/Bucket.Name
x-amz-content-sha256:...This causes the signature to be invalid. I have written a server-side workaround to fix the canonical header, but eventually it seems like it would be best to fix this in the code, at the following location possibly: https://github.com/FineUploader/fine-uploader/blob/a5137776906693b60b68f026d306ba397c75f8a9/client/js/s3/request-signer.js#L134
getCanonicalRequest: function(signatureSpec) {
return qq.format("{}\n{}\n{}\n{}\n{}\n{}",
signatureSpec.method,
v4.getCanonicalUri(signatureSpec.endOfUrl), // this should include /Bucket.Name/ at the beginning
v4.getCanonicalQueryString(signatureSpec.endOfUrl),
signatureSpec.headersStr || "\n", // if there is a host header, it should exclude the /Bucket.Name
v4.getSignedHeaders(signatureSpec.headerNames),
signatureSpec.hashedContent);
},Source: FineUploader/fine-uploader