120 lines
3.6 KiB
JavaScript
120 lines
3.6 KiB
JavaScript
var AWS = require('../core');
|
|
var inherit = AWS.util.inherit;
|
|
|
|
/**
|
|
* @api private
|
|
*/
|
|
var expiresHeader = 'presigned-expires';
|
|
|
|
/**
|
|
* @api private
|
|
*/
|
|
function signedUrlBuilder(request) {
|
|
var expires = request.httpRequest.headers[expiresHeader];
|
|
var signerClass = request.service.getSignerClass(request);
|
|
|
|
delete request.httpRequest.headers['User-Agent'];
|
|
delete request.httpRequest.headers['X-Amz-User-Agent'];
|
|
|
|
if (signerClass === AWS.Signers.V4) {
|
|
if (expires > 604800) { // one week expiry is invalid
|
|
var message = 'Presigning does not support expiry time greater ' +
|
|
'than a week with SigV4 signing.';
|
|
throw AWS.util.error(new Error(), {
|
|
code: 'InvalidExpiryTime', message: message, retryable: false
|
|
});
|
|
}
|
|
request.httpRequest.headers[expiresHeader] = expires;
|
|
} else if (signerClass === AWS.Signers.S3) {
|
|
var now = request.service ? request.service.getSkewCorrectedDate() : AWS.util.date.getDate();
|
|
request.httpRequest.headers[expiresHeader] = parseInt(
|
|
AWS.util.date.unixTimestamp(now) + expires, 10).toString();
|
|
} else {
|
|
throw AWS.util.error(new Error(), {
|
|
message: 'Presigning only supports S3 or SigV4 signing.',
|
|
code: 'UnsupportedSigner', retryable: false
|
|
});
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @api private
|
|
*/
|
|
function signedUrlSigner(request) {
|
|
var endpoint = request.httpRequest.endpoint;
|
|
var parsedUrl = AWS.util.urlParse(request.httpRequest.path);
|
|
var queryParams = {};
|
|
|
|
if (parsedUrl.search) {
|
|
queryParams = AWS.util.queryStringParse(parsedUrl.search.substr(1));
|
|
}
|
|
|
|
var auth = request.httpRequest.headers['Authorization'].split(' ');
|
|
if (auth[0] === 'AWS') {
|
|
auth = auth[1].split(':');
|
|
queryParams['AWSAccessKeyId'] = auth[0];
|
|
queryParams['Signature'] = auth[1];
|
|
|
|
AWS.util.each(request.httpRequest.headers, function (key, value) {
|
|
if (key === expiresHeader) key = 'Expires';
|
|
if (key.indexOf('x-amz-meta-') === 0) {
|
|
// Delete existing, potentially not normalized key
|
|
delete queryParams[key];
|
|
key = key.toLowerCase();
|
|
}
|
|
queryParams[key] = value;
|
|
});
|
|
delete request.httpRequest.headers[expiresHeader];
|
|
delete queryParams['Authorization'];
|
|
delete queryParams['Host'];
|
|
} else if (auth[0] === 'AWS4-HMAC-SHA256') { // SigV4 signing
|
|
auth.shift();
|
|
var rest = auth.join(' ');
|
|
var signature = rest.match(/Signature=(.*?)(?:,|\s|\r?\n|$)/)[1];
|
|
queryParams['X-Amz-Signature'] = signature;
|
|
delete queryParams['Expires'];
|
|
}
|
|
|
|
// build URL
|
|
endpoint.pathname = parsedUrl.pathname;
|
|
endpoint.search = AWS.util.queryParamsToString(queryParams);
|
|
}
|
|
|
|
/**
|
|
* @api private
|
|
*/
|
|
AWS.Signers.Presign = inherit({
|
|
/**
|
|
* @api private
|
|
*/
|
|
sign: function sign(request, expireTime, callback) {
|
|
request.httpRequest.headers[expiresHeader] = expireTime || 3600;
|
|
request.on('build', signedUrlBuilder);
|
|
request.on('sign', signedUrlSigner);
|
|
request.removeListener('afterBuild',
|
|
AWS.EventListeners.Core.SET_CONTENT_LENGTH);
|
|
request.removeListener('afterBuild',
|
|
AWS.EventListeners.Core.COMPUTE_SHA256);
|
|
|
|
request.emit('beforePresign', [request]);
|
|
|
|
if (callback) {
|
|
request.build(function() {
|
|
if (this.response.error) callback(this.response.error);
|
|
else {
|
|
callback(null, AWS.util.urlFormat(request.httpRequest.endpoint));
|
|
}
|
|
});
|
|
} else {
|
|
request.build();
|
|
if (request.response.error) throw request.response.error;
|
|
return AWS.util.urlFormat(request.httpRequest.endpoint);
|
|
}
|
|
}
|
|
});
|
|
|
|
/**
|
|
* @api private
|
|
*/
|
|
module.exports = AWS.Signers.Presign;
|