123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175 |
- var AWS = require('../core');
- var inherit = AWS.util.inherit;
- /**
- * @api private
- */
- AWS.Signers.S3 = inherit(AWS.Signers.RequestSigner, {
- /**
- * When building the stringToSign, these sub resource params should be
- * part of the canonical resource string with their NON-decoded values
- */
- subResources: {
- 'acl': 1,
- 'accelerate': 1,
- 'analytics': 1,
- 'cors': 1,
- 'lifecycle': 1,
- 'delete': 1,
- 'inventory': 1,
- 'location': 1,
- 'logging': 1,
- 'metrics': 1,
- 'notification': 1,
- 'partNumber': 1,
- 'policy': 1,
- 'requestPayment': 1,
- 'replication': 1,
- 'restore': 1,
- 'tagging': 1,
- 'torrent': 1,
- 'uploadId': 1,
- 'uploads': 1,
- 'versionId': 1,
- 'versioning': 1,
- 'versions': 1,
- 'website': 1
- },
- // when building the stringToSign, these querystring params should be
- // part of the canonical resource string with their NON-encoded values
- responseHeaders: {
- 'response-content-type': 1,
- 'response-content-language': 1,
- 'response-expires': 1,
- 'response-cache-control': 1,
- 'response-content-disposition': 1,
- 'response-content-encoding': 1
- },
- addAuthorization: function addAuthorization(credentials, date) {
- if (!this.request.headers['presigned-expires']) {
- this.request.headers['X-Amz-Date'] = AWS.util.date.rfc822(date);
- }
- if (credentials.sessionToken) {
- // presigned URLs require this header to be lowercased
- this.request.headers['x-amz-security-token'] = credentials.sessionToken;
- }
- var signature = this.sign(credentials.secretAccessKey, this.stringToSign());
- var auth = 'AWS ' + credentials.accessKeyId + ':' + signature;
- this.request.headers['Authorization'] = auth;
- },
- stringToSign: function stringToSign() {
- var r = this.request;
- var parts = [];
- parts.push(r.method);
- parts.push(r.headers['Content-MD5'] || '');
- parts.push(r.headers['Content-Type'] || '');
- // This is the "Date" header, but we use X-Amz-Date.
- // The S3 signing mechanism requires us to pass an empty
- // string for this Date header regardless.
- parts.push(r.headers['presigned-expires'] || '');
- var headers = this.canonicalizedAmzHeaders();
- if (headers) parts.push(headers);
- parts.push(this.canonicalizedResource());
- return parts.join('\n');
- },
- canonicalizedAmzHeaders: function canonicalizedAmzHeaders() {
- var amzHeaders = [];
- AWS.util.each(this.request.headers, function (name) {
- if (name.match(/^x-amz-/i))
- amzHeaders.push(name);
- });
- amzHeaders.sort(function (a, b) {
- return a.toLowerCase() < b.toLowerCase() ? -1 : 1;
- });
- var parts = [];
- AWS.util.arrayEach.call(this, amzHeaders, function (name) {
- parts.push(name.toLowerCase() + ':' + String(this.request.headers[name]));
- });
- return parts.join('\n');
- },
- canonicalizedResource: function canonicalizedResource() {
- var r = this.request;
- var parts = r.path.split('?');
- var path = parts[0];
- var querystring = parts[1];
- var resource = '';
- if (r.virtualHostedBucket)
- resource += '/' + r.virtualHostedBucket;
- resource += path;
- if (querystring) {
- // collect a list of sub resources and query params that need to be signed
- var resources = [];
- AWS.util.arrayEach.call(this, querystring.split('&'), function (param) {
- var name = param.split('=')[0];
- var value = param.split('=')[1];
- if (this.subResources[name] || this.responseHeaders[name]) {
- var subresource = { name: name };
- if (value !== undefined) {
- if (this.subResources[name]) {
- subresource.value = value;
- } else {
- subresource.value = decodeURIComponent(value);
- }
- }
- resources.push(subresource);
- }
- });
- resources.sort(function (a, b) { return a.name < b.name ? -1 : 1; });
- if (resources.length) {
- querystring = [];
- AWS.util.arrayEach(resources, function (res) {
- if (res.value === undefined) {
- querystring.push(res.name);
- } else {
- querystring.push(res.name + '=' + res.value);
- }
- });
- resource += '?' + querystring.join('&');
- }
- }
- return resource;
- },
- sign: function sign(secret, string) {
- return AWS.util.crypto.hmac(secret, string, 'base64', 'sha1');
- }
- });
- /**
- * @api private
- */
- module.exports = AWS.Signers.S3;
|