@@ -10,6 +10,9 @@ const { pushMetric } = require('../utapi/utilities');
1010const versionIdUtils = versioning . VersionID ;
1111const monitoring = require ( '../utilities/monitoringHandler' ) ;
1212const { generateToken, decryptToken } = require ( '../api/apiUtils/object/continueToken' ) ;
13+ const { parseAttributesHeaders, buildAttributesXml } = require ( './apiUtils/object/objectAttributes' ) ;
14+
15+ const OPTIONAL_ATTRIBUTES = new Set ( [ 'RestoreStatus' ] ) ;
1316
1417const xmlParamsToSkipUrlEncoding = new Set ( [ 'ContinuationToken' , 'NextContinuationToken' ] ) ;
1518
@@ -150,7 +153,11 @@ function processVersions(bucketName, listParams, list) {
150153 `<ID>${ v . Owner . ID } </ID>` ,
151154 `<DisplayName>${ v . Owner . DisplayName } </DisplayName>` ,
152155 '</Owner>' ,
153- ...processOptionalAttributes ( v , listParams . optionalAttributes ) ,
156+ ) ;
157+
158+ buildAttributesXml ( v , v . userMetadata , listParams . optionalAttributes , xml ) ,
159+
160+ xml . push (
154161 `<StorageClass>${ v . StorageClass } </StorageClass>` ,
155162 v . IsDeleteMarker ? '</DeleteMarker>' : '</Version>'
156163 ) ;
@@ -231,7 +238,7 @@ function processMasterVersions(bucketName, listParams, list) {
231238 ) ;
232239 }
233240
234- xml . push ( ... processOptionalAttributes ( v , listParams . optionalAttributes ) ) ;
241+ buildAttributesXml ( v , v . userMetadata , listParams . optionalAttributes , xml ) ;
235242
236243 return xml . push (
237244 `<StorageClass>${ v . StorageClass } </StorageClass>` ,
@@ -246,41 +253,6 @@ function processMasterVersions(bucketName, listParams, list) {
246253 return xml . join ( '' ) ;
247254}
248255
249- function processOptionalAttributes ( item , optionalAttributes ) {
250- const xml = [ ] ;
251- const userMetadata = new Set ( ) ;
252-
253- for ( const attribute of optionalAttributes ) {
254- switch ( attribute ) {
255- case 'RestoreStatus' :
256- xml . push ( '<RestoreStatus>' ) ;
257- xml . push ( `<IsRestoreInProgress>${ ! ! item . restoreStatus ?. inProgress } </IsRestoreInProgress>` ) ;
258-
259- if ( item . restoreStatus ?. expiryDate ) {
260- xml . push ( `<RestoreExpiryDate>${ item . restoreStatus ?. expiryDate } </RestoreExpiryDate>` ) ;
261- }
262-
263- xml . push ( '</RestoreStatus>' ) ;
264- break ;
265- case 'x-amz-meta-*' :
266- for ( const key of Object . keys ( item . userMetadata ) ) {
267- userMetadata . add ( key ) ;
268- }
269- break ;
270- default :
271- if ( item . userMetadata ?. [ attribute ] ) {
272- userMetadata . add ( attribute ) ;
273- }
274- }
275- }
276-
277- for ( const key of userMetadata ) {
278- xml . push ( `<${ key } >${ item . userMetadata [ key ] } </${ key } >` ) ;
279- }
280-
281- return xml ;
282- }
283-
284256function handleResult ( listParams , requestMaxKeys , encoding , authInfo , bucketName , list , log ) {
285257 // eslint-disable-next-line no-param-reassign
286258 listParams . maxKeys = requestMaxKeys ;
@@ -321,15 +293,11 @@ async function bucketGet(authInfo, request, log, callback) {
321293 const bucketName = request . bucketName ;
322294 const v2 = params [ 'list-type' ] ;
323295
324- const optionalAttributes =
325- request . headers [ 'x-amz-optional-object-attributes' ]
326- ?. split ( ',' )
327- . map ( attr => attr . trim ( ) )
328- . map ( attr => attr !== 'RestoreStatus' ? attr . toLowerCase ( ) : attr )
329- ?? [ ] ;
330- if ( optionalAttributes . some ( attr => ! attr . startsWith ( 'x-amz-meta-' ) && attr != 'RestoreStatus' ) ) {
331- throw errorInstances . InvalidArgument . customizeDescription ( 'Invalid attribute name specified' ) ;
332- }
296+ const optionalAttributes = parseAttributesHeaders (
297+ request . headers ,
298+ 'x-amz-optional-object-attributes' ,
299+ OPTIONAL_ATTRIBUTES ,
300+ ) ;
333301
334302 if ( v2 !== undefined && Number . parseInt ( v2 , 10 ) !== 2 ) {
335303 throw errorInstances . InvalidArgument . customizeDescription ( 'Invalid List Type specified in Request' ) ;
0 commit comments