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,18 +259,17 @@ 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' ] ;
268+
270269 if ( v2 !== undefined && Number . parseInt ( v2 , 10 ) !== 2 ) {
271- return callback ( errorInstances . InvalidArgument . customizeDescription ( 'Invalid ' +
272- 'List Type specified in Request' ) ) ;
270+ throw errorInstances . InvalidArgument . customizeDescription ( 'Invalid List Type specified in Request' ) ;
273271 }
272+
274273 if ( v2 ) {
275274 log . addDefaultFields ( { action : 'ListObjectsV2' , } ) ;
276275 if ( request . serverAccessLog ) {
@@ -288,18 +287,14 @@ function bucketGet(authInfo, request, log, callback) {
288287 const encoding = params [ 'encoding-type' ] ;
289288 if ( encoding !== undefined && encoding !== 'url' ) {
290289 monitoring . promMetrics ( 'GET' , bucketName , 400 , 'listBucket' ) ;
291- return callback ( errorInstances . InvalidArgument . customizeDescription ( 'Invalid ' +
292- 'Encoding Method specified in Request' ) ) ;
290+ throw errorInstances . InvalidArgument . customizeDescription ( 'Invalid Encoding Method specified in Request' ) ;
293291 }
294292
295293 const requestMaxKeys = params [ 'max-keys' ] ? Number . parseInt ( params [ 'max-keys' ] , 10 ) : 1000 ;
296294 if ( Number . isNaN ( requestMaxKeys ) || requestMaxKeys < 0 ) {
297295 monitoring . promMetrics ( 'GET' , bucketName , 400 , 'listBucket' ) ;
298- return callback ( errors . InvalidArgument ) ;
296+ throw errors . InvalidArgument ;
299297 }
300- // AWS only returns 1000 keys even if max keys are greater.
301- // Max keys stated in response xml can be greater than actual
302- // keys returned.
303298 const actualMaxKeys = Math . min ( constants . listingHardLimit , requestMaxKeys ) ;
304299
305300 const metadataValParams = {
@@ -327,47 +322,67 @@ function bucketGet(authInfo, request, log, callback) {
327322 listParams . marker = params . marker ;
328323 }
329324
330- standardMetadataValidateBucket ( metadataValParams , request . actionImplicitDenies , log , ( err , bucket ) => {
331- const corsHeaders = collectCorsHeaders ( request . headers . origin , request . method , bucket ) ;
332- if ( err ) {
333- log . debug ( 'error processing request' , { error : err } ) ;
334- monitoring . promMetrics ( 'GET' , bucketName , err . code , 'listBucket' ) ;
335- return callback ( err , null , corsHeaders ) ;
336- }
337- if ( params . versions !== undefined ) {
338- listParams . listingType = 'DelimiterVersions' ;
339- delete listParams . marker ;
340- listParams . keyMarker = params [ 'key-marker' ] ;
341- listParams . versionIdMarker = params [ 'version-id-marker' ] ?
342- versionIdUtils . decode ( params [ 'version-id-marker' ] ) :
343- undefined ;
344- }
345- if ( ! requestMaxKeys ) {
346- const emptyList = {
347- CommonPrefixes : [ ] ,
348- Contents : [ ] ,
349- Versions : [ ] ,
350- IsTruncated : false ,
351- } ;
352- return handleResult ( listParams , requestMaxKeys , encoding , authInfo ,
353- bucketName , emptyList , corsHeaders , log , callback ) ;
354- }
355- return services . getObjectListing ( bucketName , listParams , log ,
356- ( err , list ) => {
357- if ( err ) {
358- log . debug ( 'error processing request' , { error : err } ) ;
359- monitoring . promMetrics ( 'GET' , bucketName , err . code , 'listBucket' ) ;
360- return callback ( err , null , corsHeaders ) ;
361- }
362- return handleResult ( listParams , requestMaxKeys , encoding , authInfo ,
363- bucketName , list , corsHeaders , log , callback ) ;
364- } ) ;
365- } ) ;
366- return undefined ;
325+ let error ;
326+ let bucket ;
327+
328+ try {
329+ const standardMetadataValidateBucketPromised = promisify ( standardMetadataValidateBucket ) ;
330+ bucket = await standardMetadataValidateBucketPromised ( metadataValParams , request . actionImplicitDenies , log ) ;
331+ } catch ( err ) {
332+ error = err ;
333+ }
334+
335+ const corsHeaders = collectCorsHeaders ( request . headers . origin , request . method , bucket ) ;
336+
337+ if ( error ) {
338+ log . debug ( 'error processing request' , { error } ) ;
339+ monitoring . promMetrics ( 'GET' , bucketName , error . code , 'listBucket' ) ;
340+ error . additionalResHeaders = corsHeaders ;
341+ throw error ;
342+ }
343+ if ( params . versions !== undefined ) {
344+ listParams . listingType = 'DelimiterVersions' ;
345+ delete listParams . marker ;
346+ listParams . keyMarker = params [ 'key-marker' ] ;
347+ listParams . versionIdMarker = params [ 'version-id-marker' ] ?
348+ versionIdUtils . decode ( params [ 'version-id-marker' ] ) :
349+ undefined ;
350+ }
351+ if ( ! requestMaxKeys ) {
352+ const emptyList = {
353+ CommonPrefixes : [ ] ,
354+ Contents : [ ] ,
355+ Versions : [ ] ,
356+ IsTruncated : false ,
357+ } ;
358+ const res = handleResult ( listParams , requestMaxKeys , encoding , authInfo , bucketName , emptyList , log ) ;
359+ return [ res , corsHeaders ] ;
360+ }
361+
362+ let list ;
363+ try {
364+ list = await promisify ( services . getObjectListing ) ( bucketName , listParams , log ) ;
365+ } catch ( err ) {
366+ log . debug ( 'error processing request' , { error : err } ) ;
367+ monitoring . promMetrics ( 'GET' , bucketName , err . code , 'listBucket' ) ;
368+
369+ err . additionalResHeaders = corsHeaders ;
370+ throw err ;
371+ }
372+
373+ const res = handleResult ( listParams , requestMaxKeys , encoding , authInfo , bucketName , list , log ) ;
374+ return [ res , corsHeaders ] ;
367375}
368376
369377module . exports = {
370378 processVersions,
371379 processMasterVersions,
372- bucketGet,
380+ bucketGet : ( ...args ) => {
381+ const callback = args . at ( - 1 ) ;
382+ const argsWithoutCallback = args . slice ( 0 , - 1 ) ;
383+
384+ bucketGet ( ...argsWithoutCallback )
385+ . then ( result => callback ( null , ...result ) )
386+ . catch ( err => callback ( err , null , err . additionalResHeaders ) ) ;
387+ } ,
373388} ;
0 commit comments