1- const AWS = require ( 'aws-sdk' ) ;
1+ const { S3Client, HeadObjectCommand, ListObjectsV2Command } = require ( '@aws-sdk/client-s3' ) ;
2+ const { NodeHttpHandler } = require ( '@aws-sdk/node-http-handler' ) ;
3+ const { ConfiguredRetryStrategy } = require ( '@smithy/util-retry' ) ;
24const fs = require ( 'fs' ) ;
35const http = require ( 'http' ) ;
46const https = require ( 'https' ) ;
@@ -19,7 +21,6 @@ function getClient(params) {
1921 } = params ;
2022 const s3EndpointIsHttps = ( endpoint && endpoint . startsWith ( 'https:' ) ) || false ;
2123 let agent ;
22- let clientLogger ;
2324
2425 if ( s3EndpointIsHttps ) {
2526 agent = new https . Agent ( {
@@ -31,61 +32,54 @@ function getClient(params) {
3132 agent = new http . Agent ( { keepAlive : true } ) ;
3233 }
3334
34- // enable/disable sdk logs
35- if ( showClientLogsIfAvailable ) {
36- // TODO: may be use werelogs
37- clientLogger = console ;
38- }
35+ // Configure retry strategy to match original AWS SDK v2 configuration
36+ // Options specific to s3 requests - maxRetries & customBackoff
37+ // Default aws sdk retry count is 3 with an exponential delay of 2^n * 30 ms
38+ const retryStrategy = new ConfiguredRetryStrategy (
39+ defaults . AWS_SDK_REQUEST_RETRIES ,
40+ ( retryCount ) => {
41+ // retry with exponential backoff delay capped at 60s max
42+ // between retries, and a little added jitter
43+ const backoff = Math . min ( defaults . AWS_SDK_REQUEST_INITIAL_DELAY_MS
44+ * 2 ** retryCount , defaults . AWS_SDK_REQUEST_MAX_BACKOFF_LIMIT_MS )
45+ * ( 0.9 + Math . random ( ) * 0.2 ) ;
46+ // show retry errors only if client logs are enabled as this may
47+ // increase log size!
48+ if ( showClientLogsIfAvailable ) {
49+ log . error ( 'awssdk request error' , {
50+ retryCount,
51+ backoff,
52+ } ) ;
53+ }
54+ return backoff ;
55+ }
56+ ) ;
3957
40- const options = {
41- accessKeyId : accessKey ,
42- secretAccessKey : secretKey ,
43- endpoint,
44- region,
45- sslEnabled : s3EndpointIsHttps ,
46- s3ForcePathStyle : true ,
47- apiVersions : { s3 : '2006-03-01' } ,
48- signatureVersion : 'v4' ,
49- signatureCache : false ,
50- httpOptions : {
51- timeout : httpTimeout ,
52- agent,
58+ const clientConfig = {
59+ region : region ,
60+ credentials : {
61+ accessKeyId : accessKey ,
62+ secretAccessKey : secretKey ,
5363 } ,
54- logger : clientLogger ,
64+ endpoint,
65+ forcePathStyle : true ,
66+ retryStrategy,
67+ requestHandler : new NodeHttpHandler ( {
68+ httpAgent : s3EndpointIsHttps ? undefined : agent ,
69+ httpsAgent : s3EndpointIsHttps ? agent : undefined ,
70+ requestTimeout : httpTimeout || 300000 ,
71+ } ) ,
5572 } ;
5673
57- /**
58- * Options specific to s3 requests
59- * `maxRetries` & `customBackoff` are set only to s3 requests
60- * default aws sdk retry count is 3 with an exponential delay of 2^n * 30 ms
61- */
62- const s3Options = {
63- maxRetries : defaults . AWS_SDK_REQUEST_RETRIES ,
64- retryDelayOptions : {
65- customBackoff : ( retryCount , error ) => {
66- // retry with exponential backoff delay capped at 60s max
67- // between retries, and a little added jitter
68- const backoff = Math . min ( defaults . AWS_SDK_REQUEST_INITIAL_DELAY_MS
69- * 2 ** retryCount , defaults . AWS_SDK_REQUEST_MAX_BACKOFF_LIMIT_MS )
70- * ( 0.9 + Math . random ( ) * 0.2 ) ;
71- // show retry errors only if client logs are enabled as this may
72- // increase log size!
73- if ( showClientLogsIfAvailable ) {
74- log . error ( 'awssdk request error' , {
75- error,
76- retryCount,
77- backoff,
78- } ) ;
79- }
80- return backoff ;
81- } ,
82- } ,
83- } ;
74+ // Add logger if available
75+ if ( showClientLogsIfAvailable ) {
76+ clientConfig . logger = console ;
77+ }
8478
85- return new AWS . S3 ( { ... options , ... s3Options } ) ;
79+ return new S3Client ( clientConfig ) ;
8680}
8781
88- function getObjMd ( params , cb ) {
82+ async function getObjMd ( params , cb ) {
8983 const {
9084 client,
9185 bucket,
@@ -98,31 +92,29 @@ function getObjMd(params, cb) {
9892 return cb ( new Error ( errMsg ) ) ;
9993 }
10094
101- return client . headObject ( {
102- Bucket : bucket ,
103- Key : key ,
104- VersionId : versionId ,
105- } , ( err , data ) => {
106- if ( err ) {
107- return cb ( err ) ;
95+ try {
96+ const commandParams = {
97+ Bucket : bucket ,
98+ Key : key ,
99+ } ;
100+ if ( versionId ) {
101+ commandParams . VersionId = versionId ;
108102 }
109- const {
110- ContentLength,
111- LastModified,
112- VersionId,
113- Metadata,
114- } = data ;
103+
104+ const data = await client . send ( new HeadObjectCommand ( commandParams ) ) ;
115105 const resp = {
116- size : ContentLength ,
117- lastModified : LastModified ,
118- versionId : VersionId ,
119- md : Metadata ,
106+ size : data . ContentLength ,
107+ lastModified : data . LastModified ,
108+ versionId : data . VersionId ,
109+ md : data . Metadata ,
120110 } ;
121111 return cb ( null , resp ) ;
122- } ) ;
112+ } catch ( err ) {
113+ return cb ( err ) ;
114+ }
123115}
124116
125- function listObjects ( params , cb ) {
117+ async function listObjects ( params , cb ) {
126118 const {
127119 client,
128120 bucket,
@@ -140,14 +132,19 @@ function listObjects(params, cb) {
140132 return cb ( new Error ( errMsg ) ) ;
141133 }
142134
143- // TODO: support listing all versions
144- return client . listObjectsV2 ( {
145- Bucket : bucket ,
146- MaxKeys : listingLimit ,
147- Prefix : prefix ,
148- Delimiter : delimiter ,
149- ContinuationToken : nextContinuationToken ,
150- } , cb ) ;
135+ try {
136+ // TODO: support listing all versions
137+ const data = await client . send ( new ListObjectsV2Command ( {
138+ Bucket : bucket ,
139+ MaxKeys : listingLimit ,
140+ Prefix : prefix ,
141+ Delimiter : delimiter ,
142+ ContinuationToken : nextContinuationToken ,
143+ } ) ) ;
144+ return cb ( null , data ) ;
145+ } catch ( err ) {
146+ return cb ( err ) ;
147+ }
151148}
152149
153150module . exports = {
0 commit comments