1+ const { promisify } = require ( 'util' ) ;
12const querystring = require ( 'querystring' ) ;
23const { errors, errorInstances, versioning, s3middleware } = require ( 'arsenal' ) ;
34const constants = require ( '../../constants' ) ;
@@ -236,8 +237,7 @@ function processMasterVersions(bucketName, listParams, list) {
236237 return xml . join ( '' ) ;
237238}
238239
239- function handleResult ( listParams , requestMaxKeys , encoding , authInfo ,
240- bucketName , list , corsHeaders , log , callback ) {
240+ function handleResult ( listParams , requestMaxKeys , encoding , authInfo , bucketName , list , log ) {
241241 // eslint-disable-next-line no-param-reassign
242242 listParams . maxKeys = requestMaxKeys ;
243243 // eslint-disable-next-line no-param-reassign
@@ -250,7 +250,7 @@ function handleResult(listParams, requestMaxKeys, encoding, authInfo,
250250 }
251251 pushMetric ( 'listBucket' , log , { authInfo, bucket : bucketName } ) ;
252252 monitoring . promMetrics ( 'GET' , bucketName , '200' , 'listBucket' ) ;
253- return callback ( null , res , corsHeaders ) ;
253+ return res ;
254254}
255255
256256/**
@@ -259,11 +259,9 @@ function handleResult(listParams, requestMaxKeys, encoding, authInfo,
259259 * requester's info
260260 * @param {object } request - http request object
261261 * @param {function } log - Werelogs request logger
262- * @param {function } callback - callback to respond to http request
263- * with either error code or xml response body
264- * @return {undefined }
262+ * @return {Promise<object> } - object containing xml and additionalResHeaders
265263 */
266- function bucketGet ( authInfo , request , log , callback ) {
264+ async function bucketGet ( authInfo , request , log ) {
267265 const params = request . query ;
268266 const bucketName = request . bucketName ;
269267 const v2 = params [ 'list-type' ] ;
@@ -277,9 +275,9 @@ function bucketGet(authInfo, request, log, callback) {
277275 }
278276
279277 if ( v2 !== undefined && Number . parseInt ( v2 , 10 ) !== 2 ) {
280- return callback ( errorInstances . InvalidArgument . customizeDescription ( 'Invalid ' +
281- 'List Type specified in Request' ) ) ;
278+ throw errorInstances . InvalidArgument . customizeDescription ( 'Invalid List Type specified in Request' ) ;
282279 }
280+
283281 if ( v2 ) {
284282 log . addDefaultFields ( { action : 'ListObjectsV2' , } ) ;
285283 if ( request . serverAccessLog ) {
@@ -297,18 +295,14 @@ function bucketGet(authInfo, request, log, callback) {
297295 const encoding = params [ 'encoding-type' ] ;
298296 if ( encoding !== undefined && encoding !== 'url' ) {
299297 monitoring . promMetrics ( 'GET' , bucketName , 400 , 'listBucket' ) ;
300- return callback ( errorInstances . InvalidArgument . customizeDescription ( 'Invalid ' +
301- 'Encoding Method specified in Request' ) ) ;
298+ throw errorInstances . InvalidArgument . customizeDescription ( 'Invalid Encoding Method specified in Request' ) ;
302299 }
303300
304301 const requestMaxKeys = params [ 'max-keys' ] ? Number . parseInt ( params [ 'max-keys' ] , 10 ) : 1000 ;
305302 if ( Number . isNaN ( requestMaxKeys ) || requestMaxKeys < 0 ) {
306303 monitoring . promMetrics ( 'GET' , bucketName , 400 , 'listBucket' ) ;
307- return callback ( errors . InvalidArgument ) ;
304+ throw errors . InvalidArgument ;
308305 }
309- // AWS only returns 1000 keys even if max keys are greater.
310- // Max keys stated in response xml can be greater than actual
311- // keys returned.
312306 const actualMaxKeys = Math . min ( constants . listingHardLimit , requestMaxKeys ) ;
313307
314308 const metadataValParams = {
@@ -336,51 +330,67 @@ function bucketGet(authInfo, request, log, callback) {
336330 listParams . marker = params . marker ;
337331 }
338332
339- standardMetadataValidateBucket ( metadataValParams , request . actionImplicitDenies , log , ( err , bucket ) => {
340- const corsHeaders = collectCorsHeaders ( request . headers . origin , request . method , bucket ) ;
333+ let error ;
334+ let bucket ;
341335
342- if ( err ) {
343- log . debug ( 'error processing request' , { error : err } ) ;
344- monitoring . promMetrics ( 'GET' , bucketName , err . code , 'listBucket' ) ;
345- return callback ( err , null , corsHeaders ) ;
346- }
336+ try {
337+ const standardMetadataValidateBucketPromised = promisify ( standardMetadataValidateBucket ) ;
338+ bucket = await standardMetadataValidateBucketPromised ( metadataValParams , request . actionImplicitDenies , log ) ;
339+ } catch ( err ) {
340+ error = err ;
341+ }
347342
348- if ( params . versions !== undefined ) {
349- listParams . listingType = 'DelimiterVersions' ;
350- delete listParams . marker ;
351- listParams . keyMarker = params [ 'key-marker' ] ;
352- listParams . versionIdMarker = params [ 'version-id-marker' ] ?
353- versionIdUtils . decode ( params [ 'version-id-marker' ] ) :
354- undefined ;
355- }
343+ const corsHeaders = collectCorsHeaders ( request . headers . origin , request . method , bucket ) ;
356344
357- if ( ! requestMaxKeys ) {
358- const emptyList = {
359- CommonPrefixes : [ ] ,
360- Contents : [ ] ,
361- Versions : [ ] ,
362- IsTruncated : false ,
363- } ;
364- return handleResult ( listParams , requestMaxKeys , encoding , authInfo ,
365- bucketName , emptyList , corsHeaders , log , callback ) ;
366- }
345+ if ( error ) {
346+ log . debug ( 'error processing request' , { error } ) ;
347+ monitoring . promMetrics ( 'GET' , bucketName , error . code , 'listBucket' ) ;
348+ error . additionalResHeaders = corsHeaders ;
349+ throw error ;
350+ }
351+ if ( params . versions !== undefined ) {
352+ listParams . listingType = 'DelimiterVersions' ;
353+ delete listParams . marker ;
354+ listParams . keyMarker = params [ 'key-marker' ] ;
355+ listParams . versionIdMarker = params [ 'version-id-marker' ] ?
356+ versionIdUtils . decode ( params [ 'version-id-marker' ] ) :
357+ undefined ;
358+ }
359+ if ( ! requestMaxKeys ) {
360+ const emptyList = {
361+ CommonPrefixes : [ ] ,
362+ Contents : [ ] ,
363+ Versions : [ ] ,
364+ IsTruncated : false ,
365+ } ;
366+ const res = handleResult ( listParams , requestMaxKeys , encoding , authInfo , bucketName , emptyList , log ) ;
367+ return [ res , corsHeaders ] ;
368+ }
367369
368- return services . getObjectListing ( bucketName , listParams , log , ( err , list ) => {
369- if ( err ) {
370- log . debug ( 'error processing request' , { error : err } ) ;
371- monitoring . promMetrics ( 'GET' , bucketName , err . code , 'listBucket' ) ;
372- return callback ( err , null , corsHeaders ) ;
373- }
370+ let list ;
371+ try {
372+ list = await promisify ( services . getObjectListing ) ( bucketName , listParams , log ) ;
373+ } catch ( err ) {
374+ log . debug ( 'error processing request' , { error : err } ) ;
375+ monitoring . promMetrics ( 'GET' , bucketName , err . code , 'listBucket' ) ;
374376
375- return handleResult ( listParams , requestMaxKeys , encoding , authInfo ,
376- bucketName , list , corsHeaders , log , callback ) ;
377- } ) ;
378- } ) ;
379- return undefined ;
377+ err . additionalResHeaders = corsHeaders ;
378+ throw err ;
379+ }
380+
381+ const res = handleResult ( listParams , requestMaxKeys , encoding , authInfo , bucketName , list , log ) ;
382+ return [ res , corsHeaders ] ;
380383}
381384
382385module . exports = {
383386 processVersions,
384387 processMasterVersions,
385- bucketGet,
388+ bucketGet : ( ...args ) => {
389+ const callback = args . at ( - 1 ) ;
390+ const argsWithoutCallback = args . slice ( 0 , - 1 ) ;
391+
392+ bucketGet ( ...argsWithoutCallback )
393+ . then ( result => callback ( null , ...result ) )
394+ . catch ( err => callback ( err , null , err . additionalResHeaders ) ) ;
395+ } ,
386396} ;
0 commit comments