1+ const { promisify } = require ( 'util' ) ;
12const querystring = require ( 'querystring' ) ;
23const { errors, errorInstances, versioning, s3middleware } = require ( 'arsenal' ) ;
34const constants = require ( '../../constants' ) ;
@@ -280,8 +281,7 @@ function processOptionalAttributes(item, optionalAttributes) {
280281 return xml ;
281282}
282283
283- function handleResult ( listParams , requestMaxKeys , encoding , authInfo ,
284- bucketName , list , corsHeaders , log , callback ) {
284+ function handleResult ( listParams , requestMaxKeys , encoding , authInfo , bucketName , list , log ) {
285285 // eslint-disable-next-line no-param-reassign
286286 listParams . maxKeys = requestMaxKeys ;
287287 // eslint-disable-next-line no-param-reassign
@@ -297,7 +297,7 @@ function handleResult(listParams, requestMaxKeys, encoding, authInfo,
297297 pushMetric ( 'listBucket' , log , { authInfo, bucket : bucketName } ) ;
298298 monitoring . promMetrics ( 'GET' , bucketName , '200' , 'listBucket' ) ;
299299
300- return callback ( null , res , corsHeaders ) ;
300+ return res ;
301301}
302302
303303/**
@@ -306,11 +306,17 @@ function handleResult(listParams, requestMaxKeys, encoding, authInfo,
306306 * requester's info
307307 * @param {object } request - http request object
308308 * @param {function } log - Werelogs request logger
309- * @param {function } callback - callback to respond to http request
310- * with either error code or xml response body
311- * @return { undefined }
309+ * @param {function } callback - callback optional to keep backward compatibility
310+ * @return { Promise<object> } - object containing xml and additionalResHeaders
311+ * @throws { Error }
312312 */
313- function bucketGet ( authInfo , request , log , callback ) {
313+ async function bucketGet ( authInfo , request , log , callback ) {
314+ if ( callback ) {
315+ return bucketGet ( authInfo , request , log )
316+ . then ( result => callback ( null , ...result ) )
317+ . catch ( err => callback ( err , null , err . additionalResHeaders ) ) ;
318+ }
319+
314320 const params = request . query ;
315321 const bucketName = request . bucketName ;
316322 const v2 = params [ 'list-type' ] ;
@@ -322,15 +328,13 @@ function bucketGet(authInfo, request, log, callback) {
322328 . map ( attr => attr !== 'RestoreStatus' ? attr . toLowerCase ( ) : attr )
323329 ?? [ ] ;
324330 if ( optionalAttributes . some ( attr => ! attr . startsWith ( 'x-amz-meta-' ) && attr != 'RestoreStatus' ) ) {
325- return callback (
326- errorInstances . InvalidArgument . customizeDescription ( 'Invalid attribute name specified' )
327- ) ;
331+ throw errorInstances . InvalidArgument . customizeDescription ( 'Invalid attribute name specified' ) ;
328332 }
329333
330334 if ( v2 !== undefined && Number . parseInt ( v2 , 10 ) !== 2 ) {
331- return callback ( errorInstances . InvalidArgument . customizeDescription ( 'Invalid ' +
332- 'List Type specified in Request' ) ) ;
335+ throw errorInstances . InvalidArgument . customizeDescription ( 'Invalid List Type specified in Request' ) ;
333336 }
337+
334338 if ( v2 ) {
335339 log . addDefaultFields ( { action : 'ListObjectsV2' } ) ;
336340 if ( request . serverAccessLog ) {
@@ -348,18 +352,14 @@ function bucketGet(authInfo, request, log, callback) {
348352 const encoding = params [ 'encoding-type' ] ;
349353 if ( encoding !== undefined && encoding !== 'url' ) {
350354 monitoring . promMetrics ( 'GET' , bucketName , 400 , 'listBucket' ) ;
351- return callback ( errorInstances . InvalidArgument . customizeDescription ( 'Invalid ' +
352- 'Encoding Method specified in Request' ) ) ;
355+ throw errorInstances . InvalidArgument . customizeDescription ( 'Invalid Encoding Method specified in Request' ) ;
353356 }
354357
355358 const requestMaxKeys = params [ 'max-keys' ] ? Number . parseInt ( params [ 'max-keys' ] , 10 ) : 1000 ;
356359 if ( Number . isNaN ( requestMaxKeys ) || requestMaxKeys < 0 ) {
357360 monitoring . promMetrics ( 'GET' , bucketName , 400 , 'listBucket' ) ;
358- return callback ( errors . InvalidArgument ) ;
361+ throw errors . InvalidArgument ;
359362 }
360- // AWS only returns 1000 keys even if max keys are greater.
361- // Max keys stated in response xml can be greater than actual
362- // keys returned.
363363 const actualMaxKeys = Math . min ( constants . listingHardLimit , requestMaxKeys ) ;
364364
365365 const metadataValParams = {
@@ -388,47 +388,51 @@ function bucketGet(authInfo, request, log, callback) {
388388 listParams . marker = params . marker ;
389389 }
390390
391- standardMetadataValidateBucket ( metadataValParams , request . actionImplicitDenies , log , ( err , bucket ) => {
392- const corsHeaders = collectCorsHeaders ( request . headers . origin , request . method , bucket ) ;
391+ let bucket ;
393392
394- if ( err ) {
395- log . debug ( 'error processing request' , { error : err } ) ;
396- monitoring . promMetrics ( 'GET' , bucketName , err . code , 'listBucket' ) ;
397- return callback ( err , null , corsHeaders ) ;
398- }
393+ try {
394+ const standardMetadataValidateBucketPromised = promisify ( standardMetadataValidateBucket ) ;
395+ bucket = await standardMetadataValidateBucketPromised ( metadataValParams , request . actionImplicitDenies , log ) ;
396+ } catch ( err ) {
397+ log . debug ( 'error processing request' , { err } ) ;
398+ monitoring . promMetrics ( 'GET' , bucketName , err . code , 'listBucket' ) ;
399+ throw err ;
400+ }
399401
400- if ( params . versions !== undefined ) {
401- listParams . listingType = 'DelimiterVersions' ;
402- delete listParams . marker ;
403- listParams . keyMarker = params [ 'key-marker' ] ;
404- listParams . versionIdMarker = params [ 'version-id-marker' ] ?
405- versionIdUtils . decode ( params [ 'version-id-marker' ] ) :
406- undefined ;
407- }
402+ const corsHeaders = collectCorsHeaders ( request . headers . origin , request . method , bucket ) ;
408403
409- if ( ! requestMaxKeys ) {
410- const emptyList = {
411- CommonPrefixes : [ ] ,
412- Contents : [ ] ,
413- Versions : [ ] ,
414- IsTruncated : false ,
415- } ;
416- return handleResult ( listParams , requestMaxKeys , encoding , authInfo ,
417- bucketName , emptyList , corsHeaders , log , callback ) ;
418- }
404+ if ( params . versions !== undefined ) {
405+ listParams . listingType = 'DelimiterVersions' ;
406+ delete listParams . marker ;
407+ listParams . keyMarker = params [ 'key-marker' ] ;
408+ listParams . versionIdMarker = params [ 'version-id-marker' ] ?
409+ versionIdUtils . decode ( params [ 'version-id-marker' ] ) :
410+ undefined ;
411+ }
412+ if ( ! requestMaxKeys ) {
413+ const emptyList = {
414+ CommonPrefixes : [ ] ,
415+ Contents : [ ] ,
416+ Versions : [ ] ,
417+ IsTruncated : false ,
418+ } ;
419+ const res = handleResult ( listParams , requestMaxKeys , encoding , authInfo , bucketName , emptyList , log ) ;
420+ return [ res , corsHeaders ] ;
421+ }
419422
420- return services . getObjectListing ( bucketName , listParams , log , ( err , list ) => {
421- if ( err ) {
422- log . debug ( 'error processing request' , { error : err } ) ;
423- monitoring . promMetrics ( 'GET' , bucketName , err . code , 'listBucket' ) ;
424- return callback ( err , null , corsHeaders ) ;
425- }
423+ let list ;
424+ try {
425+ list = await promisify ( services . getObjectListing ) ( bucketName , listParams , log ) ;
426+ } catch ( err ) {
427+ log . debug ( 'error processing request' , { error : err } ) ;
428+ monitoring . promMetrics ( 'GET' , bucketName , err . code , 'listBucket' ) ;
426429
427- return handleResult ( listParams , requestMaxKeys , encoding , authInfo ,
428- bucketName , list , corsHeaders , log , callback ) ;
429- } ) ;
430- } ) ;
431- return undefined ;
430+ err . additionalResHeaders = corsHeaders ;
431+ throw err ;
432+ }
433+
434+ const res = handleResult ( listParams , requestMaxKeys , encoding , authInfo , bucketName , list , log ) ;
435+ return [ res , corsHeaders ] ;
432436}
433437
434438module . exports = {
0 commit comments