Reputation: 2584
Why does the Heroku Nodejs AWS S3 tutorial (https://devcenter.heroku.com/articles/s3-upload-node) fail when a plus '+' character is present in the signature?
Upvotes: 1
Views: 1096
Reputation: 64
I guess you need to uri encode your signature. like this:
signature = encodeURIComponent(
crypto.createHmac('sha1', AWS_SECRET_KEY)
.update(put_request)
.digest('base64')
);
this way you don't need to check if the signature contain '+'
Upvotes: 0
Reputation: 2584
Summary: Regenerate the signature until it does not contain a plus '+' character anymore:
if (signature.indexOf('+') != -1) {
setTimeout(function(){
//regenerate signature until it doesn't contain + anymore
generateSignature();
}, 400);
}
The working solution I found was suggested by @chadsaun on this forum post: http://www.uploadify.com/forum/#/discussion/comment/10777
Full heroku example code solution:
app.get('/sign_s3', function(req, res){
var object_name = req.query.s3_object_name;
var mime_type = req.query.s3_object_type;
var amz_headers = "x-amz-acl:public-read";
var signature, expires;
function generateSignature() {
var thisTime = new Date().getTime();
expires = Math.ceil((thisTime + 10000)/1000);
var put_request = "PUT\n\n" + mime_type + "\n"
+ expires + "\n" + amz_headers
+ "\n/" + S3_BUCKET + "/"
+ object_name;
signature = crypto.createHmac('sha1', AWS_SECRET_KEY)
.update(put_request)
.digest('base64');
console.log(signature);
if (signature.indexOf('+') != -1) {
setTimeout(function(){
//regenerate signature until it doesn't contain + anymore
generateSignature();
}, 400);
} else {
var url = 'https://' + S3_BUCKET + '.s3.amazonaws.com/' + object_name;
var credentials = {
signed_request: url + "?AWSAccessKeyId=" + AWS_ACCESS_KEY
+ "&Expires=" + expires + "&Signature="
+ signature,
url: url,
};
res.write(JSON.stringify(credentials));
res.end();
}
}
generateSignature();
});
Upvotes: 1