diff --git a/lib/api/bucketGet.js b/lib/api/bucketGet.js
index 767437b992..8cfd95aa76 100644
--- a/lib/api/bucketGet.js
+++ b/lib/api/bucketGet.js
@@ -138,6 +138,7 @@ function processVersions(bucketName, listParams, list) {
const objectKey = escapeXmlFn(item.key);
const isLatest = lastKey !== objectKey;
lastKey = objectKey;
+
xml.push(
v.IsDeleteMarker ? '' : '',
`${objectKey}`,
@@ -153,14 +154,17 @@ function processVersions(bucketName, listParams, list) {
`${v.Owner.ID}`,
`${v.Owner.DisplayName}`,
'',
+ ...processOptionalAttributes(v, listParams.optionalAttributes),
`${v.StorageClass}`,
v.IsDeleteMarker ? '' : ''
);
});
+
list.CommonPrefixes.forEach(item => {
const val = escapeXmlFn(item);
xml.push(`${val}`);
});
+
xml.push('');
return xml.join('');
}
@@ -224,6 +228,7 @@ function processMasterVersions(bucketName, listParams, list) {
if (v.isDeleteMarker) {
return null;
}
+
const objectKey = escapeXmlFn(item.key);
xml.push(
'',
@@ -232,6 +237,7 @@ function processMasterVersions(bucketName, listParams, list) {
`"${v.ETag}"`,
`${v.Size}`
);
+
if (!listParams.v2 || listParams.fetchOwner) {
xml.push(
'',
@@ -240,6 +246,9 @@ function processMasterVersions(bucketName, listParams, list) {
''
);
}
+
+ xml.push(...processOptionalAttributes(v, listParams.optionalAttributes));
+
return xml.push(
`${v.StorageClass}`,
''
@@ -253,20 +262,48 @@ function processMasterVersions(bucketName, listParams, list) {
return xml.join('');
}
+function processOptionalAttributes(item, optionalAttributes) {
+ const xml = [];
+
+ for (const key of Object.keys(item)) {
+ if (key.startsWith('x-amz-meta-')) {
+ if (optionalAttributes.includes('x-amz-meta-*') || optionalAttributes.includes(key)) {
+ xml.push(`<${key}>${item[key]}${key}>`);
+ }
+ }
+ }
+
+ if (optionalAttributes.includes('RestoreStatus')) {
+ xml.push('');
+ xml.push(`${!!item.restoreStatus?.inProgress}`);
+
+ if (item.restoreStatus?.expiryDate) {
+ xml.push(`${item.restoreStatus?.expiryDate}`);
+ }
+
+ xml.push('');
+ }
+
+ return xml;
+}
+
function handleResult(listParams, requestMaxKeys, encoding, authInfo,
bucketName, list, corsHeaders, log, callback) {
// eslint-disable-next-line no-param-reassign
listParams.maxKeys = requestMaxKeys;
// eslint-disable-next-line no-param-reassign
listParams.encoding = encoding;
+
let res;
if (listParams.listingType === 'DelimiterVersions') {
res = processVersions(bucketName, listParams, list);
} else {
res = processMasterVersions(bucketName, listParams, list);
}
+
pushMetric('listBucket', log, { authInfo, bucket: bucketName });
monitoring.promMetrics('GET', bucketName, '200', 'listBucket');
+
return callback(null, res, corsHeaders);
}
@@ -344,6 +381,7 @@ function bucketGet(authInfo, request, log, callback) {
listingType: 'DelimiterMaster',
maxKeys: actualMaxKeys,
prefix: params.prefix,
+ optionalAttributes,
};
if (params.delimiter) {
diff --git a/lib/api/metadataSearch.js b/lib/api/metadataSearch.js
index 959068eee0..900b0cceef 100644
--- a/lib/api/metadataSearch.js
+++ b/lib/api/metadataSearch.js
@@ -19,6 +19,8 @@ function handleResult(listParams, requestMaxKeys, encoding, authInfo,
listParams.maxKeys = requestMaxKeys;
// eslint-disable-next-line no-param-reassign
listParams.encoding = encoding;
+ // eslint-disable-next-line no-param-reassign
+ listParams.optionalAttributes = [];
let res;
if (listParams.listingType === 'DelimiterVersions') {
res = processVersions(bucketName, listParams, list);
diff --git a/lib/routes/veeam/list.js b/lib/routes/veeam/list.js
index 1fcb2e0158..5fd8585bfb 100644
--- a/lib/routes/veeam/list.js
+++ b/lib/routes/veeam/list.js
@@ -25,6 +25,7 @@ function buildXMLResponse(request, arrayOfFiles, versioned = false) {
prefix: validPath,
maxKeys: parsedQs['max-keys'] || 1000,
delimiter: '/',
+ optionalAttributes: [],
};
const list = {
IsTruncated: false,
diff --git a/package.json b/package.json
index 245b813e9e..ce23614187 100644
--- a/package.json
+++ b/package.json
@@ -21,7 +21,7 @@
"dependencies": {
"@azure/storage-blob": "^12.28.0",
"@hapi/joi": "^17.1.1",
- "arsenal": "git+https://github.com/scality/Arsenal#8.2.43",
+ "arsenal": "git+https://github.com/scality/arsenal#feature/ARSN-544/list-objects-v2-optional-attributes",
"async": "2.6.4",
"aws-sdk": "^2.1692.0",
"bucketclient": "scality/bucketclient#8.2.7",
diff --git a/tests/functional/aws-node-sdk/test/object/mpuVersion.js b/tests/functional/aws-node-sdk/test/object/mpuVersion.js
index 0a89eb7e32..e801a3910c 100644
--- a/tests/functional/aws-node-sdk/test/object/mpuVersion.js
+++ b/tests/functional/aws-node-sdk/test/object/mpuVersion.js
@@ -101,7 +101,7 @@ function checkObjMdAndUpdate(objMDBefore, objMDAfter, props) {
});
}
-function clearUploadIdFromVersions(versions) {
+function clearUploadIdFromVersionsAndRestoreStatus(versions) {
if (!versions || versions.length === 0) {
return versions;
}
@@ -109,6 +109,7 @@ function clearUploadIdFromVersions(versions) {
for (const version of versions) {
if (version.value) {
version.value.uploadId = undefined;
+ version.value.restoreStatus = undefined;
}
}
@@ -263,7 +264,7 @@ describe('MPU with x-scal-s3-version-id header', () => {
return next(err);
}),
next => metadata.listObject(bucketName, mdListingParams, log, (err, res) => {
- versionsBefore = clearUploadIdFromVersions(res.Versions);
+ versionsBefore = clearUploadIdFromVersionsAndRestoreStatus(res.Versions);
return next(err);
}),
next => putMPUVersion(s3, bucketName, objectName, '', next),
@@ -272,7 +273,7 @@ describe('MPU with x-scal-s3-version-id header', () => {
return next(err);
}),
next => metadata.listObject(bucketName, mdListingParams, log, (err, res) => {
- versionsAfter = clearUploadIdFromVersions(res.Versions);
+ versionsAfter = clearUploadIdFromVersionsAndRestoreStatus(res.Versions);
return next(err);
}),
], err => {
@@ -304,7 +305,7 @@ describe('MPU with x-scal-s3-version-id header', () => {
return next(err);
}),
next => metadata.listObject(bucketName, mdListingParams, log, (err, res) => {
- versionsBefore = clearUploadIdFromVersions(res.Versions);
+ versionsBefore = clearUploadIdFromVersionsAndRestoreStatus(res.Versions);
return next(err);
}),
next => putMPUVersion(s3, bucketName, objectName, '', next),
@@ -313,7 +314,7 @@ describe('MPU with x-scal-s3-version-id header', () => {
return next(err);
}),
next => metadata.listObject(bucketName, mdListingParams, log, (err, res) => {
- versionsAfter = clearUploadIdFromVersions(res.Versions);
+ versionsAfter = clearUploadIdFromVersionsAndRestoreStatus(res.Versions);
return next(err);
}),
], err => {
@@ -353,7 +354,7 @@ describe('MPU with x-scal-s3-version-id header', () => {
}),
next => fakeMetadataArchive(bucketName, objectName, vId, archive, next),
next => metadata.listObject(bucketName, mdListingParams, log, (err, res) => {
- versionsBefore = clearUploadIdFromVersions(res.Versions);
+ versionsBefore = clearUploadIdFromVersionsAndRestoreStatus(res.Versions);
return next(err);
}),
next => getMetadata(bucketName, objectName, vId, (err, objMD) => {
@@ -366,7 +367,7 @@ describe('MPU with x-scal-s3-version-id header', () => {
return next(err);
}),
next => metadata.listObject(bucketName, mdListingParams, log, (err, res) => {
- versionsAfter = clearUploadIdFromVersions(res.Versions);
+ versionsAfter = clearUploadIdFromVersionsAndRestoreStatus(res.Versions);
return next(err);
}),
], err => {
@@ -405,7 +406,7 @@ describe('MPU with x-scal-s3-version-id header', () => {
}),
next => fakeMetadataArchive(bucketName, objectName, vId, archive, next),
next => metadata.listObject(bucketName, mdListingParams, log, (err, res) => {
- versionsBefore = clearUploadIdFromVersions(res.Versions);
+ versionsBefore = clearUploadIdFromVersionsAndRestoreStatus(res.Versions);
return next(err);
}),
next => getMetadata(bucketName, objectName, vId, (err, objMD) => {
@@ -418,7 +419,7 @@ describe('MPU with x-scal-s3-version-id header', () => {
return next(err);
}),
next => metadata.listObject(bucketName, mdListingParams, log, (err, res) => {
- versionsAfter = clearUploadIdFromVersions(res.Versions);
+ versionsAfter = clearUploadIdFromVersionsAndRestoreStatus(res.Versions);
return next(err);
}),
], err => {
@@ -458,7 +459,7 @@ describe('MPU with x-scal-s3-version-id header', () => {
return next(err);
}),
next => metadata.listObject(bucketName, mdListingParams, log, (err, res) => {
- versionsBefore = clearUploadIdFromVersions(res.Versions);
+ versionsBefore = clearUploadIdFromVersionsAndRestoreStatus(res.Versions);
return next(err);
}),
next => putMPUVersion(s3, bucketName, objectName, 'null', next),
@@ -467,7 +468,7 @@ describe('MPU with x-scal-s3-version-id header', () => {
return next(err);
}),
next => metadata.listObject(bucketName, mdListingParams, log, (err, res) => {
- versionsAfter = clearUploadIdFromVersions(res.Versions);
+ versionsAfter = clearUploadIdFromVersionsAndRestoreStatus(res.Versions);
return next(err);
}),
], err => {
@@ -511,7 +512,7 @@ describe('MPU with x-scal-s3-version-id header', () => {
return next(err);
}),
next => metadata.listObject(bucketName, mdListingParams, log, (err, res) => {
- versionsBefore = clearUploadIdFromVersions(res.Versions);
+ versionsBefore = clearUploadIdFromVersionsAndRestoreStatus(res.Versions);
next(err);
}),
next => putMPUVersion(s3, bucketName, objectName, vId, next),
@@ -520,7 +521,7 @@ describe('MPU with x-scal-s3-version-id header', () => {
return next(err);
}),
next => metadata.listObject(bucketName, mdListingParams, log, (err, res) => {
- versionsAfter = clearUploadIdFromVersions(res.Versions);
+ versionsAfter = clearUploadIdFromVersionsAndRestoreStatus(res.Versions);
return next(err);
}),
], err => {
@@ -567,7 +568,7 @@ describe('MPU with x-scal-s3-version-id header', () => {
return next(err);
}),
next => metadata.listObject(bucketName, mdListingParams, log, (err, res) => {
- versionsBefore = clearUploadIdFromVersions(res.Versions);
+ versionsBefore = clearUploadIdFromVersionsAndRestoreStatus(res.Versions);
next(err);
}),
next => putMPUVersion(s3, bucketName, objectName, '', next),
@@ -576,7 +577,7 @@ describe('MPU with x-scal-s3-version-id header', () => {
return next(err);
}),
next => metadata.listObject(bucketName, mdListingParams, log, (err, res) => {
- versionsAfter = clearUploadIdFromVersions(res.Versions);
+ versionsAfter = clearUploadIdFromVersionsAndRestoreStatus(res.Versions);
return next(err);
}),
], err => {
@@ -621,7 +622,7 @@ describe('MPU with x-scal-s3-version-id header', () => {
return next(err);
}),
next => metadata.listObject(bucketName, mdListingParams, log, (err, res) => {
- versionsBefore = clearUploadIdFromVersions(res.Versions);
+ versionsBefore = clearUploadIdFromVersionsAndRestoreStatus(res.Versions);
return next(err);
}),
next => putMPUVersion(s3, bucketName, objectName, vId, next),
@@ -630,7 +631,7 @@ describe('MPU with x-scal-s3-version-id header', () => {
return next(err);
}),
next => metadata.listObject(bucketName, mdListingParams, log, (err, res) => {
- versionsAfter = clearUploadIdFromVersions(res.Versions);
+ versionsAfter = clearUploadIdFromVersionsAndRestoreStatus(res.Versions);
return next(err);
}),
], err => {
@@ -670,7 +671,7 @@ describe('MPU with x-scal-s3-version-id header', () => {
}),
next => fakeMetadataArchive(bucketName, objectName, vId, archive, next),
next => metadata.listObject(bucketName, mdListingParams, log, (err, res) => {
- versionsBefore = clearUploadIdFromVersions(res.Versions);
+ versionsBefore = clearUploadIdFromVersionsAndRestoreStatus(res.Versions);
return next(err);
}),
next => getMetadata(bucketName, objectName, vId, (err, objMD) => {
@@ -683,7 +684,7 @@ describe('MPU with x-scal-s3-version-id header', () => {
return next(err);
}),
next => metadata.listObject(bucketName, mdListingParams, log, (err, res) => {
- versionsAfter = clearUploadIdFromVersions(res.Versions);
+ versionsAfter = clearUploadIdFromVersionsAndRestoreStatus(res.Versions);
return next(err);
}),
], err => {
@@ -729,7 +730,7 @@ describe('MPU with x-scal-s3-version-id header', () => {
}),
next => fakeMetadataArchive(bucketName, objectName, vId, archive, next),
next => metadata.listObject(bucketName, mdListingParams, log, (err, res) => {
- versionsBefore = clearUploadIdFromVersions(res.Versions);
+ versionsBefore = clearUploadIdFromVersionsAndRestoreStatus(res.Versions);
return next(err);
}),
next => getMetadata(bucketName, objectName, vId, (err, objMD) => {
@@ -743,7 +744,7 @@ describe('MPU with x-scal-s3-version-id header', () => {
return next(err);
}),
next => metadata.listObject(bucketName, mdListingParams, log, (err, res) => {
- versionsAfter = clearUploadIdFromVersions(res.Versions);
+ versionsAfter = clearUploadIdFromVersionsAndRestoreStatus(res.Versions);
return next(err);
}),
], err => {
@@ -777,7 +778,7 @@ describe('MPU with x-scal-s3-version-id header', () => {
next => s3.putObject(params, next),
next => fakeMetadataArchive(bucketName, objectName, undefined, archive, next),
next => metadata.listObject(bucketName, mdListingParams, log, (err, res) => {
- versionsBefore = clearUploadIdFromVersions(res.Versions);
+ versionsBefore = clearUploadIdFromVersionsAndRestoreStatus(res.Versions);
return next(err);
}),
next => getMetadata(bucketName, objectName, undefined, (err, objMD) => {
@@ -791,7 +792,7 @@ describe('MPU with x-scal-s3-version-id header', () => {
return next(err);
}),
next => metadata.listObject(bucketName, mdListingParams, log, (err, res) => {
- versionsAfter = clearUploadIdFromVersions(res.Versions);
+ versionsAfter = clearUploadIdFromVersionsAndRestoreStatus(res.Versions);
return next(err);
}),
], err => {
diff --git a/tests/functional/aws-node-sdk/test/object/putVersion.js b/tests/functional/aws-node-sdk/test/object/putVersion.js
index f90d712536..74dc164ff9 100644
--- a/tests/functional/aws-node-sdk/test/object/putVersion.js
+++ b/tests/functional/aws-node-sdk/test/object/putVersion.js
@@ -34,6 +34,21 @@ function putObjectVersion(s3, params, vid, next) {
return request.send(next);
}
+function clearRestoreStatus(versions) {
+ if (!versions || versions.length === 0) {
+ return versions;
+ }
+
+ for (const version of versions) {
+ if (version.value) {
+ version.value.restoreStatus = undefined;
+ }
+ }
+
+ return versions;
+}
+
+
function checkVersionsAndUpdate(versionsBefore, versionsAfter, indexes) {
indexes.forEach(i => {
assert.notStrictEqual(versionsAfter[i].value.Size, versionsBefore[i].value.Size);
@@ -203,7 +218,7 @@ describe('PUT object with x-scal-s3-version-id header', () => {
return next(err);
}),
next => metadata.listObject(bucketName, mdListingParams, log, (err, res) => {
- versionsBefore = res.Versions;
+ versionsBefore = clearRestoreStatus(res.Versions);
return next(err);
}),
next => putObjectVersion(s3, params, '', next),
@@ -212,7 +227,7 @@ describe('PUT object with x-scal-s3-version-id header', () => {
return next(err);
}),
next => metadata.listObject(bucketName, mdListingParams, log, (err, res) => {
- versionsAfter = res.Versions;
+ versionsAfter = clearRestoreStatus(res.Versions);
return next(err);
}),
], err => {
@@ -250,7 +265,7 @@ describe('PUT object with x-scal-s3-version-id header', () => {
}),
next => fakeMetadataArchive(bucketName, objectName, vId, archive, next),
next => metadata.listObject(bucketName, mdListingParams, log, (err, res) => {
- versionsBefore = res.Versions;
+ versionsBefore = clearRestoreStatus(res.Versions);
return next(err);
}),
next => getMetadata(bucketName, objectName, vId, (err, objMD) => {
@@ -263,7 +278,7 @@ describe('PUT object with x-scal-s3-version-id header', () => {
return next(err);
}),
next => metadata.listObject(bucketName, mdListingParams, log, (err, res) => {
- versionsAfter = res.Versions;
+ versionsAfter = clearRestoreStatus(res.Versions);
return next(err);
}),
], err => {
@@ -301,7 +316,7 @@ describe('PUT object with x-scal-s3-version-id header', () => {
}),
next => fakeMetadataArchive(bucketName, objectName, vId, archive, next),
next => metadata.listObject(bucketName, mdListingParams, log, (err, res) => {
- versionsBefore = res.Versions;
+ versionsBefore = clearRestoreStatus(res.Versions);
return next(err);
}),
next => getMetadata(bucketName, objectName, vId, (err, objMD) => {
@@ -314,7 +329,7 @@ describe('PUT object with x-scal-s3-version-id header', () => {
return next(err);
}),
next => metadata.listObject(bucketName, mdListingParams, log, (err, res) => {
- versionsAfter = res.Versions;
+ versionsAfter = clearRestoreStatus(res.Versions);
return next(err);
}),
], err => {
@@ -353,7 +368,7 @@ describe('PUT object with x-scal-s3-version-id header', () => {
return next(err);
}),
next => metadata.listObject(bucketName, mdListingParams, log, (err, res) => {
- versionsBefore = res.Versions;
+ versionsBefore = clearRestoreStatus(res.Versions);
next(err);
}),
next => putObjectVersion(s3, params, 'null', next),
@@ -362,7 +377,7 @@ describe('PUT object with x-scal-s3-version-id header', () => {
return next(err);
}),
next => metadata.listObject(bucketName, mdListingParams, log, (err, res) => {
- versionsAfter = res.Versions;
+ versionsAfter = clearRestoreStatus(res.Versions);
return next(err);
}),
], err => {
@@ -405,7 +420,7 @@ describe('PUT object with x-scal-s3-version-id header', () => {
return next(err);
}),
next => metadata.listObject(bucketName, mdListingParams, log, (err, res) => {
- versionsBefore = res.Versions;
+ versionsBefore = clearRestoreStatus(res.Versions);
return next(err);
}),
next => putObjectVersion(s3, params, vId, next),
@@ -414,7 +429,7 @@ describe('PUT object with x-scal-s3-version-id header', () => {
return next(err);
}),
next => metadata.listObject(bucketName, mdListingParams, log, (err, res) => {
- versionsAfter = res.Versions;
+ versionsAfter = clearRestoreStatus(res.Versions);
return next(err);
}),
], err => {
@@ -460,7 +475,7 @@ describe('PUT object with x-scal-s3-version-id header', () => {
return next(err);
}),
next => metadata.listObject(bucketName, mdListingParams, log, (err, res) => {
- versionsBefore = res.Versions;
+ versionsBefore = clearRestoreStatus(res.Versions);
return next(err);
}),
next => putObjectVersion(s3, params, '', next),
@@ -469,7 +484,7 @@ describe('PUT object with x-scal-s3-version-id header', () => {
return next(err);
}),
next => metadata.listObject(bucketName, mdListingParams, log, (err, res) => {
- versionsAfter = res.Versions;
+ versionsAfter = clearRestoreStatus(res.Versions);
return next(err);
}),
], err => {
@@ -509,7 +524,7 @@ describe('PUT object with x-scal-s3-version-id header', () => {
next => fakeMetadataArchive(bucketName, objectName, vId, archive, next),
next => s3.putObject(params, next),
next => metadata.listObject(bucketName, mdListingParams, log, (err, res) => {
- versionsBefore = res.Versions;
+ versionsBefore = clearRestoreStatus(res.Versions);
return next(err);
}),
next => getMetadata(bucketName, objectName, vId, (err, objMD) => {
@@ -522,7 +537,7 @@ describe('PUT object with x-scal-s3-version-id header', () => {
return next(err);
}),
next => metadata.listObject(bucketName, mdListingParams, log, (err, res) => {
- versionsAfter = res.Versions;
+ versionsAfter = clearRestoreStatus(res.Versions);
return next(err);
}),
], err => {
@@ -561,7 +576,7 @@ describe('PUT object with x-scal-s3-version-id header', () => {
}),
next => fakeMetadataArchive(bucketName, objectName, vId, archive, next),
next => metadata.listObject(bucketName, mdListingParams, log, (err, res) => {
- versionsBefore = res.Versions;
+ versionsBefore = clearRestoreStatus(res.Versions);
return next(err);
}),
next => getMetadata(bucketName, objectName, vId, (err, objMD) => {
@@ -574,7 +589,7 @@ describe('PUT object with x-scal-s3-version-id header', () => {
return next(err);
}),
next => metadata.listObject(bucketName, mdListingParams, log, (err, res) => {
- versionsAfter = res.Versions;
+ versionsAfter = clearRestoreStatus(res.Versions);
return next(err);
}),
], err => {
@@ -619,7 +634,7 @@ describe('PUT object with x-scal-s3-version-id header', () => {
}),
next => fakeMetadataArchive(bucketName, objectName, vId, archive, next),
next => metadata.listObject(bucketName, mdListingParams, log, (err, res) => {
- versionsBefore = res.Versions;
+ versionsBefore = clearRestoreStatus(res.Versions);
return next(err);
}),
next => getMetadata(bucketName, objectName, vId, (err, objMD) => {
@@ -633,7 +648,7 @@ describe('PUT object with x-scal-s3-version-id header', () => {
return next(err);
}),
next => metadata.listObject(bucketName, mdListingParams, log, (err, res) => {
- versionsAfter = res.Versions;
+ versionsAfter = clearRestoreStatus(res.Versions);
return next(err);
}),
], err => {
@@ -666,7 +681,7 @@ describe('PUT object with x-scal-s3-version-id header', () => {
next => s3.putObject(params, next),
next => fakeMetadataArchive(bucketName, objectName, undefined, archive, next),
next => metadata.listObject(bucketName, mdListingParams, log, (err, res) => {
- versionsBefore = res.Versions;
+ versionsBefore = clearRestoreStatus(res.Versions);
return next(err);
}),
next => getMetadata(bucketName, objectName, undefined, (err, objMD) => {
@@ -680,7 +695,7 @@ describe('PUT object with x-scal-s3-version-id header', () => {
return next(err);
}),
next => metadata.listObject(bucketName, mdListingParams, log, (err, res) => {
- versionsAfter = res.Versions;
+ versionsAfter = clearRestoreStatus(res.Versions);
return next(err);
}),
], err => {
diff --git a/tests/unit/api/bucketGet.js b/tests/unit/api/bucketGet.js
index 971e58748b..ed8a1eb5f1 100644
--- a/tests/unit/api/bucketGet.js
+++ b/tests/unit/api/bucketGet.js
@@ -514,5 +514,99 @@ describe('bucketGet API V2', () => {
done();
});
});
+
+ it('should return user metadata if requested and present', done => {
+ const objectNameMeta = 'objectWithMeta';
+ const putRequest = new DummyRequest({
+ bucketName,
+ headers: { 'x-amz-meta-color': 'red' },
+ url: `/${bucketName}/${objectNameMeta}`,
+ namespace,
+ objectKey: objectNameMeta,
+ }, postBody);
+
+ const testGetRequest = Object.assign({
+ query: {},
+ url: baseUrl,
+ }, baseGetRequest);
+ testGetRequest.headers['x-amz-optional-object-attributes'] = 'x-amz-meta-color';
+
+ async.waterfall([
+ next => bucketPut(authInfo, testPutBucketRequest, log, next),
+ (_, next) => objectPut(authInfo, putRequest, undefined, log, next),
+ (_, next) => bucketGet(authInfo, testGetRequest, log, next),
+ (result, _, next) => parseString(result, next),
+ ],
+ (err, result) => {
+ assert.strictEqual(err, null);
+ const content = result.ListBucketResult.Contents[0];
+ assert.strictEqual(content.Key[0], objectNameMeta);
+ assert.strictEqual(content['x-amz-meta-color'][0], 'red');
+ done();
+ });
+ });
+
+ it('should return all user metadata if wildcard requested', done => {
+ const objectNameMeta = 'objectWithMetaWildcard';
+ const putRequest = new DummyRequest({
+ bucketName,
+ headers: { 'x-amz-meta-color': 'red', 'x-amz-meta-size': 'large' },
+ url: `/${bucketName}/${objectNameMeta}`,
+ namespace,
+ objectKey: objectNameMeta,
+ }, postBody);
+
+ const testGetRequest = Object.assign({
+ query: {},
+ url: baseUrl,
+ }, baseGetRequest);
+ testGetRequest.headers['x-amz-optional-object-attributes'] = 'x-amz-meta-*';
+
+ async.waterfall([
+ next => bucketPut(authInfo, testPutBucketRequest, log, next),
+ (_, next) => objectPut(authInfo, putRequest, undefined, log, next),
+ (_, next) => bucketGet(authInfo, testGetRequest, log, next),
+ (result, _, next) => parseString(result, next),
+ ],
+ (err, result) => {
+ assert.strictEqual(err, null);
+ const content = result.ListBucketResult.Contents[0];
+ assert.strictEqual(content.Key[0], objectNameMeta);
+ assert.strictEqual(content['x-amz-meta-color'][0], 'red');
+ assert.strictEqual(content['x-amz-meta-size'][0], 'large');
+ done();
+ });
+ });
+
+ it('should return user metadata in version listing if requested', done => {
+ const objectNameMeta = 'objectWithMetaVersion';
+ const putRequest = new DummyRequest({
+ bucketName,
+ headers: { 'x-amz-meta-ver': '1' },
+ url: `/${bucketName}/${objectNameMeta}`,
+ namespace,
+ objectKey: objectNameMeta,
+ }, postBody);
+
+ const testGetRequest = Object.assign({
+ query: { versions: '' },
+ url: `${baseUrl}?versions`,
+ }, baseGetRequest);
+ testGetRequest.headers['x-amz-optional-object-attributes'] = 'x-amz-meta-ver';
+
+ async.waterfall([
+ next => bucketPut(authInfo, testPutBucketRequest, log, next),
+ (_, next) => objectPut(authInfo, putRequest, undefined, log, next),
+ (_, next) => bucketGet(authInfo, testGetRequest, log, next),
+ (result, _, next) => parseString(result, next),
+ ],
+ (err, result) => {
+ assert.strictEqual(err, null);
+ const version = result.ListVersionsResult.Version[0];
+ assert.strictEqual(version.Key[0], objectNameMeta);
+ assert.strictEqual(version['x-amz-meta-ver'][0], '1');
+ done();
+ });
+ });
});
});
diff --git a/yarn.lock b/yarn.lock
index 88c3dfed6a..4ab9aa8e08 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1495,9 +1495,9 @@ arraybuffer.prototype.slice@^1.0.4:
optionalDependencies:
ioctl "^2.0.2"
-"arsenal@git+https://github.com/scality/Arsenal#8.2.43":
- version "8.2.43"
- resolved "git+https://github.com/scality/Arsenal#c2375224bb0f0a0391c0509b4545859b77f87c92"
+"arsenal@git+https://github.com/scality/arsenal#feature/ARSN-544/list-objects-v2-optional-attributes":
+ version "8.2.44"
+ resolved "git+https://github.com/scality/arsenal#7b5b61bd6616219941fe3ff31ef38d25971e4c5b"
dependencies:
"@azure/identity" "^4.13.0"
"@azure/storage-blob" "^12.28.0"