add ability to sign() without fetch

This commit is contained in:
AJ ONeal 2020-09-10 02:12:43 -06:00
parent d26ab16475
commit 0452e68809
2 changed files with 110 additions and 54 deletions

View File

@ -2,12 +2,28 @@
> Minimalist S3 client > Minimalist S3 client
A lightweight alternative to the s3 SDK that uses @root/request and aws4. A lightweight alternative to the s3 SDK that uses only @root/request and aws4.
* set() - set()
* get() - get()
* head() - head()
* delete() - delete()
- sign()
Download a file from S3
```js
s3.get({
accessKeyId,
secretAccessKey,
region,
bucket,
prefix,
key
});
```
Upload a new file to S3
```js ```js
s3.set({ s3.set({
@ -19,7 +35,21 @@ s3.set({
key, key,
body, body,
size size
}) });
```
Return signed URL without fetching.
```js
s3.sign({
method: 'get',
accessKeyId,
secretAccessKey,
region,
bucket,
prefix,
key
});
``` ```
If the body is a stream then `size` must be set to `fs.statSync(filePath).size`, or the request will fail: If the body is a stream then `size` must be set to `fs.statSync(filePath).size`, or the request will fail:

View File

@ -4,17 +4,13 @@ var aws4 = require('aws4');
var request = require('@root/request'); var request = require('@root/request');
var env = process.env; var env = process.env;
module.exports = { var S3;
module.exports = S3 = {
// HEAD // HEAD
head: function({ head: function (
host, { host, accessKeyId, secretAccessKey, region, bucket, prefix, key },
accessKeyId, _sign
secretAccessKey, ) {
region,
bucket,
prefix,
key
}) {
// TODO support minio // TODO support minio
/* /*
var awsHost = config.awsHost; var awsHost = config.awsHost;
@ -45,7 +41,7 @@ module.exports = {
} }
var signed = aws4.sign( var signed = aws4.sign(
{ {
host: host || (bucket + '.s3.amazonaws.com'), host: host || bucket + '.s3.amazonaws.com',
service: 's3', service: 's3',
region: region, region: region,
path: (host ? '/' + bucket : '') + '/' + prefix + key, path: (host ? '/' + bucket : '') + '/' + prefix + key,
@ -55,8 +51,11 @@ module.exports = {
{ accessKeyId: accessKeyId, secretAccessKey: secretAccessKey } { accessKeyId: accessKeyId, secretAccessKey: secretAccessKey }
); );
var url = 'https://' + signed.host + signed.path; var url = 'https://' + signed.host + signed.path;
if ('sign' === _sign) {
return url;
}
return request({ method: 'HEAD', url }).then(function(resp) { return request({ method: 'HEAD', url }).then(function (resp) {
if (200 === resp.statusCode) { if (200 === resp.statusCode) {
resp.url = url; resp.url = url;
return resp; return resp;
@ -73,7 +72,8 @@ module.exports = {
}, },
// GET // GET
get: function({ get: function (
{
host, host,
accessKeyId, accessKeyId,
secretAccessKey, secretAccessKey,
@ -82,14 +82,16 @@ module.exports = {
prefix, prefix,
key, key,
json json
}) { },
_sign
) {
prefix = prefix || ''; prefix = prefix || '';
if (prefix) { if (prefix) {
prefix = prefix.replace(/\/?$/, '/'); prefix = prefix.replace(/\/?$/, '/');
} }
var signed = aws4.sign( var signed = aws4.sign(
{ {
host: host || (bucket + '.s3.amazonaws.com'), host: host || bucket + '.s3.amazonaws.com',
service: 's3', service: 's3',
region: region, region: region,
path: (host ? '/' + bucket : '') + '/' + prefix + key, path: (host ? '/' + bucket : '') + '/' + prefix + key,
@ -99,6 +101,9 @@ module.exports = {
{ accessKeyId: accessKeyId, secretAccessKey: secretAccessKey } { accessKeyId: accessKeyId, secretAccessKey: secretAccessKey }
); );
var url = 'https://' + signed.host + signed.path; var url = 'https://' + signed.host + signed.path;
if ('sign' === _sign) {
return url;
}
// stay binary by default // stay binary by default
var encoding = null; var encoding = null;
@ -110,7 +115,7 @@ module.exports = {
url, url,
encoding: encoding, encoding: encoding,
json: json json: json
}).then(function(resp) { }).then(function (resp) {
if (200 === resp.statusCode) { if (200 === resp.statusCode) {
resp.url = url; resp.url = url;
return resp; return resp;
@ -127,7 +132,8 @@ module.exports = {
}, },
// PUT // PUT
set: function({ set: function (
{
host, host,
accessKeyId, accessKeyId,
secretAccessKey, secretAccessKey,
@ -137,14 +143,16 @@ module.exports = {
key, key,
body, body,
size size
}) { },
_sign
) {
prefix = prefix || ''; prefix = prefix || '';
if (prefix) { if (prefix) {
prefix = prefix.replace(/\/?$/, '/'); prefix = prefix.replace(/\/?$/, '/');
} }
var signed = aws4.sign( var signed = aws4.sign(
{ {
host: host || (bucket + '.s3.amazonaws.com'), host: host || bucket + '.s3.amazonaws.com',
service: 's3', service: 's3',
region: region, region: region,
path: (host ? '/' + bucket : '') + '/' + prefix + key, path: (host ? '/' + bucket : '') + '/' + prefix + key,
@ -159,7 +167,7 @@ module.exports = {
headers['Content-Length'] = size; headers['Content-Length'] = size;
} }
return request({ method: 'PUT', url, body, headers }).then(function( return request({ method: 'PUT', url, body, headers }).then(function (
resp resp
) { ) {
if (200 === resp.statusCode) { if (200 === resp.statusCode) {
@ -178,22 +186,17 @@ module.exports = {
}, },
// DELETE // DELETE
del: function({ del: function (
host, { host, accessKeyId, secretAccessKey, region, bucket, prefix, key },
accessKeyId, _sign
secretAccessKey, ) {
region,
bucket,
prefix,
key
}) {
prefix = prefix || ''; prefix = prefix || '';
if (prefix) { if (prefix) {
prefix = prefix.replace(/\/?$/, '/'); prefix = prefix.replace(/\/?$/, '/');
} }
var signed = aws4.sign( var signed = aws4.sign(
{ {
host: host || (bucket + '.s3.amazonaws.com'), host: host || bucket + '.s3.amazonaws.com',
service: 's3', service: 's3',
region: region, region: region,
path: (host ? '/' + bucket : '') + '/' + prefix + key, path: (host ? '/' + bucket : '') + '/' + prefix + key,
@ -204,7 +207,7 @@ module.exports = {
); );
var url = 'https://' + signed.host + signed.path; var url = 'https://' + signed.host + signed.path;
return request({ method: 'DELETE', url }).then(function(resp) { return request({ method: 'DELETE', url }).then(function (resp) {
if (204 === resp.statusCode) { if (204 === resp.statusCode) {
resp.url = url; resp.url = url;
return resp; return resp;
@ -218,5 +221,28 @@ module.exports = {
err.response = resp; err.response = resp;
throw err; throw err;
}); });
},
// 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 + "'");
}
} }
}; };