2020-03-12 10:26:31 +00:00
|
|
|
'use strict';
|
|
|
|
|
|
|
|
var aws4 = require('aws4');
|
|
|
|
var request = require('@root/request');
|
|
|
|
var env = process.env;
|
|
|
|
|
2020-09-10 08:12:43 +00:00
|
|
|
var S3;
|
|
|
|
module.exports = S3 = {
|
2020-03-12 10:26:31 +00:00
|
|
|
// HEAD
|
2020-09-10 08:12:43 +00:00
|
|
|
head: function (
|
|
|
|
{ host, accessKeyId, secretAccessKey, region, bucket, prefix, key },
|
|
|
|
_sign
|
|
|
|
) {
|
2020-03-12 10:26:31 +00:00
|
|
|
// TODO support minio
|
|
|
|
/*
|
|
|
|
var awsHost = config.awsHost;
|
|
|
|
if (!awsHost) {
|
|
|
|
if (awsRegion) {
|
|
|
|
awsHost = awsHost || 's3.'+awsRegion+'.amazonaws.com';
|
|
|
|
} else {
|
|
|
|
// default
|
|
|
|
awsHost = 's3.amazonaws.com';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
/*
|
2020-03-17 01:58:31 +00:00
|
|
|
if (env.AWS_ACCESS_KEY || env.AWS_ACCESS_KEY_ID) {
|
|
|
|
accessKeyId = accessKeyId || env.AWS_ACCESS_KEY || env.AWS_ACCESS_KEY_ID;
|
2020-03-12 10:26:31 +00:00
|
|
|
secretAccessKey = secretAccessKey || env.AWS_SECRET_ACCESS_KEY;
|
|
|
|
bucket = bucket || env.AWS_BUCKET;
|
|
|
|
prefix = prefix || env.AWS_BUCKET_PREFIX;
|
|
|
|
region = region || env.AWS_REGION;
|
|
|
|
endpoint = endpoint || env.AWS_ENDPOINT;
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
prefix = prefix || '';
|
|
|
|
if (prefix) {
|
|
|
|
// whatever => whatever/
|
|
|
|
// whatever/ => whatever/
|
|
|
|
prefix = prefix.replace(/\/?$/, '/');
|
|
|
|
}
|
|
|
|
var signed = aws4.sign(
|
|
|
|
{
|
2020-09-18 10:27:52 +00:00
|
|
|
host: host || (bucket + '.s3.amazonaws.com'),
|
2020-03-12 10:26:31 +00:00
|
|
|
service: 's3',
|
|
|
|
region: region,
|
2020-03-14 03:40:38 +00:00
|
|
|
path: (host ? '/' + bucket : '') + '/' + prefix + key,
|
2020-03-12 10:26:31 +00:00
|
|
|
method: 'HEAD',
|
|
|
|
signQuery: true
|
|
|
|
},
|
|
|
|
{ accessKeyId: accessKeyId, secretAccessKey: secretAccessKey }
|
|
|
|
);
|
2020-03-14 03:40:38 +00:00
|
|
|
var url = 'https://' + signed.host + signed.path;
|
2020-09-10 08:12:43 +00:00
|
|
|
if ('sign' === _sign) {
|
|
|
|
return url;
|
|
|
|
}
|
2020-03-12 10:26:31 +00:00
|
|
|
|
2020-09-10 08:12:43 +00:00
|
|
|
return request({ method: 'HEAD', url }).then(function (resp) {
|
2020-03-12 10:26:31 +00:00
|
|
|
if (200 === resp.statusCode) {
|
2020-03-14 03:40:38 +00:00
|
|
|
resp.url = url;
|
2020-03-12 10:26:31 +00:00
|
|
|
return resp;
|
|
|
|
}
|
|
|
|
var err = new Error(
|
|
|
|
'expected status 200 but got ' +
|
|
|
|
resp.statusCode +
|
|
|
|
'. See err.response for more info.'
|
|
|
|
);
|
|
|
|
err.url = url;
|
|
|
|
err.response = resp;
|
|
|
|
throw err;
|
|
|
|
});
|
|
|
|
},
|
|
|
|
|
|
|
|
// GET
|
2020-09-10 08:12:43 +00:00
|
|
|
get: function (
|
|
|
|
{
|
|
|
|
host,
|
|
|
|
accessKeyId,
|
|
|
|
secretAccessKey,
|
|
|
|
region,
|
|
|
|
bucket,
|
|
|
|
prefix,
|
|
|
|
key,
|
|
|
|
json
|
|
|
|
},
|
|
|
|
_sign
|
|
|
|
) {
|
2020-03-12 10:26:31 +00:00
|
|
|
prefix = prefix || '';
|
|
|
|
if (prefix) {
|
|
|
|
prefix = prefix.replace(/\/?$/, '/');
|
|
|
|
}
|
|
|
|
var signed = aws4.sign(
|
|
|
|
{
|
2020-09-18 10:27:52 +00:00
|
|
|
host: host || (bucket + '.s3.amazonaws.com'),
|
2020-03-12 10:26:31 +00:00
|
|
|
service: 's3',
|
|
|
|
region: region,
|
2020-03-14 03:40:38 +00:00
|
|
|
path: (host ? '/' + bucket : '') + '/' + prefix + key,
|
2020-03-12 10:26:31 +00:00
|
|
|
method: 'GET',
|
|
|
|
signQuery: true
|
|
|
|
},
|
|
|
|
{ accessKeyId: accessKeyId, secretAccessKey: secretAccessKey }
|
|
|
|
);
|
2020-03-14 03:40:38 +00:00
|
|
|
var url = 'https://' + signed.host + signed.path;
|
2020-09-10 08:12:43 +00:00
|
|
|
if ('sign' === _sign) {
|
|
|
|
return url;
|
|
|
|
}
|
2020-03-12 10:26:31 +00:00
|
|
|
|
|
|
|
// stay binary by default
|
|
|
|
var encoding = null;
|
|
|
|
if (json) {
|
|
|
|
encoding = undefined;
|
|
|
|
}
|
2020-03-14 03:40:38 +00:00
|
|
|
return request({
|
|
|
|
method: 'GET',
|
|
|
|
url,
|
|
|
|
encoding: encoding,
|
|
|
|
json: json
|
2020-09-10 08:12:43 +00:00
|
|
|
}).then(function (resp) {
|
2020-03-14 03:40:38 +00:00
|
|
|
if (200 === resp.statusCode) {
|
|
|
|
resp.url = url;
|
|
|
|
return resp;
|
2020-03-12 10:26:31 +00:00
|
|
|
}
|
2020-03-14 03:40:38 +00:00
|
|
|
var err = new Error(
|
|
|
|
'expected status 200 but got ' +
|
|
|
|
resp.statusCode +
|
|
|
|
'. See err.response for more info.'
|
|
|
|
);
|
|
|
|
err.url = url;
|
|
|
|
err.response = resp;
|
|
|
|
throw err;
|
|
|
|
});
|
2020-03-12 10:26:31 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
// PUT
|
2020-09-10 08:12:43 +00:00
|
|
|
set: function (
|
|
|
|
{
|
|
|
|
host,
|
|
|
|
accessKeyId,
|
|
|
|
secretAccessKey,
|
|
|
|
region,
|
|
|
|
bucket,
|
|
|
|
prefix,
|
|
|
|
key,
|
|
|
|
body,
|
|
|
|
size
|
|
|
|
},
|
|
|
|
_sign
|
|
|
|
) {
|
2020-03-12 10:26:31 +00:00
|
|
|
prefix = prefix || '';
|
|
|
|
if (prefix) {
|
|
|
|
prefix = prefix.replace(/\/?$/, '/');
|
|
|
|
}
|
|
|
|
var signed = aws4.sign(
|
|
|
|
{
|
2020-09-18 10:27:52 +00:00
|
|
|
host: host || (bucket + '.s3.amazonaws.com'),
|
2020-03-12 10:26:31 +00:00
|
|
|
service: 's3',
|
|
|
|
region: region,
|
2020-03-14 03:40:38 +00:00
|
|
|
path: (host ? '/' + bucket : '') + '/' + prefix + key,
|
2020-03-12 10:26:31 +00:00
|
|
|
method: 'PUT',
|
|
|
|
signQuery: true
|
|
|
|
},
|
|
|
|
{ accessKeyId: accessKeyId, secretAccessKey: secretAccessKey }
|
|
|
|
);
|
2020-03-14 03:40:38 +00:00
|
|
|
var url = 'https://' + signed.host + signed.path;
|
2020-03-12 10:26:31 +00:00
|
|
|
var headers = {};
|
|
|
|
if ('undefined' !== typeof size) {
|
|
|
|
headers['Content-Length'] = size;
|
|
|
|
}
|
|
|
|
|
2020-09-10 08:12:43 +00:00
|
|
|
return request({ method: 'PUT', url, body, headers }).then(function (
|
2020-03-12 10:26:31 +00:00
|
|
|
resp
|
|
|
|
) {
|
|
|
|
if (200 === resp.statusCode) {
|
2020-03-14 03:40:38 +00:00
|
|
|
resp.url = url;
|
2020-03-12 10:26:31 +00:00
|
|
|
return resp;
|
|
|
|
}
|
|
|
|
var err = new Error(
|
|
|
|
'expected status 201 but got ' +
|
|
|
|
resp.statusCode +
|
|
|
|
'. See err.response for more info.'
|
|
|
|
);
|
|
|
|
err.url = url;
|
|
|
|
err.response = resp;
|
|
|
|
throw err;
|
|
|
|
});
|
|
|
|
},
|
|
|
|
|
|
|
|
// DELETE
|
2020-09-10 08:12:43 +00:00
|
|
|
del: function (
|
|
|
|
{ host, accessKeyId, secretAccessKey, region, bucket, prefix, key },
|
|
|
|
_sign
|
|
|
|
) {
|
2020-03-12 10:26:31 +00:00
|
|
|
prefix = prefix || '';
|
|
|
|
if (prefix) {
|
|
|
|
prefix = prefix.replace(/\/?$/, '/');
|
|
|
|
}
|
|
|
|
var signed = aws4.sign(
|
|
|
|
{
|
2020-09-18 10:27:52 +00:00
|
|
|
host: host || (bucket + '.s3.amazonaws.com'),
|
2020-03-12 10:26:31 +00:00
|
|
|
service: 's3',
|
|
|
|
region: region,
|
2020-03-14 03:40:38 +00:00
|
|
|
path: (host ? '/' + bucket : '') + '/' + prefix + key,
|
2020-03-12 10:26:31 +00:00
|
|
|
method: 'DELETE',
|
|
|
|
signQuery: true
|
|
|
|
},
|
|
|
|
{ accessKeyId: accessKeyId, secretAccessKey: secretAccessKey }
|
|
|
|
);
|
2020-03-14 03:40:38 +00:00
|
|
|
var url = 'https://' + signed.host + signed.path;
|
2020-03-12 10:26:31 +00:00
|
|
|
|
2020-09-10 08:12:43 +00:00
|
|
|
return request({ method: 'DELETE', url }).then(function (resp) {
|
2020-03-12 10:26:31 +00:00
|
|
|
if (204 === resp.statusCode) {
|
2020-03-14 03:40:38 +00:00
|
|
|
resp.url = url;
|
2020-03-12 10:26:31 +00:00
|
|
|
return resp;
|
|
|
|
}
|
|
|
|
var err = new Error(
|
|
|
|
'expected status 204 but got ' +
|
|
|
|
resp.statusCode +
|
|
|
|
'. See err.response for more info.'
|
|
|
|
);
|
|
|
|
err.url = url;
|
|
|
|
err.response = resp;
|
|
|
|
throw err;
|
|
|
|
});
|
2020-09-10 08:12:43 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
// sign-only
|
|
|
|
sign: function (opts) {
|
|
|
|
var method = opts.method;
|
|
|
|
if (!method) {
|
|
|
|
method = 'GET';
|
|
|
|
}
|
|
|
|
switch (method.toUpperCase()) {
|
|
|
|
case 'HEAD':
|
|
|
|
return S3.head(opts, 'sign');
|
|
|
|
case 'GET':
|
|
|
|
return S3.get(opts, 'sign');
|
|
|
|
case 'POST':
|
|
|
|
case 'PUT':
|
|
|
|
case 'SET':
|
|
|
|
return S3.set(opts, 'sign');
|
|
|
|
case 'DEL':
|
|
|
|
case 'DELETE':
|
|
|
|
return S3.del(opts, 'sign');
|
|
|
|
default:
|
|
|
|
throw new Error("Unknown method '" + method + "'");
|
|
|
|
}
|
2020-03-12 10:26:31 +00:00
|
|
|
}
|
|
|
|
};
|